change
当输入的输入值更改并且输入失去焦点时触发该事件。在这里不会有帮助。
当某个元素相对于任何东西改变其位置时,不会触发任何特殊事件。
有一些事件会导致元素重新定位:
- 浏览器窗口已调整大小。这个很容易被发现。
- 加载了一些 CSS 或图像。您可以尝试连接到
load
所有样式和图像的事件。不完全是轻量级的。
- 一些内容通过 Javascript 添加到页面中。有各种 DOM 突变事件,但它们的支持各不相同,并且它们也有其他缺点(即它们触发的频率太高)并且它们已被弃用。他们替换突变观察者也没有得到普遍支持,但至少他们没有其他缺点。请注意,这可能包括其他图像和样式,因此您还需要挂钩它们的加载事件。
- CSS3 过渡和动画。有些事件会在这些事件开始或结束时触发,但不会在中间触发。
- Javascript 更改了一些样式或 CSS 类。突变事件检测属性更改,但不检测属性更改。至少某些属性更改不会影响相应的属性。仔细查看支撑台。
- 用户调整文本区域的大小,或将
resizable
CSS 属性设置为任何其他元素的其他元素resizable: none
(大多数元素的默认值)。一种解决方法可能是禁用调整大小。
在不了解确切环境的情况下,几乎不可能做到这一点。
这给我们留下了最后的选择,轮询更改,但它有自己的几个问题:它不会立即获取更改并且即使没有任何更改也使用 CPU(不要用于许多元素!)。
实现为一个 jQuery 插件,它可能看起来像:
(function($){
var watches = $();
var timeout = 100;
var awake = false;
$.fn.watcher = function(option, value){
if(typeof option == 'function'){
value = option;
option = undefined;
}
switch(option){
case 'watch':
case undefined:
watches = watches.add(this);
if(typeof value == 'function'){
this.on("watcher.move", value);
}
if(!awake && this.length > 0){
awake = true;
setTimeout(watcher, timeout);
}
break;
case 'unwatch':
watches = watches.not(this)
break;
case 'timeout':
if(arguments.length == 1){
return timeout;
} else {
timeout = value;
}
default: throw "unknown option "+option;
}
return this;
}
function watcher(){
watches.each(function(){
var $this = $(this);
var oldPos = $this.data("watcher.position");
var newPos = $this.offset(); //relative to the document
if(oldPos && (oldPos.top !== newPos.top || oldPos.left !== newPos.left)){
$this.trigger("watcher.move");
}
$this.data("watcher.position", newPos);
})
if(watches.length){
setTimeout(watcher, timeout);
} else {
awake = false;
}
}
})(jQuery)
示例用法:
$("#comp1")
.watcher('timeout', 50)
.watcher('watch')
.on("watcher.move", function(){
console.log("#comp1 has moved!")
})
要不就:
$("#comp1").watcher(function(){
console.log("#comp1 has moved!")
})
在这里测试:http: //jsfiddle.net/qC99z/
但是,说真的,改变你的设计,这样你就不需要这个了!!!