Насколько дорог этот триггер jQuery? - PullRequest
1 голос
/ 13 апреля 2011

Этот jsFiddle демонстрирует, о чем я говорю.По сути, я привязываю некоторые элементы к пользовательскому событию, а затем вызываю триггер, используя

$('*').trigger('myevent', args)

Я делаю это, потому что некоторые элементы будут связаны с этим событием, но я не знаю, чтоони будут еще, и я хотел бы максимально разделить этот код.Смехотворно дорого вызывать $('*').trigger или не так дорого, поскольку он будет запускать только элементы, связанные с этим событием?

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

Ответы [ 3 ]

6 голосов
/ 13 апреля 2011

Лучшее решение состоит в том, чтобы связывать и инициировать события вне документа, поскольку это будет только один элемент DOM:

$(document).bind('myevent', function(e) {});

$(document).trigger('myevent');

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

$(document).delegate('.my-delegation-selector', 'myevent', function(e) {

});

Взгляните на этот пример из http://api.jquery.com/delegate/

<!DOCTYPE html>
<html>
<head>
  <style>
  p { color:red; }
  span { color:blue; }
  </style>
  <script src="http://code.jquery.com/jquery-1.5.js"></script>
</head>
<body>
  <p>Has an attached custom event.</p>
  <button>Trigger custom event</button>
  <span style="display:none;"></span>
<script>

    $("body").delegate("p", "myCustomEvent", function(e, myName, myValue){
      $(this).text("Hi there!");
      $("span").stop().css("opacity", 1)
               .text("myName = " + myName)
               .fadeIn(30).fadeOut(1000);
    });
    $("button").click(function () {
      $("p").trigger("myCustomEvent");
    });

</script>

</body>
</html>
2 голосов
/ 13 апреля 2011

Ты думал о pubsub?Что-то такое простое, как.

(function() {
    var $obj = $(window);

    window.pub = function(ev, data) {
        $obj.trigger(ev, data);
    };

    window.sub = function(ev, f) {
        $obj.bind(ev, f);
    };
})();

или отбросить зависимость jQuery

(function() {
    var $obj = {},
        undefined;

    window.pub = function(ev, data) {
        if ($obj[ev] === undefined) {
            return false;
        }
        for (var i = 0, len = $obj[ev].length; i < len; i++) {
            $obj[ev][i](data);
        }
    };

    window.sub = function(ev, f) {
        if ($obj[ev] === undefined) {
            $obj[ev] = [];
        }
        $obj[ev].push(f);
    };
})();

Оба ampify.subscribe и Backbone.Events имеют определенныеобъекты для этого.Вы можете даже найти другие библиотеки с подобными объектами.Для этого есть даже библиотеки PubSub.js .

Пример:

$("table.sort th").click(function(e) {
    ...
    window.pub("click.sortHeader", e); 
});

...

$.fn.pagify = function(json) {
    var table = $(this);
    ...
    //enter code here

    window.sub("click.sortHeader", function() {
         // handle table sorting.

         // adjust table pagifying plugin accordingly.
    });
};

В общем pub это trigger, а sub это bind,В этом конкретном примере у нас есть два независимых плагина.Они не знают, находятся ли они на той же странице или вообще разговаривают.Но так как сортировка «ломает» пейджинговый плагин на нашей таблице, у нас есть подписка на «сортировку» события, чтобы исправить нашу подкачку страниц.

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

0 голосов
/ 13 апреля 2011

Глядя на исходный код JQuery.Когда вы запускаете событие в jQuery, он проверяет действительный узел

    // don't do events on text and comment nodes
    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
        return undefined;
    }

, а затем проверяет действительный обработчик для фактического объекта dom

    // Trigger the event, it is assumed that "handle" is a function
    var handle = jQuery._data( elem, "handle" );

    if ( handle ) {
        handle.apply( elem, data );
    }

Я думаю, что настоящая проблемаиспользование селектора $ ('*').Попробуйте другое из предложенных решений вашей проблемы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...