Question

This question refers a similar question asked here about how to apply a tag to selected text. The question was answered, but that answer had one major flaw, which is that if the same text that is selected exists elsewhere in the document, the <span> wraps around the duplicate, not the text in question.

I realize this maybe be against some stackoverflow protocol, but I'm posting here without a real clue as to how to proceed. My best guess would be to somehow find the string length before the selected text (something along these lines) but how to incorporate that in to the replacement function itself ... well I could use a push. Anyone?

(I have pasted the solution to the previous post (by mathias-bynens ) below.)

    $("p").live("mouseup",function() {
    selection = getSelectedText();
    if(selection.length >= 3) {
        var spn = '<span class="selected">' + selection + '</span>';
        $(this).text($(this).html().replace(selection, spn));

    }
});

//Grab selected text
function getSelectedText(){
    if(window.getSelection){
        return window.getSelection().toString();
    }
    else if(document.getSelection){
        return document.getSelection();
    }
    else if(document.selection){
        return document.selection.createRange().text;
    }
}
Was it helpful?

Solution

I cheated, and used document.execCommand to wrap the selected text, then used the href (third parameter of the CreateLink execCommand) to find the element, wrap it with what I wanted, and then remove the link:

$("p").live("mouseup",function() {
    document.execCommand('CreateLink', false, 'uniqueid');
    var sel = $('a[href="uniqueid"]');
    sel.wrap('<span class="selected" />')
    sel.contents().unwrap();
});

document.execCommand is supported by all major browsers so you should be safe hacking it this way. In the browsers I've tested, the browser itself will close and open tags for you, so if you're selecting from the middle of one html tag to the middle of another, it should nest the tags correctly.

OTHER TIPS

i think your key is to figure out what getSelection returns and work with that.

on firefox i was able to do this:

$(document.getSelection().anchorNode).wrap('<div style="color:blue">')

document.selection.createRange() must have a similar thing that lets you find the thing that was selected.

so something like:

$("p").live("mouseup",function() {
    var $sel = getSelectedElem();
    if($.trim($sel.text()).length >= 3) {
        $sel.warp('<span class="selected">');
    }
});

//Grab selected text
function getSelectedElem(){
    if(window.getSelection){
        return $(window.getSelection().anchorNode);
    }
    else if(document.getSelection){
        return $(document.getSelection().anchorNode)
    }
    else if(document.selection){
        //todo figure out what to return here:
        return document.selection.createRange().text;
    }
    return $([]);
}

What about this?

document.execCommand("insertHTML", false, "<span class='own-class'>"+ document.getSelection()+"</span>");

source by YeppThat'sMe

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top