2009-10-13 13 views

Respuesta

17

Por "ventana de contenido editable" Voy a suponer que quiere decir un elemento con contenteditable encendido o un documento con designMode encendido.

También hay dos casos a tener en cuenta: el caso cuando el usuario ha hecho una selección y el caso donde hay solo un símbolo de intercalación. El código siguiente funcionará en ambos casos y le proporcionará el elemento más interno que contiene la selección por completo. Si la selección está completamente contenida dentro de un nodo de texto, es un poco complicado obtener ese nodo de texto en IE (trivial en otros navegadores), así que no he proporcionado ese código aquí. Si lo necesitas, puedo desenterrarlo.

function getSelectionContainerElement() { 
    var range, sel, container; 
    if (document.selection && document.selection.createRange) { 
     // IE case 
     range = document.selection.createRange(); 
     return range.parentElement(); 
    } else if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt) { 
      if (sel.rangeCount > 0) { 
       range = sel.getRangeAt(0); 
      } 
     } else { 
      // Old WebKit selection object has no getRangeAt, so 
      // create a range from other selection properties 
      range = document.createRange(); 
      range.setStart(sel.anchorNode, sel.anchorOffset); 
      range.setEnd(sel.focusNode, sel.focusOffset); 

      // Handle the case when the selection was selected backwards (from the end to the start in the document) 
      if (range.collapsed !== sel.isCollapsed) { 
       range.setStart(sel.focusNode, sel.focusOffset); 
       range.setEnd(sel.anchorNode, sel.anchorOffset); 
      } 
     } 

     if (range) { 
      container = range.commonAncestorContainer; 

      // Check if the container is a text node and return its parent if so 
      return container.nodeType === 3 ? container.parentNode : container; 
     } 
    } 
} 
+0

Tim, esto es exactamente lo que estaba buscando. Le agradecería si también puede cavar en el caso de IE donde la selección está contenida en un nodo de texto. Gracias. –

+0

Por cierto, el caso de IE donde devuelve range.parentElement() siempre parece devolver el elemento de cuerpo aunque el símbolo de intercalación estaba en el texto que dentro de un nodo de anclaje, por ejemplo. En este HTML xyz si el símbolo de intercalación estaba entre 'x' y 'y', ¿no debería parentElement() devolver el nodo 'a'? –

+0

Sí, debería. No he tenido problemas con 'parentElement()' antes. ¿Tiene una página que pueda ver que muestre el problema? –

3

También puede utilizar el Rangy Biblioteca:

elementAtCursor = rangy.getSelection().anchorNode.parentNode 
Cuestiones relacionadas