Подтвердить что ты не робот

Как бы вы отвязали все события jQuery из определенного пространства имен?

Есть ли в jQuery "глобальная" функция unbind, так что я смогу удалить все связанные события из определенного пространства имен? например:

// assume these are the events bound to different elements
$('#foo').bind('click.myNS', ...);
$('#bar').bind('keyup.myNS', ...);
$('#baz').bind('dblclick.myNS', ...);    

// magic occurs here...
$.magicalGlobalUnbindFunction('.myNS');

// ...and afterwards, the three binds from above are gone

Все примеры, которые я видел для unbind, требуют, чтобы некоторые элементы были выбраны первыми. Я думаю, что технически вы могли бы сделать $('*').unbind('.myNS'), но это кажется очень неэффективным.

4b9b3361

Ответ 1

Вы можете добавить myNS как класс к каждому из элементов, в которых вы хотите развязать события.

Ответ 2

Вы всегда можете переносить $.fn.bind, а затем кэшировать необходимые ссылки:

(function ($) {
    var origBind = $.fn.bind,
        boundHash = {};

    $.fn.bind = function (type, data, fn) {
        var namespace = '',
            events = [];

        if (typeof type === 'string') {
            // @todo check the allowed chars for event namespaces.
            namespace = type.replace(/^[^.]+/, '');

            if (namespace.length) {
                events = boundHash[namespace];

                // Namespaces can hold any number of events.
                events = boundHash[namespace] = $.isArray(events) ? events : [];

                // Only really need ref to the html element(s)    
                events.push({
                    type: type, 
                    fn: $.isFunction(fn) ? fn : data, 
                    that: this.length > 1 ? this.toArray() : this[0]
                });
            }
        }

        origBind.apply(this, arguments);
    };

    // namespace to be muffled. Feel free to qualify a specific event type.
    $.muffle = function (namespace, type) {
        var events = [];

        if (boundHash.hasOwnProperty(namespace)) {
            events = boundHash[namespace];

            $.map(events, function (event) {
                var _type = type || event.type;

                if (event.type.indexOf(_type) === 0) {
                    $(event.that).unbind(_type, event.fn);
                }
            });

            // @todo think of better return value.
            return true;
        }

        // @todo think of better return value.
        return false
    };
})(jQuery);

Ответ 3

Воистину, вы ищете магическую глобальную функцию, но, как всегда, с магией, вы можете получить иллюзию в этом случае простоты.

Существует также решение jQuery, использующее . live() или .() (это только вариант live()).

Используя $("body").delegate("#foo", "click.myNs", func), вы также связываете событие и используя $("#body").undelegate(".myNs"), вы отвязываете его. Я использую здесь элемент body, но, конечно, вы можете использовать любой элемент, который является предком всех элементов, на которые нужно привязать.

Это сделает вашу "развязывающую" работу быстрее, но снова это заставит ваши события реагировать медленнее.

Ответ 4

Вам нужно использовать jQuery On и Off. Используйте документ как селектор.

$(document).off('.myNS');

$(document).on('click.myNS','#foo', ...);
$(document).on('keyup.myNS','#bar', ...);
$(document).on('dblclick.myNS','#baz',''');

тогда ваши методы могут выглядеть как

$(document).on('click.myNS','#foo', fooClicked);
var fooClicked = function(e){
    var $this = $(e.target);
    // do stuff
}

Ответ 5

Вам нужно взломать внутренние элементы jQuery, здесь приведена рабочая демонстрация простой реализации:

http://jsfiddle.net/nkMQv/1/

Основная работа выполняется в обычных циклах js и не должна быть очень неэффективной, так как даже эта страница содержит в конечном счете всего 106 элементов для прокрутки. Конечно, вы должны как можно больше использовать делегирование событий, чтобы количество элементов в коллекции обработчиков jQuery было как можно меньше.

Ответ 6

Вы должны добавить класс в функцию bind

$('#foo').bind('click.myNS', ...).addClass('removeLater');
$('#bar').bind('keyup.myNS', ...).addClass('removeLater');
$('#baz').bind('dblclick.myNS', ...).addClass('removeLater');  

а затем

$('.removeLater').unbind();

Если #foo #bar и #etc - это все те же самые элементы или их небольшие группы, вы также можете:

$('div, button').unbind();

но если у вас есть связанное событие, которое вы не хотите удалять, это не будет хорошей идеей

Ответ 7

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

var eventArray=[];
(function ($) {
    var bind = $.fn.bind;
    $.fn.bind= function () {
    var result = bind.apply(this, arguments);
    var selector=arguments[0];
    var nameSpace= selector.split(".")[1];   //code to select the nameSpace eg. click.myNS o/p->myNS (update this if your selector has multiple '.')
    if(!eventArray[nameSpace])    //if the associative array does not contain the namespace yet
    {
       eventArray[nameSpace]=[];
    }
    eventArray[nameSpace].push(selector);
    return result;
};
})(jQuery);

Теперь с помощью eventArray вы можете отменить привязку по своему усмотрению. Код для развязывания всех событий в пространстве имен myNS будет выглядеть следующим образом:

$.each(eventArray['myNS'],function(){
   $(this).unbind();
});

Надеюсь, это хорошее решение. сообщите мне, допустили ли я какие-либо ошибки.