11

Is it possible to detect if the content of a paragraph has been changed in JQuery ?

I tried the below code.

<p id="test">Text</p>
<button id="submit1">change</button>

-

$(document).on("click", "#submit1", function () {
    var d = new Date();
    var time = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
    $("#test").text(time);
});       
$(document).on("change", "#test", function () {
    alert("Paragraph changed");
});

JSFiddle : http://jsfiddle.net/nnbqye55/

I guess I am missing something obvious.

Soumya
  • 885
  • 3
  • 14
  • 29

7 Answers7

10

change events won't fire on the paragraph. What you need are known as Mutation Observers. Here is the relevant MDN documentation. They have pretty good browser penetration; for older IEs, you can probably use the deprecated Mutation Events, though those are known to be performance killers, so be very careful. I'll rewrite your example using Mutation Observers; you can also check out a jsFiddle demo:

$(function(){
    //Store the test paragraph node
    var test = $('#test');

    //Function to change the paragraph
    var changeParagraph = function () {
        var d = new Date();
        var time = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
        test.text(time);
    };

    //Bind the paragraph changing event
    $('#submit1').on('click', changeParagraph);

    //Observe the paragraph
    this.observer = new MutationObserver( function(mutations) {
        alert('Paragraph changed!')
    }.bind(this));
    this.observer.observe(test.get(0), {characterData: true, childList: true});
});
AlexZ
  • 11,515
  • 3
  • 28
  • 42
  • Do you know why there 2 `MutationRecord` ( mutations ) in the `MutationObserver`? – Mephiztopheles Dec 18 '14 at 07:33
  • Because two mutations occurred. First, the list of child nodes changed(one `text` node was replaced by another). Second, the `data` contained within the observed DOM element changed (watch the value of `test.get(0).data` in your devtools to see what I mean). You could only watch for `childList` changes by doing `this.observer.observe(test.get(0),{childList: true})`, but then if the data of the `text` node itself is changed *without* replacing that node, the observer wouldn't be triggered. Best to watch for both possible mutations, then iterate through them to find the one you want. – AlexZ Dec 18 '14 at 08:00
4

You can use 'DOMSubtreeModified' to check the dom changes on html tag elements. See the support for this event across browsers.

http://jsfiddle.net/nnbqye55/7/

$(document).on("DOMSubtreeModified", "#test", function () {
    alert("Paragraph changed");
});
Monie corleone
  • 1,618
  • 1
  • 16
  • 37
1

You can attach the change() event only to <input>, <select> and <textarea> element and detect their value change. Not on other elements. Check here

kapantzak
  • 11,610
  • 4
  • 39
  • 61
0

On change you have to trigger change event like below

$(document).on("click", "#submit1", function () {
    var d = new Date();
    var time = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
    $("#test").text(time).trigger("change");
});     

$(document).on("change", "#test", function () {
    alert("Paragraph changed");
});

JS Fiddle

Sadikhasan
  • 18,365
  • 21
  • 80
  • 122
  • Maybe I was clear in my query - I wanted to check for changes to the paragraph.. the change may be due to any event elsewhere...Your solution assumes that the change is done via button click only. – Soumya Dec 18 '14 at 08:27
  • My answer is help you? – Sadikhasan Dec 18 '14 at 08:31
0

You can use the code from here http://quiiver.appspot.com/method_observer_for_jquery and use it like

$('#test').bind('text' // the method's name used to change the text
, function(){
    alert("Paragraph changed");
})

DEMO However, it works only for modifications done through jQuery.

Amit Joki
  • 58,320
  • 7
  • 77
  • 95
0

You don't necessarily need JQuery, in modern browsers the web API includes mutation observers. For older browsers there are mutation events.

mutation observer example:

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    alert(mutation.type);
  });    
});

Fiddle with mutation observers: http://jsfiddle.net/nnbqye55/5/

For JQuery/older IE support, see: https://github.com/kapetan/jquery-observe

thebenedict
  • 2,539
  • 3
  • 20
  • 29
0

The approved answer didn't work for me so here is my revised and working example for anyone looking.

function getNode(){
//Store the test paragraph node
var test = $('#test');

if(!test){
  // The node we need may not exist yet
  // Wait 500ms and try again
window.setTimeout(getNode, 500);
return;
}
//Function to change the paragraph
var changeParagraph = function () {
    var d = new Date();
    var time = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
    test.text(time);
};

//Bind the paragraph changing event
$('#submit1').on('click', changeParagraph);

//Observe the paragraph
this.observer = new MutationObserver(changeParagraph);
this.observer.observe(test, {characterData: true, childList: true});
});
//Delay calling our function until page loads
setTimeout(function() {
    getNode();
}, 5000);
Shawn W
  • 566
  • 4
  • 13