2012-02-17 59 views
5

我搜索跨瀏覽器溶液(鉻,FF,歌劇> 10,IE> = 8)以下的問題:檢查是否指定的元素是內部選擇

有一些HTML代碼:

<div> 
    <div id="one"> 
     <p id="red">red</p> 
     <p id="green">green</p> 
    </div> 
    <div id="two"> 
     <p id="blue">blue</p> 
     <p id="black">black</p> 
    </div> 
</div> 

和用戶使用鼠標文本從'een'(在#green節點)到'blu'(在#blue節點)中進行選擇。如何檢查#blue是否在選擇範圍內(全選或部分選擇無關緊要),#red和#black不在選擇中。 簡單的API應該是這樣的:

Selection.isElementSelected(document.getElementById('black')); 

我試着使用DOMSelection和範圍,但問題是,我需要檢查嵌套的結構元素。在Chrome中,我可以使用Range.intersectsNode(),但這是唯一支持此方法的瀏覽器。

有什麼建議嗎?

回答

3

一些研究,我做了基於以下材料的解決方案後: https://developer.mozilla.org/en/DOM/range

http://msdn.microsoft.com/en-us/library/ms535872(v=vs.85).aspx

http://www.quirksmode.org/dom/range_intro.html

在IE8中所有節點的情況下,必須選擇,但是這對我來說是可以接受的。

這裏是的jsfiddle一些遊樂場:http://jsfiddle.net/58Uvd/ 這裏是代碼:

(function() { 

    function UserRange (win) { 
     this.win = win || window; 
     this.doc = this.win.document; 

     this.userRange = this.createUserRange(); 
    } 

    var NonIEPrototype = { 

     constructor: UserRange, 

     createUserRange: function() { 
      var selection = this.win.getSelection(); 
      return selection.rangeCount 
       ? selection.getRangeAt(0) 
       : this.doc.createRange(); 
     }, 

     overlapsNode: function (node) { 
      return this.intersectsNode(node); 
     }, 


     intersectsNode: function (node) { 
      // this method is implemented in Firefox with Gecko before 1.9 
      // and other non-IE browsers 
      if (this.userRange.intersectsNode) { 
       return this.userRange.intersectsNode(node); 
      } 

      return this.intersectsRange(this.createRangeWithNode(node)); 
     }, 

     createRangeWithNode: function (node) { 
      var rangeWithNode = node.ownerDocument.createRange(); 
      try { 
       rangeWithNode.selectNode(node); 
      } 
      catch (ex) { 
       rangeWithNode.selectNodeContents(node); 
      } 
      return rangeWithNode; 
     }, 

     intersectsRange: function (range) { 
      return this.userRange.compareBoundaryPoints(Range.END_TO_START, range) === -1 && 
       this.userRange.compareBoundaryPoints(Range.START_TO_END, range) === 1; 
     } 
    }; 

    var IEPrototype = { 

     constructor: UserRange, 

     createUserRange: function() { 
      return this.doc.selection.createRange(); 
     }, 

     overlapsNode: function (node) { 
      var rangeWithNode = this.createRangeWithNode(node); 
      return this.containsRange(rangeWithNode); 
     }, 

     createRangeWithNode: function (node) { 
      var range = node.ownerDocument.selection.createRange(); 
      range.moveToElementText(node); 
      return range; 
     }, 

     containsRange: function (range) { 
      return this.userRange.inRange(range); 
     } 
    }; 

    UserRange.prototype = window.getSelection ? NonIEPrototype : IEPrototype; 
    window.UserRange = UserRange; 

}()); 

與用法:

var userRange = new UserRange(); 
userRange.overlapsNode(document.getElementById('node-to-check')); 
+0

也許這可以幫助你一個完美的結果在IE <9: containsRange:function(range){ return this.userRange.inRange(range)|| range.inRange(this.userRange)|| this.userRange.compareEndPoints(「EndToStart」,range)> -1 && this.userRange.compareEndPoints(「StartToEnd」,range)<1; } – 2013-01-03 15:34:04