2015-01-27 3 views
1

Я работаю над расширением JavaScript, которое должно каким-то образом передать выделенный текст и отправить его на мой сервер. «Обертка» выполняется так, чтобы сервер мог идентифицировать точное положение выделенного текста, даже если были дубликаты.window.getSelection(). GetRangeAt (0) innerHTML без прерывания узлов

Я воспользовался этой ссылкой, How to change CSS of selected text using Google Chrome Extension, чтобы получить выделенный текст. Впоследствии я следовал этому подходу, How to get selected html text with 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> 

Я использую f5e975aa551d1ae4e91e8ce9 здесь, чтобы определить текст, так же как и любой вид уникального текста, который, скорее всего, не будет существовать в обычной веб-страницы. Как вы видите выше, «IntroDiv» присутствует дважды, а также «ProjectsSlider». Это одна и та же часть страницы перед вызовом любых функций.

<div id="IntroDiv"> 
     <p> 
      <img src="Theme/Images/Intro/logo.png"> 
      <br/><br/> 
      A neat theme 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"> <!-- Add your slides here. You're free to have different styles or content --> 
         <div class="swiper-slide" style="background-image:url('http://placehold.it/215x270/');">Project 1</div> 
         <div class="swiper-slide" style="background-image:url('http://placehold.it/215x270/');">Project 2</div> 
         <div class="swiper-slide" style="background-image:url('http://placehold.it/215x270/');">Project 3</div> 
         <div class="swiper-slide" style="background-image:url('http://placehold.it/215x270/');">Project 4</div> 
         <div class="swiper-slide" style="background-image:url('http://placehold.it/215x270/');">Project 5</div> 
        </div> 

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

      <ul id="ThreeDSwiperBullets"></ul> <!-- Where slider bullets are automatically added according to the slider by JavaScript, Index.js file --> 
     </div> 
    </div> 

Это мой код.

//save_last_element.js  
document.body.addEventListener('contextmenu', function(e) { 
    LAST_SELECTION = window.getSelection().getRangeAt(0); 
}, false); 


//script.js 
if (LAST_SELECTION) { 
    var mySelection = LAST_SELECTION.cloneRange(); 

    var selectionContents = mySelection.cloneContents(); 
    var div = document.createElement("f5e975aa551d1ae4e91e8ce9"); 
    div.appendChild(selectionContents); 
    mySelection.insertNode(div); 
} 

Есть ли способ избежать испортить DOM? Могу ли я каким-то образом определить позицию выбранного текста с помощью совершенно другого подхода?

ответ

1

Таким образом, после того, как много попыток, я мог бы сделать Это.

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; 

Это сработало отлично.

+1

Хороший! Хотя я думаю, что важно отметить, что ['Selection.anchorNode' еще не является частью официальной спецификации] (https://developer.mozilla.org/en-US/docs/Web/API/Selection.anchorNode) и по сей день поддерживается только Firefox и Chrome. –

1

Для извлечения выделенного текста вы можете выбрать только узлы текста и объединить их.

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); 

EDIT

Как обернуть выбор со строкой идентификатора:

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]'); 

splice Любезность this post

+0

Опять же, «Вся проблема заключается в идентификации текста внутри DOM. Используя подход, основанный только на тексте, если пользователь выбрал слово, которое было несколько раз в DOM, я хочу определить тот, который он выбрал, и не ошибаюсь, и не все из них ». – TheNavigat

+0

Теперь я действительно не понимаю. Этот фрагмент будет извлекать весь текст в пределах выделения, а не весь текст в DOM. Является ли «слово в DOM (или выборе) несколько раз» или не имеет никакого отношения к выборам IMHO. –

+0

Ну, дело в том, что мне нужно отправить всю DOM на сервер. Он должен добавить фон/границу/или что-то другое в выделенный текст и разместить всю страницу MHTML. Прямо сейчас пересылка страницы MHTML работает, и единственная проблема заключается в том, чтобы определить место для выбранного текста, чтобы я мог его стилизовать так, как я хочу. Извините, что немного запутался. – TheNavigat

Смежные вопросы