How can I prevent Range.selectNode () from selecting too much of the DOM when trying to select a node using appendChild ()?

I am having a problem with a combination of usage appendChild()

and Range.selectNode()

in JavaScript.

When trying to use a range to select a newly added <textarea>

node, it selects too much of the DOM. Copying and pasting the selection seems to just contain a space.

However, if I put a <textarea>

node in the DOM from the start (i.e. don't add it with appendChild()

), then it works fine and I can copy and paste the selected text as expected.

Note that CSS isn't really needed here, but it highlights the fact that there is more to the selection <textarea>

(or at least it does in Chrome).

HTML:

<div>
    <a class="hoverTrigger">Click to trigger textarea element with selected text</a>
</div>

      

CSS

.floating {
    position: absolute;
}

      

JavaScript / jQuery (executed in DOM ready mode):

$(".hoverTrigger").click(createAndSelectStuff);

function createAndSelectStuff() {
    var textArea = document.createElement("textarea");
    textArea.className = "floating";
    textArea.value = "Some dynamic text to select";
    this.parentNode.appendChild(textArea);
    selectObjectText(textArea);
    return false;
}

function selectObjectText(container) {    
    var range = document.createRange();
    range.selectNode(container);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);    
}

      

Here's a jsFiddle .

This is what the result looks like in Chrome:

Image showing selection of DOM outside of intended area

How can I stop this and just select the text I want?

+3


source to share


1 answer


Replace the call selectObjectText

with:

container.setSelectionRange(0, container.value.length);

      



The problem with elements textarea

is that they don't store their content in DOM nodes. The text value is a property of the element. When you call range.selectNode

what happens is that the range is set to span the node you are passing to the function and the children of that node's node, but since a textarea

does not store its text in the child nodes, then you only select textarea

.

setSelectionRange

works with the value of the input element, so it doesn't suffer from this problem. You might want to check the compatibility matrix here to check which browsers support it.

+2


source







All Articles