2012-02-17 9 views
5

estoy en busca de solución de navegadores (Chrome, FF, Opera> 10, es decir,> = 8) para el siguiente problema:Comprobar si el elemento especificado es la selección dentro

Hay algún código 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> 

y el usuario selecciona con el texto del mouse desde 'een' (en el nodo #verde) a 'blu' (en el nodo azul). ¿Cómo puedo verificar si #blue está dentro de la selección (no importa si está total o parcialmente seleccionado) y #red y #black no están en la selección. API simple sería el siguiente:

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

He intentado utilizar DOMSelection y rangos, pero el problema es que necesito para comprobar los elementos de estructura anidada. En Chrome puedo usar Range.intersectsNode(), pero este es el único navegador compatible con este método.

¿Alguna sugerencia?

Respuesta

3

Después de algunas investigaciones que he hecho solución basada en materiales siguientes: 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

En caso de toda IE8 nodo debe seleccionarse pero esto es aceptable para mí.

Aquí es un poco de parque infantil en jsFiddle: http://jsfiddle.net/58Uvd/ Y aquí es código:

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

}()); 

y uso:

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

Tal vez esto le ayuda para un resultado perfecto en IE <9: containsRange: function (rango) { return this.userRange.inRange (rango) || range.inRange (this.userRange) || this.userRange.compareEndPoints ("EndToStart", rango)> -1 && this.userRange.compareEndPoints (rango "StartTo End") <1; } –

Cuestiones relacionadas