2010-02-01 4 views
4

ont ce html:Comment supprimer un élément HTML dans une div avec l'attribut contentEditable?

<div id="editable" contentEditable="true" > 
    <span contentEditable="false" >Text to delete</span> 
</div> 

besoin que la durée (et tout le texte à l'intérieur) est retiré avec une seule backspace, est-il possible?

+0

Pourriez-vous fournir plus d'informations sur ce qui se passe lorsque l'utilisateur appuie sur le retour arrière lorsque, par exemple, le curseur se trouve au milieu d'un nœud de texte ou au début de la zone modifiable. –

Répondre

9

Cela s'est avéré plus compliqué que je ne le pensais. Ou je l'ai rendu plus compliqué que nécessaire. Quoi qu'il en soit, cela devrait fonctionner dans tous les grands navigateurs:

function getLastTextNodeIn(node) { 
    while (node) { 
     if (node.nodeType == 3) { 
      return node; 
     } else { 
      node = node.lastChild; 
     } 
    } 
} 

function isRangeAfterNode(range, node) { 
    var nodeRange, lastTextNode; 
    if (range.compareBoundaryPoints) { 
     nodeRange = document.createRange(); 
     lastTextNode = getLastTextNodeIn(node); 
     nodeRange.selectNodeContents(lastTextNode); 
     nodeRange.collapse(false); 
     return range.compareBoundaryPoints(range.START_TO_END, nodeRange) > -1; 
    } else if (range.compareEndPoints) { 
     if (node.nodeType == 1) { 
      nodeRange = document.body.createTextRange(); 
      nodeRange.moveToElementText(node); 
      nodeRange.collapse(false); 
      return range.compareEndPoints("StartToEnd", nodeRange) > -1; 
     } else { 
      return false; 
     } 
    } 
} 

document.getElementById("editable").onkeydown = function(evt) { 
    var sel, range, node, nodeToDelete, nextNode, nodeRange; 
    evt = evt || window.event; 
    if (evt.keyCode == 8) { 
     // Get the DOM node containing the start of the selection 
     if (window.getSelection && window.getSelection().getRangeAt) { 
      range = window.getSelection().getRangeAt(0); 
     } else if (document.selection && document.selection.createRange) { 
      range = document.selection.createRange(); 
     } 

     if (range) { 
      node = this.lastChild; 
      while (node) { 
       if (isRangeAfterNode(range, node)) { 
        nodeToDelete = node; 
        break; 
       } else { 
        node = node.previousSibling; 
       } 
      } 

      if (nodeToDelete) { 
       this.removeChild(nodeToDelete); 
      } 
     } 
     return false; 
    } 
}; 
+0

non, je dois supprimer uniquement l'élément à gauche du curseur de texte | – byterussian

+0

comment puis-je rendre ce code plus dynamique en ajoutant span usnig Entrer KeyDown Appuyez sur et enlevez la durée en utilisant le retour arrière aidez-moi si vous le pouvez. – Basbous

+0

cela fonctionne dans crome mais pas dans firefox. Y a-t-il un problème lié au nœud dans le navigateur Firefox? J'ai besoin d'aide, s'il vous plaît [voir le lien ci-joint] (http://jsfiddle.net/C5R8M/7). –

2

Parce que vous voulez supprimer tout l'élément, il est préférable de le faire contenteditable="false" afin que le navigateur ne laissera pas le contenu d'un élément à supprimer.

Ensuite, vous pouvez utiliser cet attribut pour les tests dans le gestionnaire d'événements comme suit:

$('#editable').on('keydown', function (event) { 
    if (window.getSelection && event.which == 8) { // backspace 
     // fix backspace bug in FF 
     // https://bugzilla.mozilla.org/show_bug.cgi?id=685445 
     var selection = window.getSelection(); 
     if (!selection.isCollapsed || !selection.rangeCount) { 
      return; 
     } 

     var curRange = selection.getRangeAt(selection.rangeCount - 1); 
     if (curRange.commonAncestorContainer.nodeType == 3 && curRange.startOffset > 0) { 
      // we are in child selection. The characters of the text node is being deleted 
      return; 
     } 

     var range = document.createRange(); 
     if (selection.anchorNode != this) { 
      // selection is in character mode. expand it to the whole editable field 
      range.selectNodeContents(this); 
      range.setEndBefore(selection.anchorNode); 
     } else if (selection.anchorOffset > 0) { 
      range.setEnd(this, selection.anchorOffset); 
     } else { 
      // reached the beginning of editable field 
      return; 
     } 
     range.setStart(this, range.endOffset - 1); 


     var previousNode = range.cloneContents().lastChild; 
     if (previousNode && previousNode.contentEditable == 'false') { 
      // this is some rich content, e.g. smile. We should help the user to delete it 
      range.deleteContents(); 
      event.preventDefault(); 
     } 
    } 
}); 

demo on jsfiddle

+0

J'ai résolu mon problème – Saravanan

0

semble fonctionner par défaut (sans javascript) dans la dernière version Chrome (je l'ai testé avec 61.0.3163.100).

Questions connexes