desencadenar un evento cuando contenteditable se cambia

Cuando un divs se cambia el valor de ¿cómo puedo activar un evento?

<div class="changeable" contenteditable="true"> Click this div to edit it <div>

Así que cuando sus cambios de contenido quiero crear un alerta y/o hacer otras cosas:

$('.changeable').text().change(function() {
  alert('Handler for .change() called.');
});
InformationsquelleAutor johnmosly | 2011-06-06

12 Kommentare

  1. 45

    Sólo almacenar el contenido de una variable y comprobar si es diferente después de blur() evento. Si es diferente, la tienda de los nuevos contenidos.

    var contents = $('.changeable').html();
    $('.changeable').blur(function() {
        if (contents!=$(this).html()){
            alert('Handler for .change() called.');
            contents = $(this).html();
        }
    });

    ejemplo: http://jsfiddle.net/niklasvh/a4QNB/

    • la posición del cursor no es correcto en IE11
    • Muchas gracias @Niklas !
    • Este es un sucio hack y no debe ser utilizado.
    • Modificado @Niklas código y se añade la nueva respuesta here
    • No funciona en mi Chrome 65 – sólo cuando ‘borrosa’ (enfocado a cabo).
  2. 17

    Usted puede simplemente utilizar el enfoque/desenfoque evento con la función data() de jQuery :

    //Find all editable content.
    $('[contenteditable=true]')
        //When you click on item, record into data("initialText") content of this item.
        .focus(function() {
            $(this).data("initialText", $(this).html());
        });
        //When you leave an item...
        .blur(function() {
            //...if content is different...
            if ($(this).data("initialText") !== $(this).html()) {
                //... do something.
                console.log('New data when content change.');
                console.log($(this).html());
            }
        });
    });

    ACTUALIZACIÓN: Vainilla Con JS

    //Find all editable content.
    var contents = document.querySelectorAll("[contenteditable=true]");
    [].forEach.call(contents, function (content) {
        //When you click on item, record into `data-initial-text` content of this item.
        content.addEventListener("focus", function () {
            content.setAttribute("data-initial-text", content.innerHTML);
        });
        //When you leave an item...
        content.addEventListener("blur", function () {
            //...if content is different...
            if (content.getAttribute("data-initial-text") !== content.innerHTML) {
                //... do something.
                console.log("New data when content change.");
                console.log(content.innerHTML);
            }
        });
    });
    • +1 por ser la única solución para mi (sin contabilizar) pregunta «¿cómo se puede detectar cuando la edición comienza?»… así que usted puede mostrar un botón de guardar, etc… Todo lo relacionado con las preguntas se centraron en la detección de cambio, no el inicio de la sesión de edición…
    • +1 para mostrar cómo lidiar con todos los elementos editable sin tener que hacer referencia a la identificación específica. Funciona muy bien para crear un simple grid editable con una tabla html.
  3. 12

    He construido un plugin de jQuery para hacer esto.

    (function ($) {
        $.fn.wysiwygEvt = function () {
            return this.each(function () {
                var $this = $(this);
                var htmlold = $this.html();
                $this.bind('blur keyup paste copy cut mouseup', function () {
                    var htmlnew = $this.html();
                    if (htmlold !== htmlnew) {
                        $this.trigger('change')
                    }
                })
            })
        }
    })(jQuery);

    Usted simplemente puede llamar $('.wysiwyg').wysiwygEvt();

    También se puede quitar /agregar eventos si desea

    • ¿Qué es that en that.bind(...)?
    • blur keyup paste copy cut mouseup es todo el potencial de los eventos de cambio de
    • that.bind(...) debe ser $this.bind(...)
    • Esto es genial, excepto htmlold necesidades para actualizar en el cambio. De lo contrario, si se cambia de nuevo a la original htmlold que el evento no fuego.
  4. 11

    la mejor solución para esto en la actualidad es el HTML5 evento de entrada

    <div contenteditable="true" id="content"></div>

    en su jquery.

    $('#content').on('input', (e) => {
        //your code here
        alert('changed')
    });
    • Funciona muy bien! 👍
    • Esto probablemente debería ser aceptado contestar – lo considero el más sencillo & también mejor.
  5. 7

    Es más sencillo hacerlo con EventListener (no es un método jQuery):

    documento.getElementById("editor").addEventListener("input", function() { 
    alert("evento de entrada despedido"); 
    }, false); 
    

    • Esto es bueno para los últimos Mozilla y los navegadores WebKit, pero lamentablemente no es compatible con la contenteditable en cualquier versión de fo IE u Opera.
    • esto también puede ser usado con jquery para facilitar la attchment a clases, $(‘.la clase’).en(‘input’, function(){})
  6. 2

    Sin embargo, otra versión de jquery. Ver en jsFiddle aquí.

    var $editableContent = $("#mycontent");
    
    // Implement on text change
    $editableContent.on("focus", function(event) {$(this).data("currentText", $(this).text());});
    
    $editableContent.on("blur", function (event) {
            if ($(this).text() != $(this).data("currentText")) {
                    $(this).trigger('change');}});
    
    
    // Wire onchange event
    $editableContent.on("change", function(){alert("Text changed to: " + $(this).text())});
  7. 1

    Aquí es un jquery-versión:

    function fix_contenteditableOnchange(obj)
    {
         div=$(obj);
         var contents = div.html();
         var onchange = div.attr('onchange');
         div.blur(function() {
          if (contents!=$(this).html()){
            eval(onchange);
            fix_contenteditableOnchange(obj);
          }
         });
    }

    A probar esto.

    • ¿Por qué la llamada recursiva? Podría usted acaba de hacer contents = $(this).html()?
  8. 1

    En chrome y tal vez en otros navegadores no es bug, cuando el usuario presiona tab va a crear el espacio y anexar apple se expanden o algo como eso.. para eliminar ese usuario

    var contents = $('.changeable').html();
    $('.changeable').blur(function() {
       if (contents!=$(this).html()){
     alert('Handler for .change() called.');
          $(".Apple-tab-span").remove();
           contents = $(this).html();
           contentsTx = $(this).text();
           alert(contentsTx);
    
       }
    });

    Esto eliminará el lapso..
    es igual que el anterior código sólo se ha modificado poco, o u puede agregar

    .Apple-tab-span
    {
      Display:None;
    }

    y esto también va a resolver el problema ..
    http://jsfiddle.net/a4QNB/312/

    Acaba de modificar @Nikals respuesta …

  9. 1

    Lo que tienes que hacer es hacer una conjunción de blur y DOMSubtreeModified eventos en su contenteditable elementos.

    JS:

    var contentEdited = false;
    
    function fn($el) {
      if (contentEdited) {
        var text = $el[0].innerText.trim();
        console.log(text);
        contentEdited = false;
      }
    }
    $("div.editable").on("blur", function() {
      fn($(this));
    }).on("DOMSubtreeModified", function() {
      contentEdited = true;
    });

    HTML:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="editable" contenteditable="true">Click this div to edit it<div>

    • DOMSubtreeModified va a desaparecer eventualmente y por lo tanto probablemente debería ser evitado en la mayoría de los casos. También puede reducir drásticamente abajo DOM rendimiento.
  10. 0

    Otra solución que es versión ligeramente modificada de la anterior, pero puede ser más cómodo de usar para algunos de ustedes.

    Idea es salvar valor de origen y compárelo con el valor actual de ‘blur’ evento. Puedo guardar valor de origen como atributo de la editables etiqueta div (en lugar de crear variable para el valor de origen). El uso de atributos como contenedor para el valor de origen es más cómodo cuando uno tiene un gran número de editable divs en la tabla (como las células). Por lo que es fácil obtener el valor de origen ya que no es necesario crear muchas variables.

    Ver mi código de ejemplo completo:

    editable div

    <td><div contenteditable="true" class="cell" origin="originValue">originValue</div></td>

    la detección de cambios en el desenfoque de

    var cells = $("#table").find('td>div[contenteditable=true]');
    
    cells.each(function () {    
    
            $(this).blur(function() {
    
                        if ($(this).text() != $(this).attr("origin")) {
                            console.log('changed');
                        }
            });    
    });
    • Este no es un buen enfoque. Su valororiginal puede tener un código html no válido pero los navegadores siempre trataremos de solucionarlo en editable div, por lo que incluso cuando el contenido no cambia, su condición de prueba fallará porque el navegador se ha convertido su <br / > a <br / ></br>
    • Aquí, en el futuro, he utilizado los datos de las etiquetas para este propósito y que gran trabajo!
  11. 0

    JS:

    function myFunction(){
      alert('Handler for .change() called.');
    }

    HTML:

    <div class="changeable" contenteditable="true" onfocusout="myFunction()" > Click this div to edit it <div>

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...