2012-08-31 3 views
2

문서의 선택한 텍스트에 클래스를 추가하려고합니다. 문제는 사용자가 페이지의 모든 텍스트를 선택할 수 없도록하려는 것입니다 (예를 들어 command + A를 사용하여 ...). 그래서 범위에서 노드를 제거하고 싶습니다. 하기 위해서. 이 페이지에는 많은 텍스트/중첩 된 div가 있으므로 선택할 수있는 요소에 있는지 확인하기 위해 추가 된 클래스를 사용하면 시간이 많이 걸리거나 느려집니다.cssClass 지정한 div의 선택된 텍스트에만 적용

나는 조금 더 나은 것을 설명하기 위해 피들을 만들었습니다. http://jsfiddle.net/thomasjonas/BhKFt/20/

이 예에서 모든 텍스트를 선택하면 클래스가 모든 div에 추가됩니다. 나는 단지 CSS를 div에 'yes'클래스로 적용하기를 원한다. 거기에 좋은 아닌 브라우저 - 충돌 솔루션이 있나요?

미리 감사드립니다.

답변

2

다음은 클래스 "예"가있는 각 요소를 검사하여 선택을 가로 지르기 때문에 조금 무거 우며 비효율적입니다. 예를 들어 선택 항목이 "yes"클래스가있는 단일 요소 내에 완전히 포함되어 있는지 미리 확인하여 개선 할 수 있습니다. Rangy가 독점적으로 사용하는 범위 객체 방법 인 intersection()을 사용합니다.

데모 : http://jsfiddle.net/timdown/BhKFt/23/

코드 :

// getElementsByClassName implementation for browsers without it 
// (IE <= 7, for example) 
var getElementsByClassName = 
    (typeof document.documentElement.getElementsByClassName != "undefined") ? 

    function(el, cssClass) { 
     return el.getElementsByClassName(cssClass); 
    } : 
    function(el, cssClass) { 
     var allEls = el.getElementsByTagName("*"); 
     var elsWithClass = []; 
     var classRegex = new RegExp("(?:^|\\s)" + cssClass + "(?:\\s|$)"); 
     for (var i = 0, len = allEls.length, el; i < len; ++i) { 
      el = allEls[i]; 
      if (el.className && classRegex.test(el.className)) { 
       elsWithClass.push(el); 
      } 
     } 
     return elsWithClass; 
    }; 

$(document).ready(function(){ 
    rangy.init(); 
    $(document).mouseup(function(){ 
     var sel = rangy.getSelection(); 
     var range = sel.getRangeAt(0); 
     var classApplier = rangy.createCssClassApplier("tmp"); 

     var els = getElementsByClassName(document.body, "yes"); 

     // Create an array of ranges that represent the intersection of 
     // the selection with each "yes" element 
     var rangesWithClass = []; 
     for (var i = 0, len = els.length, elRange; i < len; ++i) { 
      if (range.intersectsNode(els[i])) { 
       elRange = rangy.createRange(); 
       elRange.selectNode(els[i]); 
       rangesWithClass.push(range.intersection(elRange)); 
       elRange.detach(); 
      } 
     } 

     // Apply the class to the ranges obtained in the last step 
     for (i = 0, len = rangesWithClass.length; i < len; ++i) { 
      classApplier.applyToRange(rangesWithClass[i]); 
      rangesWithClass[i].detach(); 
     } 

     sel.removeAllRanges(); 
    }); 
}); 

옵션이 rangy.createCssClassApplier()에 전달 된 객체에 대한 필터링 옵션의 일종이 있다면 그것은 유용 할 수 있습니다. 나는 생각할 것이다.

+0

안녕하세요, 내 질문에 답변 해 주셔서 감사드립니다 ... 이전에 답변하지 않으 셨으니 죄송합니다 ... 알림을 사용 중지 한 것 같습니다. 코드가 꽤 무거운 사이트 그래서 당신의 솔루션이 도움이되기를 바라고 있어요 ... 그 동안 유효하지 않은 선택을 무너 뜨리는 또 다른 해결책이 떠올랐다는 의미입니다. 즉, '아니오'클래스가 선택되었을 때). 그 코드는 여기에서 볼 수 있습니다 : http://jsfiddle.net/thomasjonas/CM2wJ/ – thomasjonas

관련 문제