Переопределить основные функции jQuery на уровне элемента - PullRequest
11 голосов
/ 23 апреля 2011

Можно ли переопределить основные функции jQuery на уровне элемента, поэтому, например, я хочу переопределить val () функцию только для одного элемента.

если я сделаю что-то подобное

var element = $('select');
var old_val = element.val;
element.val = function () {
  console.log('The new val');
  return old_val.apply(this, arguments);
}
element.val(19);

работает как положено, но как только я обращаюсь к тому же полю с новым экземпляром jQuery

var element = $('select');
element.val(19);

он перестает работать, потому что у нас есть новый экземпляр объекта jQuery. если я возлюсь с функцией $. fn.val , я изменю это поведение для всех объектов, которые поддерживают функцию val, что для меня немного.

Любая помощь будет оценена. Спасибо.

Ответы [ 5 ]

4 голосов
/ 13 ноября 2012

Я сделал это расширение jquery для того, о чем вы говорите:

// overrides a method thats supposed to be called on a single node (a method like val)
$.fn.overrideNodeMethod = function(methodName, action) {
    var originalVal = $.fn[methodName];
    var thisNode = this;
    $.fn[methodName] = function() {
        if (this[0]==thisNode[0]) {
            return action.apply(this, arguments);
        } else {
            return originalVal.apply(this, arguments);
        }
    };
};

Бонус за ответ Дейва - вам не нужно загрязнять пространство имен данных jquery или беспокоиться о том, что кто-то перезаписывает этот ключ

4 голосов
/ 23 апреля 2011

Основано на ответе sdleihssirhc, но изменено, чтобы применяться только к ранее согласованным элементам, поскольку вы сказали «только на один

element.data('custom_val', function() {
    console.log('The new val');
});

$.fn.old_val = $.fn.val;
$.fn.val = function () {
    var custom_val = this.data('custom_val');
    if (custom_val) {
         return custom_val.apply(this, arguments);
    } else {
         return this.old_val.apply(this, arguments);
    }
};
3 голосов
/ 09 февраля 2017

Этот небольшой фрагмент позволяет переопределить методы jQuery.

Я считаю ответ @BT довольно плохим, поскольку он создает дополнительный обратный вызов при каждом использовании функции.Поэтому, если вы примените его к 1000 элементам, 1000 функций для КАЖДОГО val() будут называться!

Мой overrideNodeMethod может быть применен к любому количеству элементов столько раз, сколько вы хотите.Это в основном проверяет hasOverriddenMethod данные

var originaljQueryMethods = {};
for(var method in $.fn){        
    originaljQueryMethods[method] = $.fn[method];
};

$.fn.callOriginalMethod = function(method, args) {        
    return originaljQueryMethods[method].apply(this, args);
};        

$.fn.overrideNodeMethod = function(method, callback) {                
    var dataKey = "hasOverriddenMethod." + method;
    $(this).callOriginalMethod("data", [dataKey, callback]);
    $.fn[method] = function() {
        var callback = $(this).callOriginalMethod("data", [dataKey])
        if (callback) {
            return callback.apply(this, arguments);                
        }
        return $(this).callOriginalMethod(method, arguments);            
    };
};
1 голос
/ 23 апреля 2011

Да, это отличный вопрос. Я бы никогда не попробовал это.

Пошли:

Прежде чем мы начнем, мы должны скопировать стандартную val-функцию в другое место:

jQuery.fn.oldval = jQuery.fn.val;

Я бы написал глобальную функцию для перехвата функции val ():

jQuery.fn.val = function(value) {
   var t = jQuery(this);
   if(t.get(0)) {
      //Check for overwritten function
      var func = jQuery.data(t.get(0), 'val-function');
      if(jQuery.isFunction(func)) {
         return func(value);
      }
   }
   //Use old function
   return jQuery(this).oldval(value);
};

После этого вы можете установить функцию для ваших Элемент-Данных с помощью:

var element = jQuery(...);
jQuery.data(element.get(0), 'val-function', function(value){
   /* Your Function here */
});

Я не знаю, работает ли это. Попытайся. Это только из моего мозга.

1 голос
/ 23 апреля 2011

Каждый объект jQuery включает в себя свойство selector, которое содержит (дух) оригинальный селектор, который использовался для получения элементов (я даже не работал с ним вообще, поэтому я не уверен, что с ним происходит как вы проходите через цепочку методов).

Таким образом, вы можете заключить метод val в функцию, которая проверяет свойство selector и затем решает, использовать ли вашу функцию или оригинал. Это будет выглядеть примерно так:

$.fn.old_val = $.fn.val;
$.fn.val = function () {
    if (this.selector === 'select') {
        console.log('The new val');
    }
    return this.old_val.apply(this, arguments);
};

У вас, по сути, было это раньше, я просто настраиваю его, чтобы оно распространялось на все новые экземпляры jQuery.

(Кроме того, это довольно упрощенно само по себе; вы захотите соответственно изменить / улучшить его.)

...