-2

我有下面的两个选择器。当更多选择器附加到"render"时,"comp1"的位置会下降一点,每次"comp1"的位置发生变化时我都想执行一个函数。

我已经尝试通过绑定到更改事件,但它没有按我想要的那样工作。

<div id="render" >
<div id="comp1" >

这是我尝试过的 JS 部分:

function doUpdate(e){
    console.log("Component is updated "+e);
}
// capture change in the component
$('#comp1).bind('change', doUpdate);
4

1 回答 1

2

change当输入的输入值更改并且输入失去焦点时触发该事件。在这里不会有帮助。

当某个元素相对于任何东西改变其位置时,不会触发任何特殊事件。

有一些事件会导致元素重新定位:

  • 浏览器窗口已调整大小。这个很容易被发现。
  • 加载了一些 CSS 或图像。您可以尝试连接到load所有样式和图像的事件。不完全是轻量级的。
  • 一些内容通过 Javascript 添加到页面中。有各种 DOM 突变事件,但它们的支持各不相同,并且它们也有其他缺点(即它们触发的频率太高)并且它们已被弃用。他们替换突变观察者也没有得到普遍支持,但至少他们没有其他缺点。请注意,这可能包括其他图像和样式,因此您还需要挂钩它们的加载事件。
  • CSS3 过渡和动画。有些事件会在这些事件开始或结束时触发,但不会在中间触发。
  • Javascript 更改了一些样式或 CSS 类。突变事件检测属性更改,但不检测属性更改。至少某些属性更改不会影响相应的属性。仔细查看支撑台。
  • 用户调整文本区域的大小,或将resizableCSS 属性设置为任何其他元素的其他元素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/

但是,说真的,改变你的设计,这样你就不需要这个了!!!

于 2013-07-09T06:51:20.760 回答