klidifia
klidifia

Reputation: 1495

Inserting an HTML element after text selection

I am trying to insert some HTML after the user has selected some text on the page. I have it working but not optimally and there is one problem in particular:

It relies on the element being on the page, but I don't want it to be. I want to do it all in the code, I am sure it's something relatively simple but need some help :)

I also welcome any other tips/suggestions/feedback!

The code canbe seen working here: http://jsfiddle.net/shE58/ (The selectionchange library is to make this work in FF).

document.addEventListener('selectionchange', function (event) {
    var sel = this.getSelection();

    // If text is being selected by drag, to wait for them to finish selecting.
    jQuery("body").mouseup(function() {
      // Ensure there is some text selected and that it is more than one character.
      if (sel.toString().length > 1) {
        // We only want one #element on the page at a time.
        $("#element").remove();

        // @TODO: Remove dependency on this:
        var el = document.getElementById('selection');
        el.innerHTML = '<div id="element"></div>';
        var frag = document.createDocumentFragment(), node;
        frag.appendChild(el.firstChild);

        var range = sel.getRangeAt(0)
        var startNode = range.startContainer, startOffset = range.startOffset;
        var boundaryRange = range.cloneRange();
        boundaryRange.collapse(false);
        boundaryRange.insertNode(frag);
        boundaryRange.setStart(startNode, startOffset);
        boundaryRange.collapse(true);
        // Clean up
        sel = '';
      }
    });
  });

Upvotes: 0

Views: 84

Answers (1)

user2226755
user2226755

Reputation: 13159

Solution 1

Remove frag variable and directly add value in insertNode function like this :

boundaryRange.insertNode($('<div id="element"></div>')[0]);

http://jsfiddle.net/N6zz8/

Fix issue when to select right to left :

With a condition check if endOffset is smaller than startOffset.

var startNode = range.startContainer, startOffset = range.startOffset;
if (range.endOffset < range.startOffset) {
    startNode = range.endContainer;
    startOffset = range.endOffset;
}

http://jsfiddle.net/2c4qw/

Solution 2

Remove unnecessary code, remove 'el' variable like this :

// @TODO: Remove dependency on this:
var frag = document.createDocumentFragment(), node;
$(frag).append($('<div id="element"></div>'));

http://jsfiddle.net/zYSH4/

Solution 3

Declare your variable like this var el = $("<div></div>")[0];. To get this :

// @TODO: Remove dependency on this:
var el = $("<div></div>")[0];
el.innerHTML = '<div id="element"></div>';
var frag = document.createDocumentFragment(), node;
frag.appendChild(el.firstChild);

http://jsfiddle.net/7L3Kf/

Upvotes: 1

Related Questions