当尝试选择用appendChild()注入的节点时,如何防止Range.selectNode()选择过多的DOM?

2024-02-08

我遇到了使用组合的问题appendChild() and Range.selectNode()在 JavaScript 中。

当尝试使用范围来选择新附加的<textarea>节点,它选择了太多的 DOM。复制并粘贴所选内容似乎只包含一个空格。

但是,如果我把<textarea>从一开始就将节点添加到 DOM 中(即不要将其添加为appendChild())然后它工作得很好,我可以按预期复制并粘贴所选文本。

请注意,CSS 在这里并不是真正必要的,但它强调了这样一个事实:选择内容不仅仅包含<textarea>(或者至少在 Chrome 中是这样)。

HTML:

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

CSS:

.floating {
    position: absolute;
}

JavaScript/jQuery(在 DOM 上运行):

$(".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);    
}

这是一个jsFiddle http://jsfiddle.net/c3gpenfu/.

Chrome 中的选择结果如下所示:

我怎样才能阻止这种情况发生,并只选择所需的文本?


将您的呼叫替换为selectObjectText with:

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

问题在于textarea元素的特点是它们不将其内容保存在 DOM 节点中。文本值是元素的属性。你打电话时range.selectNode,会发生的情况是,范围被设置为包含您传递给函数的节点以及该节点的子节点,但由于textarea不将其文本存储在子节点中,那么您只选择textarea.

setSelectionRange使用输入元素的值,因此不会遇到此问题。您可能想检查兼容性矩阵here https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement.setSelectionRange检查哪些浏览器支持它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当尝试选择用appendChild()注入的节点时,如何防止Range.selectNode()选择过多的DOM? 的相关文章

随机推荐