【问题标题】:Observe DOMNode property观察 DOMNode 属性
【发布时间】:2013-06-05 12:12:45
【问题描述】:

我需要一种方法来识别对象(DOMNode 类型)的属性发生了变化(或者被创建或删除,可选)。

我有一个 INPUT 元素,必须在属性 .value 被修改时得到通知。问题是没有有一个 attr 定义,我可以使用 MutationObserver,是的,一个属性定义 (input.value),它不会触发观察者。

我可以使用可用的最新功能,因为我不会使用 IE (bwhahahah)。

编辑#1

我让this test 显示:

  1. 手动触发有效,但我无法使用/预期此功能;
  2. 自动触发器不起作用,我喜欢这样;
  3. __defineSetter__ 工作得很好,除了我不能在不停止“默认传播”的情况下使用它。

如果有什么办法可以让__defineSetter__一直持续到最后,那就解决这个案子了。

【问题讨论】:

  • 说真的,请检查this answer。恐怕你正在寻找不可能的东西——至少目前是这样。 )
  • 你是认真的吗?如果您想弄清楚输入的值何时发生更改,您可以将事件处理程序绑定到可能更改它的事件!
  • 不知何故,我认为 OP 知道这些。问题是,如何以更统一的方式做到这一点。
  • 请看我的编辑

标签: javascript dom-node


【解决方案1】:

您并没有真正说明您是在尝试跟踪用户对输入元素的更改还是程序更改。对于新的浏览器,您可以监视input 事件,它会告诉您输入字段的值何时被用户控件更改。没有跨浏览器的方式来判断字段的值是否已以编程方式更改,除了挂钩所有可能更改它的代码以添加您自己的通知系统以通知可能已应用更改。

我不久前编写了这个跨浏览器函数来监控所有不同形式的用户对所有浏览器输入字段的更改。这段代码恰好是 jQuery 方法的形式,但是可以很容易地将逻辑修改为纯 javascript。此代码检查是否支持新事件。如果是这样,它会使用它们。如果没有,它会挂钩许多其他事件,以尝试捕获用户更改字段的所有可能方式(拖放、复制/粘贴、键入等)。

(function($) {

    var isIE = false;
    // conditional compilation which tells us if this is IE
    /*@cc_on
    isIE = true;
    @*/

    // Events to monitor if 'input' event is not supported
    // The boolean value is whether we have to 
    // re-check after the event with a setTimeout()
    var events = [
        "keyup", false,
        "blur", false,
        "focus", false,
        "drop", true,
        "change", false,
        "input", false,
        "textInput", false,
        "paste", true,
        "cut", true,
        "copy", true,
        "contextmenu", true
    ];
    // Test if the input event is supported
    // It's too buggy in IE so we never rely on it in IE
    if (!isIE) {
        var el = document.createElement("input");
        var gotInput = ("oninput" in el);
        if  (!gotInput) {
            el.setAttribute("oninput", 'return;');
            gotInput = typeof el["oninput"] == 'function';
        }
        el = null;
        // if 'input' event is supported, then use a smaller
        // set of events
        if (gotInput) {
            events = [
                "input", false,
                "textInput", false
            ];
        }
    }

    $.fn.userChange = function(fn, data) {
        function checkNotify(e, delay) {
            var self = this;
            var this$ = $(this);

            if (this.value !== this$.data("priorValue")) {
                this$.data("priorValue", this.value);
                fn.call(this, e, data);
            } else if (delay) {
                // The actual data change happens aftersome events
                // so we queue a check for after
                // We need a copy of e for setTimeout() because the real e
                // may be overwritten before the setTimeout() fires
                var eCopy = $.extend({}, e);
                setTimeout(function() {checkNotify.call(self, eCopy, false)}, 1);
            }
        }

        // hook up event handlers for each item in this jQuery object
        // and remember initial value
        this.each(function() {
            var this$ = $(this).data("priorValue", this.value);
            for (var i = 0; i < events.length; i+=2) {
                (function(i) {
                    this$.on(events[i], function(e) {
                        checkNotify.call(this, e, events[i+1]);
                    });
                })(i);
            }
        });
    }
})(jQuery);    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 2012-04-20
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2011-05-27
    相关资源
    最近更新 更多