2013-06-09 2 views
1

Мне нужен способ идентифицировать свойство объекта (типа DOMNode), претерпел изменение (или был создан или удален, необязательно).Соблюдать свойство DOMNode

У меня есть элемент INPUT и должен быть уведомлен о новых изменениях свойства .value. Проблема в том, что не есть определение attr, которое я мог бы использовать MutationObserver, и да, определение свойства (input.value), и это не вызывает наблюдателя.

Я могу использовать новейшие функции, так как я не буду использовать IE (bwhahahah).

Редактировать # 1

Я делаю this test, чтобы показать:

  1. Ручной запуск работает, но я не могу использовать/ожидать, что это;
  2. Автоматический триггер не работает, и мне это нравится;
  3. __defineSetter__ работает очень хорошо, за исключением того, что я не могу использовать его, не останавливая «распространение по умолчанию».

Если есть способ допустить, чтобы __defineSetter__ продолжал до конца, разрешил бы случай.

+1

Серьезно, однако, проверьте [этот ответ] (http://stackoverflow.com/a/14958209/1229023). Боюсь, вы ищете то, что невозможно - по крайней мере, в настоящее время.) – raina77ow

+0

Вы серьезно? Если вы пытаетесь выяснить, когда изменяется значение ввода, вы привязываете обработчик событий к событиям, которые могут его изменить! – adeneo

+0

Как-то я думаю, что ОП знает об этом. Вопрос в том, как сделать это более единообразным образом. – raina77ow

ответ

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);  
Смежные вопросы