2013-12-15 3 views
0

웹 페이지의 어떤 단어 위로 마우스를 가져 가서 그 단어로 그 단어 위에 팝업을 표시하고 싶습니다. 거대한 성능 문제가 없다면 거의 불가능한 것처럼 보이므로 마우스를 놓기 대신 더블 클릭을 시도했습니다.선택한 단어를 스팬으로 감싸는 방법

두 번 클릭하면 단어의 텍스트를 감지 할 수 있지만 페이지의 단어 자체는 아무 것도 할 수 없습니다. 기본적으로 나는 선택된 텍스트를 span 태그로 감싸서 상대적으로 위치를 지정할 수 있습니다. 전에 하이 라이터로 해봤지만, 어떻게해야할지 모르겠다.

참고 :이 기능은 Firefox에서만 작동하면됩니다.

+1

아마 도움이되지만 더 자세한 정보를 필요로 할 수 있습니다. 첫째, 기존 웹 페이지에이 기능을 추가 할 것인지 아니면이 기능을 자신의 웹 페이지로 추가 할 것입니까? 이것은 물론 큰 차이를 만든다;) 또한, 당신이 달성하려고하는 것을 보여주는 바이올린 (fiddlejs.net)을 게시 할 수 있다면 그것은 또한 많은 도움이 될 수있다. 언뜻 보면 이벤트 위임과 게으른로드는 친구입니다. –

+0

이것은 기존 웹 페이지 (Firefox Addon) 용입니다. – Ian

답변

3

이러한 기능을 사용할 수 있습니다 : 이것은 B-태그 선택을 둘러싼

var range = window.getSelection().getRangeAt(0); 
var newNode = document.createElement("b"); 
range.surroundContents(newNode); 

.

+0

'b' 태그에 클래스가있을 수있는 방법은 없습니까? – Ian

+1

예상대로 작동하는 것으로 보입니다. 'var range = window.getSelection(). getRangeAt (0); range.surroundContents ($ ("", {'클래스 ':'테스트 '}) [0]),' – megawac

+0

newNode .className = 'foo' '. –

1

mouseover 이벤트에서는 불가능하지 않습니다. Firefox 20 이상에서 표준화되고 지원되는 document.caretPositionFromPoint()을 사용할 수 있으며 WebKit의 독점적 인 동등 물로 돌아갈 수 있습니다. 마우스 이벤트를 처리

http://jsfiddle.net/2zzjL/6/

단계는 다음과 같습니다

  • 가 커서의 범위를 만들기 이벤트
  • 에서 좌표 가져 오기 표시하는 경우
    • 이 단어 팝업 숨기기 document.caretPositionFromPoint() 또는 동등 물을 사용하는 커서 좌표
    • 범위의 컨테이너 노드가 텍스트 노드 인 경우 오프셋은 문자 색인 wi입니다. 우리가 단어
    • 업데이트를 얻을 수있는 범위를 전체 단어
    • 전화 getBoundingClientRect()을 포함하는 범위를 얻기 위해 공백을 칠 때까지 거기에서
    • 는, 텍스트 노드의 텍스트 앞뒤로 확장 텍스트 노드의 텍스트 얇은 단어
    • 위치의 좌표와 그 좌표에서 멀리 오프셋 일부의 단어 팝업 요소는 데모가 매우 제한되어

    (예를 들어,이 요소를 교차하는 단어로 작동하지 않습니다 보여 경계, 매우 조잡한 단어 탐지 및 re는 최적화를위한 충분한 범위입니다.)하지만 시작하기에 충분해야합니다. document.caretPositionFromPoint()을 지원하지 않는 IE를 제외한 현재 브라우저에서 작동합니다.

    다음은 중요한 코드 :

    function expandToWord(str, offset) { 
        var start = offset; 
        while (start >= 1 && /\S/.test(str.charAt(start - 1))) { 
         --start; 
        } 
    
        var end = offset, len = str.length; 
        while (end < len && /\S/.test(str.charAt(end))) { 
         ++end; 
        } 
    
        return { 
         start: start, 
         end: end, 
         word: str.slice(start, end) 
        }; 
    } 
    
    var wordDiv = document.createElement("div"); 
    wordDiv.className = "word"; 
    
    var createRangeFromPoint = (function(doc) { 
        // Try standards-based method first 
        if (typeof doc.caretPositionFromPoint != "undefined") { 
         return function(x, y) { 
          var pos = doc.caretPositionFromPoint(x, y); 
          var range = null; 
          if (pos) { 
           range = doc.createRange(); 
           range.setStart(pos.offsetNode, pos.offset); 
           range.collapse(true); 
          } 
          return range; 
         }; 
        } 
    
        // Now try WebKit's proprietary method 
        else if (typeof doc.caretRangeFromPoint != "undefined") { 
         return function(x, y) { 
          return doc.caretRangeFromPoint(x, y); 
         }; 
        } 
    
        // Give up 
        else { 
         return function() { return null; }; 
        } 
    })(document); 
    
    function mouseEventHandler(e) { 
        if (wordDiv.parentNode) { 
         wordDiv.parentNode.removeChild(wordDiv); 
        } 
        var range = createRangeFromPoint(e.clientX, e.clientY); 
        if (range) { 
         if (range.startContainer.nodeType == 3) { 
          var wordInfo = expandToWord(range.startContainer.data, range.startOffset); 
          if (wordInfo.word) { 
           range.setStart(range.startContainer, wordInfo.start); 
           range.setEnd(range.startContainer, wordInfo.end); 
    
           var rect = range.getBoundingClientRect(); 
    
           // Get the difference between client and page coordinates from the event 
           // for positioning the word div 
           var offsetX = e.clientX - e.pageX; 
           var offsetY = e.clientY - e.pageY; 
    
           wordDiv.style.left = (rect.left + offsetX) + "px"; 
           wordDiv.style.top = (rect.top + offsetY - 20) + "px"; 
           wordDiv.innerHTML = ""; 
           wordDiv.appendChild(document.createTextNode(wordInfo.word)); 
    
           document.body.appendChild(wordDiv); 
          } 
         } 
        } 
    } 
    
    document.onmousemove = mouseEventHandler; 
    document.onmouseover = mouseEventHandler; 
    document.onmouseout = mouseEventHandler; 
    
  • +0

    이 코드를 설명 할 수 있습니까? 캐럿 위치가 감지되지만 캐럿 아래에있는 단어를 어떻게 감지합니까? – Ian

    +0

    @Ian : 캐럿 위치에서 가져 오는 범위는 노드의 텍스트 내의 텍스트 노드와 오프셋에 대한 참조를 가지며, 여기에서 예제의 'expandToWord()'함수를 사용하여 단어를 추정 할 수 있습니다. –

    관련 문제