jQuery watch div
Is there any way to watch, if the content within a div changes?
Let's say I have:
<div id="hello"><p>Some content here</p></div>
Which at some point 5 seconds later changes to:
<div id="hello"><ul><li>This is totally different!</li></ul></div>
How can I be 开发者_高级运维notified of this via a callback or something else? I can in most cases get the javascript that's doing the inserting, to tell me. But I wanted to know if it was possible.
The jQuery .change() method works only for form fields.
I wrote a little jQuery plugin for you:
<!-- jQuery is required -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<!-- this is the plugin -->
<script>
jQuery.fn.contentChange = function(callback){
var elms = jQuery(this);
elms.each(
function(i){
var elm = jQuery(this);
elm.data("lastContents", elm.html());
window.watchContentChange = window.watchContentChange ? window.watchContentChange : [];
window.watchContentChange.push({"element": elm, "callback": callback});
}
)
return elms;
}
setInterval(function(){
if(window.watchContentChange){
for( i in window.watchContentChange){
if(window.watchContentChange[i].element.data("lastContents") != window.watchContentChange[i].element.html()){
window.watchContentChange[i].callback.apply(window.watchContentChange[i].element);
window.watchContentChange[i].element.data("lastContents", window.watchContentChange[i].element.html())
};
}
}
},500);
</script>
<!-- some divs to test it with -->
<p>Testing it: (click on divs to change contents)</p>
<div id="a" onclick="$(this).append('i')">Hi</div>
<div id="b" onclick="$(this).append('o')">Ho</div>
<div class="c" onclick="$(this).append('y')">He</div>
<div class="c" onclick="$(this).append('w')">He</div>
<div class="c" onclick="$(this).append('a')">He</div>
<!-- this is how to actually use it -->
<script>
function showChange(){
var element = $(this);
alert("it was '"+element.data("lastContents")+"' and now its '"+element.html()+"'");
}
$('#a').contentChange(function(){ alert("Hi!") });
$('div#b').contentChange( showChange );
$('.c').contentChange(function(){ alert("He he he...") });
</script>
Be aware that this watches changes in the contents of the element (html) only, not the attributes.
There is no native jQuery/DOM event that will fire when HTML/DOM content changes.
You could (if you are feeling particularly wasteful) do something like this:
$(function() {
var $div = $("#hello");
var html = $div.html();
var checking = setInterval(function() {
var newhtml = $div.html();
if (html != newhtml) {
myCallback();
html = newhtml;
}
},100);
function myCallback() {
alert('content changed!');
// if you only want it to fire once, uncomment the following:
// clearInterval(checking);
}
});
Just remember, calling .html()
every 100ms is probably not the best idea for your sites performance.
jsFiddle mockup
Maybe, it's reasonable to monitor the source of events that amend the contents of your layer(s)? Say, a user has clicked anywhere (read, "did a click") after what the contents may had changed. So if you check the .html() after a click rather than using a loop - it might save some system resources.
Who/what will change this? If it's some JS you control, use that to also trigger your callback. Obviously a user cannot change this.
If you want to watch a <input>
element etc, use the 'change' event. jQuery version here: http://api.jquery.com/change/
Here's a code sample that calls a simple alert when the given value changes:
<!DOCTYPE html>
<html lang="en">
<head>
<title>watchu, watchu, watchu want, watchu want?</title>
</head>
<body>
<div id='foo'>Hello World!</div>
<p><input type="button" id="ChangeButton" value="Change It" /></p>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(function () {
$('#ChangeButton').click(function () {
$('#foo').html('Awfveeterzain!');
});
window.watchForChangeOriginalValue = $('#foo').html();
watchForChange();
});
function watchForChange() {
if ($('#foo').html() != window.watchForChangeOriginalValue)
alert('the value changed!');
else
window.setTimeout(watchForChange, 500);
}
</script>
</body>
</html>
There are some events called DOMNodeInserted
, DOMNodeRemoved
and DOMSubtreeModified
. Which check is there any elements are added or removed or any inner Html changed inside a div. for this you need an setInterval()
function.
function DivChange() {
$('#YourDiv').bind('DOMNodeInserted DOMNodeRemoved', function (event) {
if (event.type == 'DOMNodeInserted') {
alert('Content added');
} else if (event.type == 'DOMNodeRemoved') {
alert('Content removed');
} else {
alert('Inner Html changed for some content');
}
});
}
var DivTimer = setInterval(DivChange, 1000);
The above functions will checks the Div for any content change, for every second
Note: This events are not supported by IE
精彩评论