Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I wrap the previous, current, and next word inside a tag using jQuery?

Not sure if the title is well chosen...

I am trying to simulate text-selection in HTML/JS/CSS to get rid of the action bubble on mobile device when truly selecting texts.

To be more specific, I'm trying to avoid this: enter image description here

The visual:

enter image description here

The way I built it and it may change because it doesn't matter, is that the text selected is wrapped inside a span.selection and inside that tag, there are also two caret used as handlers:

Lorem ipsum dolor                            <!-- Unselected Text -->

<span class="selection">                     <!-- Start selection wrapper -->

  <span rel="previous" class="caret"></span> <!-- The left-side caret -->

  sit amet, consectetur                      <!-- The selected texts -->

  <span rel="next" class="caret"></span>     <!-- The right-side caret -->

</span>                                      <!-- End selection wrapper -->

adipiscing elit.                             <!-- Unselected Text -->

Ideally, it would be fun to use a drag-n-drop to select more or less texts but I believe this would be darn hard to do and in that case, maybe using click on the carets to select either the previous or the following word and wrap it inside the .selection wouldn't be that bad.

Here is the jsfiddle: http://jsfiddle.net/m6Qx4/

The surrounding texts may contains HTML tags too such as: <i>, <b>, <span> and <ul>/<li> may be present making the parsing harder.

Any ideas how this can be done?

Status Update:

I have actually managed to make it work with .click(); event listener using my custom jQuery methods.

Eventually, I will replace the click events with jQuery UI draggable to select surrounding words so long as it's useable for mobile devices.

My current bug consists of the re-position of the red carets. I have tried destroying them and prepend/append them back and it's still not working. It might be a bug with Firefox that can't reload the DOM properly after changes made to Text Nodes?

Reference: jsFiddle

To check operating condition of jsFiddle.net due to recent outages, visit their Tweets.

like image 829
Cybrix Avatar asked Jun 28 '12 18:06

Cybrix


People also ask

What does the jQuery wrap () function do?

jQuery wrap() method is used to wrap specified HTML elements around each selected element. The wrap () function can accept any string or object that could be passed through the $() factory function. Syntax: $(selector).

Which jQuery method allows you to add a wrapper element around another set of elements?

The wrap() method wraps specified HTML element(s) around each selected element.

Which of the following method wraps is specified HTML elements around each selected element using jQuery?

jQuery wrapInner() Method The wrapInner() method wraps specified HTML element(s) around the content (innerHTML) of each selected element.


1 Answers

A few thoughts:

I can't see how wrapping everything in a <span> is a viable solution. What happens when you have something like this?

<p>The <b>important terms</b> will be bolded in this text</p>

When you select The important, you'll have some tag mayhem where the <span> tag's body wants to overlap the <b> tag's body.

I think a better solution would be to have multiple selection <span> tags with the same class. Each time an HTML tag is encountered, you skip over the tag and create a new selection <span>. Then, when you reposition your carets, you simply do this:

$(".selection:first").prepend(startCaret);
$(".selection:last").append(endCaret);

I played around with this idea and it was working fine for me. If you want to get really fancy, you could try and merge selection <span>s when you find a closing tag after you've encountered its corresponding start tag, but that would be a lot of work.


Your carets aren't moving correctly because you specify a style of absolute positioning. Change that to relative and give each caret a body of &nbsp;. You'll have to play around with a few other positioning CSS settings to get it to look just right, but it moves as you'd expect with those changes (example here).


As I was playing with some ideas for this, I tried doing absolute positioning on the carets so they didn't have to be moved around inside the selection <span>. That was a mistake. I ran into problems with paragraphs that overflowed to a new line without any markup. Stay with your idea of having the carets inside of your selection <span>.


Lastly, a few thought questions:

  • Are you going to limit the scope? (i.e., if you start selecting inside a <p> tag, don't allow selection to spill outside of that tag to the next <p> or whatever follows)
  • Are certain tags going to be unselectable? (i.e., <table>, <script>, <select>, etc)

I think this idea is pretty cool, but it could be a pretty massive project. I'll post some of my prototypes that I tried when I get them a bit more polished.

like image 150
RustyTheBoyRobot Avatar answered Sep 22 '22 19:09

RustyTheBoyRobot