Javascript window.getSelection().getRangeAt(0)innerHTML而不中断节点

Javascript window.getSelection().getRangeAt(0)innerHTML而不中断节点,javascript,dom,Javascript,Dom,我正在开发一个JavaScript扩展,它应该以某种方式包装所选文本并将其发送到我的服务器。包装完成后,即使存在重复的文本,服务器也可以识别高亮显示文本的确切位置 我遵循这个链接,以能够获得选定的文本。之后,我采用了这种方法,特别是选择的答案,以获得innerHTML。问题是,当选择跨越不同的div时,它会破坏DOM,或者正如zyklus在回答中所说的那样,将节点分成两半并创建额外的跨度会产生副作用 例如, <div id="IntroDiv"> <p&

我正在开发一个JavaScript扩展,它应该以某种方式包装所选文本并将其发送到我的服务器。包装完成后,即使存在重复的文本,服务器也可以识别高亮显示文本的确切位置

我遵循这个链接,以能够获得选定的文本。之后,我采用了这种方法,特别是选择的答案,以获得innerHTML。问题是,当选择跨越不同的div时,它会破坏DOM,或者正如zyklus在回答中所说的那样,将节点分成两半并创建额外的跨度会产生副作用

例如,

    <div id="IntroDiv">
        <p>
            <img src="http://localhost:9000/Theme/Images/Intro/logo.png">
            <br><br>
            A neat th<f5e975aa551d1ae4e91e8ce9><div id="IntroDiv"><p>eme for start-ups and small corporations.
        </p>
    </div>

    <div id="ProjectsSlider">
        <div id="ProjectsSliderContent">

            <p class="Title">Projects</p>
            <p class="Subtitle">Samples O</p></div></div></f5e975aa551d1ae4e91e8ce9>eme for start-ups and small corporations.
        </p>
    </div>

    <div id="ProjectsSlider">
        <div id="ProjectsSliderContent">

            <p class="Title">Projects</p>
            <p class="Subtitle">Samples Of Our Work</p>

            <div id="SliderContainer">
                <div class="LeftArrow"></div>
                <div class="RightArrow"></div>
                <div class="ThreeD swiper-container stop-swiping">
                    <div class="swiper-wrapper swiper-no-swiping" style="width: 2365px; height: 285px; transform: translate3d(-430px, 0px, 0px); -webkit-transform: translate3d(-430px, 0px, 0px); transition-duration: 0s; -webkit-transition-duration: 0s;"><div class="swiper-slide swiper-slide-duplicate" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -336px) rotateX(0deg) rotateY(-75deg); -webkit-transform: translate3d(0px, 0px, -336px) rotateX(0deg) rotateY(-75deg); z-index: -2; background-image: url(http://placehold.it/215x270/);">Project 3</div><div class="swiper-slide swiper-slide-duplicate" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -224px) rotateX(0deg) rotateY(-50deg); -webkit-transform: translate3d(0px, 0px, -224px) rotateX(0deg) rotateY(-50deg); z-index: -1; background-image: url(http://placehold.it/215x270/);">Project 4</div><div class="swiper-slide swiper-slide-duplicate swiper-slide-visible swiper-slide-active" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -112px) rotateX(0deg) rotateY(-25deg); -webkit-transform: translate3d(0px, 0px, -112px) rotateX(0deg) rotateY(-25deg); z-index: 0; background-image: url(http://placehold.it/215x270/);">Project 5</div> <!-- Add your slides here. You're free to have different styles or content -->
                        <div class="swiper-slide swiper-slide-visible" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, 0px) rotateX(0deg) rotateY(0deg); -webkit-transform: translate3d(0px, 0px, 0px) rotateX(0deg) rotateY(0deg); z-index: 1; background-image: url(http://placehold.it/215x270/);">Project 1</div>
                        <div class="swiper-slide swiper-slide-visible" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -112px) rotateX(0deg) rotateY(25deg); -webkit-transform: translate3d(0px, 0px, -112px) rotateX(0deg) rotateY(25deg); z-index: 0; background-image: url(http://placehold.it/215x270/);">Project 2</div>
                        <div class="swiper-slide" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -224px) rotateX(0deg) rotateY(50deg); -webkit-transform: translate3d(0px, 0px, -224px) rotateX(0deg) rotateY(50deg); z-index: -1; background-image: url(http://placehold.it/215x270/);">Project 3</div>
                        <div class="swiper-slide" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -336px) rotateX(0deg) rotateY(75deg); -webkit-transform: translate3d(0px, 0px, -336px) rotateX(0deg) rotateY(75deg); z-index: -2; background-image: url(http://placehold.it/215x270/);">Project 4</div>
                        <div class="swiper-slide" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -448px) rotateX(0deg) rotateY(100deg); -webkit-transform: translate3d(0px, 0px, -448px) rotateX(0deg) rotateY(100deg); z-index: -3; background-image: url(http://placehold.it/215x270/);">Project 5</div>
                    <div class="swiper-slide swiper-slide-duplicate" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -560px) rotateX(0deg) rotateY(125deg); -webkit-transform: translate3d(0px, 0px, -560px) rotateX(0deg) rotateY(125deg); z-index: -4; background-image: url(http://placehold.it/215x270/);">Project 1</div><div class="swiper-slide swiper-slide-duplicate" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -672px) rotateX(0deg) rotateY(150deg); -webkit-transform: translate3d(0px, 0px, -672px) rotateX(0deg) rotateY(150deg); z-index: -5; background-image: url(http://placehold.it/215x270/);">Project 2</div><div class="swiper-slide swiper-slide-duplicate" style="width: 215px; height: 285px; transition-duration: 0ms; -webkit-transition-duration: 0ms; transform: translate3d(0px, 0px, -784px) rotateX(0deg) rotateY(175deg); -webkit-transform: translate3d(0px, 0px, -784px) rotateX(0deg) rotateY(175deg); z-index: -6; background-image: url(http://placehold.it/215x270/);">Project 3</div></div>

                    <div class="SeePhotos"></div>
                </div>
            </div>

            <ul id="ThreeDSwiperBullets"><li id="0" class="active"></li><li id="1"></li><li id="2"></li><li id="3"></li><li id="4"></li></ul> <!-- Where slider bullets are automatically added according to the slider by JavaScript, Index.js file -->
        </div>
    </div>

有没有办法避免弄乱DOM?我可以用完全不同的方法来确定所选文本的位置吗?

要提取所选文本,您可以只遍历文本节点的选择并将它们连接起来

var content = window.getSelection().getRangeAt(0).cloneContents();
var treeWalker = document.createTreeWalker(content, NodeFilter.SHOW_TEXT);
var text = '';

while (treeWalker.nextNode()) { 
    text = text.concat(treeWalker.currentNode.nodeValue);
}
console.log(text);
编辑

如何使用标识符字符串包装所选内容:

String.prototype.splice = function( idx, rem, s ) {
    return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};

var range = window.getSelection().getRangeAt(0);
range.startContainer.nodeValue = range.startContainer.nodeValue.splice(range.startOffset, 0, '[highlight]');
range.endContainer.nodeValue = range.endContainer.nodeValue.splice(range.endOffset, 0, '[/highlight]');

感谢

所以,经过多次尝试,我可以做到

    var myAnchorNodeValue = window.getSelection().anchorNode.nodeValue;
    var myAnchorOffset = window.getSelection().anchorOffset
    var myFocusOffset =  window.getSelection().focusOffset

    var myFocusNodeLength = window.getSelection().focusNode.nodeValue.length;

    window.getSelection().anchorNode.nodeValue = myAnchorNodeValue.slice(0, myAnchorOffset) + "[IDENTIFY]" + myAnchorNodeValue.slice(myAnchorOffset);

    var myFocusNodeValue = window.getSelection().focusNode.nodeValue;

    if(window.getSelection().focusNode.nodeValue.length - myFocusNodeLength > 0) {
        myFocusOffset += window.getSelection().focusNode.nodeValue.length - myFocusNodeLength;
    }

    window.getSelection().focusNode.nodeValue = myFocusNodeValue.slice(0, myFocusOffset) + "[/IDENTIFY]" + myFocusNodeValue.slice(myFocusOffset);

    LAST_SELECTION = window.getSelection().getRangeAt(0);
    myDocument = document.documentElement.innerHTML;

这非常有效。

同样,整个问题在于识别DOM中的文本。使用纯文本的方法,如果用户选择了DOM中多次出现的单词,我想识别他实际选择的单词,而不是错误的单词,也不是所有的单词。现在我真的不明白了。这将只提取所选内容中的所有文本,而不是DOM中的所有文本。一个单词是否多次出现在DOM或选择中与选择IMHO无关,关键是我需要将整个DOM发送到服务器。它应该在所选文本中添加背景/边框/或其他内容,并承载整个MHTML页面。现在发送MHTML页面是可行的,唯一的问题是识别所选文本本身的位置,这样我就可以按照我想要的方式设置它的样式。抱歉,有点混乱。标识包装器必须是DOM节点吗?否则,您可以使用字符串标识符。同时,我将考虑使用实际节点包装所选文本/节点。不,不必如此。你说的字符串标识符到底是什么意思?很好!尽管我认为重要的是要提到这一点,而且到目前为止只有Firefox和Chrome支持。
String.prototype.splice = function( idx, rem, s ) {
    return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};

var range = window.getSelection().getRangeAt(0);
range.startContainer.nodeValue = range.startContainer.nodeValue.splice(range.startOffset, 0, '[highlight]');
range.endContainer.nodeValue = range.endContainer.nodeValue.splice(range.endOffset, 0, '[/highlight]');
    var myAnchorNodeValue = window.getSelection().anchorNode.nodeValue;
    var myAnchorOffset = window.getSelection().anchorOffset
    var myFocusOffset =  window.getSelection().focusOffset

    var myFocusNodeLength = window.getSelection().focusNode.nodeValue.length;

    window.getSelection().anchorNode.nodeValue = myAnchorNodeValue.slice(0, myAnchorOffset) + "[IDENTIFY]" + myAnchorNodeValue.slice(myAnchorOffset);

    var myFocusNodeValue = window.getSelection().focusNode.nodeValue;

    if(window.getSelection().focusNode.nodeValue.length - myFocusNodeLength > 0) {
        myFocusOffset += window.getSelection().focusNode.nodeValue.length - myFocusNodeLength;
    }

    window.getSelection().focusNode.nodeValue = myFocusNodeValue.slice(0, myFocusOffset) + "[/IDENTIFY]" + myFocusNodeValue.slice(myFocusOffset);

    LAST_SELECTION = window.getSelection().getRangeAt(0);
    myDocument = document.documentElement.innerHTML;