【问题标题】:Create a jQuery special event for content changed为内容更改创建一个 jQuery 特殊事件
【发布时间】:2010-11-29 19:08:24
【问题描述】:

我正在尝试创建一个 jQuery 特殊事件,该事件在绑定的内容发生更改时触发。我的方法是使用 setInterval 检查内容并检查内容是否与上次相比发生了变化。如果你有更好的方法,请告诉我。另一个问题是我似乎无法清除间隔。无论如何,我需要的是使用 event.special 检查内容更改的最佳方式。

(function(){

    var interval;

    jQuery.event.special.contentchange = {
        setup: function(data, namespaces) {
            var $this = $(this);
            var $originalContent = $this.text();
            interval = setInterval(function(){
                if($originalContent != $this.text()) {
                    console.log('content changed');
                    $originalContent = $this.text();
                    jQuery.event.special.contentchange.handler();
                }
            },500);
        },
        teardown: function(namespaces){
            clearInterval(interval);
        },
        handler: function(namespaces) {
            jQuery.event.handle.apply(this, arguments)
        }
    };

})();

并像这样绑定它:

$('#container').bind('contentchange', function() {
        console.log('contentchange triggered');
});

我得到了 console.log '内容更改',但没有得到 console.log '内容更改触发'。所以很明显,回调永远不会被触发。

我只是使用 Firebug 来更改内容并触发事件,进行测试。

更新
我认为我说得不够清楚,我的代码实际上不起作用。我正在寻找我做错了什么。


这里是所有感兴趣的人的完成代码

(function(){

    var interval;

    jQuery.event.special.contentchange = {
        setup: function(){
            var self = this,
            $this = $(this),
            $originalContent = $this.text();
            interval = setInterval(function(){
                if($originalContent != $this.text()) {
                    $originalContent = $this.text();
                    jQuery.event.handle.call(self, {type:'contentchange'});
                }
            },100);
        },
        teardown: function(){
            clearInterval(interval);
        }
    };

})();

感谢 Mushex 帮助我。

【问题讨论】:

  • 有什么原因你不使用'var'来声明$this?
  • 您在 real 页面中是否有一致的 'orginalContent' 拼写?
  • 何时调用拆卸?
  • @David Andres - 当我取消绑定事件时。 $('#container').unbind('contentchange');
  • 如果我没记错的话,这个实现只会保留最后一个计时器ID。要修复它,我会做类似 $(this).data("onchange.timer.id",interval) 并在拆卸中检索

标签: javascript jquery events javascript-events intervals


【解决方案1】:

也许你可以试试 Mutation Observer

代码如下:

mainArea = document.querySelector("#main_area");
MutationObserver = window.MutationObserver;
DocumentObserver = new MutationObserver(function() {
       //what you want to run
});

DocumentObserverConfig = {attributes: true, childList: true, characterData: true, subtree: true};

DocumentObserver.observe(mainArea, DocumentObserverConfig);

【讨论】:

    【解决方案2】:

    原始问题中完成的代码对我有用,谢谢!我只想指出,我正在使用 jquery 1.9.1 并且 $.event.handle 似乎已被删除。我更改了以下内容以使其正常工作。

    jQuery.event.handle.call(self, {type:'contentchange'});

    到

    jQuery.event.dispatch.call(self, {type:'contentchange'});

    【讨论】:

      【解决方案3】:


      我知道这个帖子/问题有点老了,但这些天我支持一个类似的解决方案,我发现了这个:

      $('#selector').bind('DOMNodeInserted', function(e) {
          console.log(e.target);
      });
      

      来源:http://naspinski.net/post/Monitoring-a-DOM-Element-for-Modification-with-jQuery.aspx

      希望这对某人有所帮助!

      【讨论】:

      • 几乎不值得投反对票。很多东西都被弃用了,但在所有浏览器都提供更好的解决方案之前,它们仍然会被使用,而且理解起来仍然很有用。 (这里 +1 抵消投票)
      • 整洁!即使它已被弃用,它也比计时器更清洁!
      • 已弃用,是的,但有一个 CSS3 替代品。 stackoverflow.com/a/25256569/1450294 连IE也终于支持了(11版)! caniuse.com/#feat=mutationobserver
      【解决方案4】:

      还可以看看 James similar script(声明为 jquery 对象方法而不是事件)

      jQuery.fn.watch = function( id, fn ) {
      
          return this.each(function(){
      
              var self = this;
      
              var oldVal = self[id];
              $(self).data(
                  'watch_timer',
                  setInterval(function(){
                      if (self[id] !== oldVal) {
                          fn.call(self, id, oldVal, self[id]);
                          oldVal = self[id];
                      }
                  }, 100)
              );
      
          });
      
          return self;
      };
      
      jQuery.fn.unwatch = function( id ) {
      
          return this.each(function(){
              clearInterval( $(this).data('watch_timer') );
          });
      
      };
      

      并创建特殊事件

      jQuery.fn.valuechange = function(fn) {
          return this.bind('valuechange', fn);
      };
      
      jQuery.event.special.valuechange = {
      
          setup: function() {
      
              jQuery(this).watch('value', function(){
                  jQuery.event.handle.call(this, {type:'valuechange'});
              });
      
          },
      
          teardown: function() {
              jQuery(this).unwatch('value');
          }
      
      };
      

      无论如何,如果你只需要它作为事件,你的脚本很好:)

      【讨论】:

      • 我正在寻找的是如何创建一个特殊事件,就像我所做的那样,只有一个真正有效的事件。你能告诉我吗?
      • 我以为你解决了它,只是把这个例子带给你,看看这个问题的一些不同的方法。如果您的脚本实际上还不起作用,请告诉我。
      • 我的脚本不起作用。如果你能帮助我让它工作会很棒:)顺便说一句,谢谢你的另一种方法。
      • 谢谢 :) 很高兴知道我很接近。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多