0

In my page, user select a text, once they select i am passing the selected object to function. In the function i would like to get the appropriate text note using jquery.. how to get that?

here is my function :

var manipulator = function (coreObject) {
    console.log(coreObject);//i would like find the text node using this object and like to wrap in to a element say 'span'...
}

function highlight() {
    var range, sel;
    var span = document.createElement("span");
    span.style.fontWeight = "bold";
    span.style.color = "green";
    // IE case
    if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        manipulator(range)
    } else if (window.getSelection) {
        // Non-IE
        sel = window.getSelection();
        manipulator(sel)
    }
}

$("#addText").on('click',  function(event) {
    event.preventDefault();
    highlight();
});

Live Demo

I am looking for all browser friendly approach.

3gwebtrain
  • 14,640
  • 25
  • 121
  • 247

1 Answers1

1

The value returned by selection or getSelection is selected text string, not an element in the DOM. This is why you cannot target it as a jQuery object.

What you can do however, is to use a Range.surroundContents() method (Ref: https://developer.mozilla.org/en-US/docs/Web/API/range.surroundContents), to wrap the text selection in any element.

You would also need to create a range out of the selected text using the Selection.getRangeAt() method (Ref: https://developer.mozilla.org/en-US/docs/Web/API/Selection.getRangeAt).

Here is a sample snippet:

var manipulator = function (coreObject) {
    var span = document.createElement("span");
    span.style.fontWeight = "bold";
    span.style.color = "blue";
 coreObject.getRangeAt(0).surroundContents(span);
}

function highlight() {
    var range, sel;
    if (document.selection && document.selection.createRange) { // IE
        range = document.selection.createRange();
        manipulator(range)
    } else if (window.getSelection) { // Non-IE
        sel = window.getSelection();
        manipulator(sel)
    }
}

$("#addText").on('click',  function(event) {
 event.preventDefault();
 highlight();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Lorem ipsum dolor sit amet, <strong>consectetur</strong> adipisicing elit. Error ipsa quo illum excepturi autem voluptatem, maiores tempora quasi temporibus architecto ratione delectus modi qui cum earum, omnis itaque nam iure!</p><br/>
<input type="button" id="addText"  value="Surround" />
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • It's ok. But can you check this issue... in case if i use your solution : http://stackoverflow.com/questions/27602239/not-able-to-add-the-span-container-to-element-selection – 3gwebtrain Dec 22 '14 at 15:37
  • @3gwebtrain: (1) Yes. If you read the ref which I linked to, it says *An exception will be thrown, however, if the Range splits a non-Text node with only one of its boundary points.* (2) [Official Specs here](http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level2-Range-method-surroundContents) (3) It means that `surroundContents` will work only if the selected range will produce a valid HTML markup after execution. So, if you select overlapping areas, it will give an exception. As long as you are not overlapping, it will be fine. – Abhitalks Dec 22 '14 at 15:55
  • @3gwebtrain: If you require overlapping selection, then the best option for you is to use HTML Editing APIs, [Specs Here](https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html). Also, have a look at this answer which I gave a while ago: http://stackoverflow.com/a/27442159/1355315 – Abhitalks Dec 22 '14 at 15:58