trigger an event when contenteditable is changed

JqueryContenteditable

Jquery Problem Overview


When a divs value is changed, how Can I trigger an event?

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

So when its content changes I want to create an alert and/or do other things:

$('.changeable').text().change(function() {
  alert('Handler for .change() called.');
});

Jquery Solutions


Solution 1 - Jquery

Just store the contents to a variable and check if it is different after blur() event. If it is different, store the new contents.

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

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

Solution 2 - Jquery

You can simply use focus/blur event with data() function of 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());
        }
    });
});

UPDATE: With Vanilla 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);
        }
    });
});

Solution 3 - Jquery

the best solution to this currently is the HTML5 input event

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

in your jquery.

$('#content').on('input', (e) => {
    // your code here
    alert('changed')
});

Solution 4 - Jquery

I built a jQuery plugin to do this.

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

You can simply call $('.wysiwyg').wysiwygEvt();

You can also remove / add events if you wish

Solution 5 - Jquery

It's more simple to do it using EventListener (not a jQuery method):

document.getElementById("editor").addEventListener("input", function() {
alert("input event fired");
}, false);

Solution 6 - Jquery

This is my approach...

$('.changeable').focusout(function() {
  alert('Handler for .change() called.');
});

Solution 7 - Jquery

Yet another version in jquery. View in jsFiddle here.

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

Solution 8 - Jquery

Here is a jquery-version:

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);
      }
     });
}

Try this out.

Solution 9 - Jquery

In chrome and maybe in other browsers there is bug, when user presses tab it will create space and append apple-be span or some thing like that.. to remove that user

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);
       
   }
});

This will remove the span.. it same as above code just modified it little, or u can add

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

and this will also solve problem .. http://jsfiddle.net/a4QNB/312/

Just modified @Nikals answer ...

Solution 10 - Jquery

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

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

Solution 11 - Jquery

Another solution which is slightly modified version of previous ones but it may be more comfortable to use for some of you.

Idea is to save origin value and compare it with current value in 'blur' event. I save origin value as attribute of editable div tag (instead of creating variable for origin value). Using attribute as container for origin value is more comfortable when one has a huge number of editable divs in table (as cells). So it is easy to get origin value since you don't need to create many variables.

See my complete example code:

editable div

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

detecting changes in blur

var cells = $("#table").find('td>div[contenteditable=true]');

cells.each(function () {    

        $(this).blur(function() {
                    
                    if ($(this).text() != $(this).attr("origin")) {
                        console.log('changed');
                    }
        });    
});

Solution 12 - Jquery

(EDIT: DOMSubtreeModified is deprecated.)


What you have to do is make a conjunction of blur and DOMSubtreeModified events on your contenteditable elements.

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;
});

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjohnmoslyView Question on Stackoverflow
Solution 1 - JqueryNiklasView Answer on Stackoverflow
Solution 2 - JqueryBruno J. S. LesieurView Answer on Stackoverflow
Solution 3 - JqueryCanaan EtaiView Answer on Stackoverflow
Solution 4 - JqueryBlowsieView Answer on Stackoverflow
Solution 5 - JqueryVasGView Answer on Stackoverflow
Solution 6 - JqueryMarcel BarrazaView Answer on Stackoverflow
Solution 7 - JquerydcapeloView Answer on Stackoverflow
Solution 8 - JquerySvenView Answer on Stackoverflow
Solution 9 - JquerynikunjMView Answer on Stackoverflow
Solution 10 - JqueryπterView Answer on Stackoverflow
Solution 11 - JqueryBronekView Answer on Stackoverflow
Solution 12 - JqueryDan PhilipView Answer on Stackoverflow