【问题标题】:How to make a Jquery event on the change of an object?如何对对象的更改进行 Jquery 事件?
【发布时间】:2012-06-29 01:06:47
【问题描述】:

我确信这个问题有一些非常简单的解决方案,至少看起来应该有。但是一直没找到……

我有一个对象(它不是 DOM 的一部分),它的属性会定期更新:

var myobject;
//wait 10 seconds
myobject.property1 = "abc";

我想在这个属性发生变化时触发一个动作(不仅仅是 1,而是许多不同的属性)。我该如何在 JQuery 中执行此操作?

【问题讨论】:

标签: javascript jquery


【解决方案1】:

您可以触发自定义事件。

function changeProperty(obj, prop, value) {
  if (prop in obj && obj[prop] !== value) {
     obj[prop] = value;
     // trigger on document is just an example.
     $(document).trigger('PropertyChange', [obj, prop]);
  }
}


var myobject;
// use the function to change property.
changeProperty(myobject, 'property1', 'abc');

// bind this custom event
$(document).on('PropertyChange', function(obj, prop) {
  console.log(obj, prop);
});

【讨论】:

    【解决方案2】:

    我可以说一个解决方案。在很大程度上,这是一个非常容易解决的问题,无需 DOM 事件,使用 setTimeout() 对我的元素进行递归检查。这个解决方案的问题在于,每秒检查我选择的元素的属性是非常臃肿和不断的 DOM 遍历。因此,鉴于此解决方案的缺陷,我们可以使用一个鲜为人知的 DOM 事件,称为 DOMAttrModified(您可以在此处阅读有关此事件和所有其他标准 DOM 事件的更多信息:http://www.w3.org/TR/DOM-Level-2-Events/events.html

    最佳解决方案

    这个事件很可能不常用,因为它还没有被所有浏览器支持。也就是说,IE 确实支持称为“propertychange”的类似事件,至少,如果我们正在处理所有其他不支持任何内容的浏览器(我我在看着你 Chrome/Safari)。您可以在此处查看浏览器列表和事件兼容性:http://www.quirksmode.org/dom/events/index.html

    由于 jQuery 是当今开发人员事实上的首选 Javascript 库,我为它创建了一个插件,它在所有浏览器中模仿 DOMAttrModified 事件。

    代码

    $.fn.watch = function(props, callback, timeout){
        if(!timeout)
            timeout = 10;
        return this.each(function(){
            var el      = $(this),
                func    = function(){ __check.call(this, el) },
                data    = { props:  props.split(","),
                            func:   callback,
                            vals:   [] };
            $.each(data.props, function(i) { data.vals[i] = el.css(data.props[i]); });
            el.data(data);
            if (typeof (this.onpropertychange) == "object"){
                el.bind("propertychange", callback);
            } else if ($.browser.mozilla){
                el.bind("DOMAttrModified", callback);
            } else {
                setInterval(func, timeout);
            }
        });
        function __check(el) {
            var data    = el.data(),
                changed = false,
                temp    = "";
            for(var i=0;i < data.props.length; i++) {
                temp = el.css(data.props[i]);
                if(data.vals[i] != temp){
                    data.vals[i] = temp;
                    changed = true;
                    break;
                }
            }
            if(changed && data.func) {
                data.func.call(el, data);
            }
        }
    }
    

    初始化代码

    jQuery(function($){
        $(".demo span").watch('width,height', function(){
            if(parseFloat($(this).width()) >= 150){
                $(this).css({'background':'green'});
            }
            if(parseFloat($(this).height()) >= 200){
                $(this).css({'background':'blue'});
            }
        });
        $('.demo a').toggle(function(){
            $('.demo span').animate({'width':'400px','height':'200px'}, 1000);
        }, function(){
            $('.demo span').css({'width':'50px','height':'50px','background':'red'});
        });
    });
    

    现场演示

    此插件可让您指定要“监视”哪些属性以进行更改。当其中一个属性发生更改时,它将触发您的回调函数。 http://darcyclarke.me/dev/watch/

    【讨论】:

      【解决方案3】:
      setInterval(function() {
        // Do something every 2 seconds
        $('#myObject').attr('anyAttribute',value);
      }, 2000);
      

      【讨论】:

        【解决方案4】:

        试试这个@Ryan

        希望这会有所帮助。

        示例代码

        $("#myObject").bind("input propertychange", function (evt) {
            // If it's the propertychange event, make sure it's the value that changed.
            if (window.event && event.type == "propertychange" && event.propertyName != "value")
                //do whatever
        
            // or if you want to use .prop api to get the attribute
                // Do your thing here
            }, 2000)); <---- delay here 2 seconds
        });
        

        【讨论】:

          【解决方案5】:

          使用setInterval 并对照先前检查的值数组检查属性值。如果他们改变了,请致电function ...

          var previousVals = [],
              checkinterval = setInterval(function(){
                  for(var i in myobject) {
                      if(/* comparison logic true */) valchanged(myobject[i]);
                  }
              }, 4000); /* check every 4 seconds */
          
          
          function valchanged(value) { /* ... do something */ }
          

          【讨论】:

            猜你喜欢
            • 2012-07-17
            • 1970-01-01
            • 1970-01-01
            • 2013-09-23
            • 1970-01-01
            • 2017-10-07
            • 2016-09-02
            • 2018-06-23
            相关资源
            最近更新 更多