简体   繁体   中英

How can I prevent Range.selectNode() selecting too much of the DOM when attempting to select a node injected with appendChild()?

I'm facing an issue with the combination of using appendChild() and Range.selectNode() in JavaScript.

When attempting to use a range to select the newly-appended <textarea> node, it selects too much of the DOM. Copying and pasting the selection seems to just contain a space.

However, if I put the <textarea> node into the DOM from the start (ie don't add it with appendChild() ) then it works perfectly well and I can copy and paste the selected text as expected.

Note that the CSS isn't really necessary here, but it highlights the fact that the selection contains more than just the <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 (run on DOM ready):

$(".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 resulting selection looks like in Chrome:

显示在预期区域之外选择DOM的图像

How can I stop this happening, and just select the desired text?

Replace your call to selectObjectText with:

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

The problem with textarea elements is that they do not hold their contents 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 so as to encompass the node you pass to the function and the children node of this node, but since a textarea does not store its text in children nodes, then you select only the textarea .

setSelectionRange works with the value of an input element so it does not suffer from this problem. You might want to check the compatibility matrix here to check which browsers support it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM