Организация кода делегирования событий JavaScript - PullRequest
6 голосов
/ 09 апреля 2011

Я привязываю событие одного клика к большому контейнеру, используя jquery (делегирование события).

У меня есть много различных элементов в этом контейнере, которые можно нажимать.

Проблема, с которой я сталкиваюсьс тем, что если у меня есть 20 элементов с возможностью нажатия, мне нужно сделать блок if else x 20 в контейнере для обработчика щелчков.Есть ли способ сделать это чище?Например:

attachClickEvent:function(){
    $(".container").click($.proxy(this.handleOnClick,this));
},
handleOnClick:function(event){
     var $target = $(event.target);
     if($target.closest(".widget1").length >0){
         //handle widget 1 interaction
     }else if($target.closest(".widget2").length >0){
         //handle widget 2 interaction
     }else if($target.closest(".widget3").length >0){
         //handle widget 3 interaction
     }else if($target.closest(".widget4").length >0){
         //handle widget 4 interaction
     }else if($target.closest(".widget5").length >0){
         //handle widget 5 interaction
     }
}

и т. Д.

Ответы [ 6 ]

2 голосов
/ 09 апреля 2011

Создание объекта с функциями

Немного опоздал с игрой, но вам стоит подумать об организации своего кода следующим образом.

Если у вас есть 20 уникальных действий для ваших виджетов, вы переходите ко всему этому коду. Попробуйте повторно использовать общий код, создав функции. Создайте такую ​​структуру:

var actions = {
    'widget1' : function(event) {
        // handle widget 1 interaction
    },
    'widget2' : function(event) {
        // handle widget 2 interaction
    },
    'widget3' : function(event) {
        // handle widget 3 interaction
    },
    call : function(event) {
        var prefix = "widget",
            widget = $(event.target).closest('[class^="'+prefix+'"]'),
            classN;
        if(widget.length) {
            classN = widget.attr('class').replace(new RegExp('.*('+prefix+'\\d*).*$'), '$1');
            if(classN in this) {
                this[classN](event);
            }
        }
    }
};

Упрощенное выполнение

Затем из обработчика кликов просто вызовите функцию следующим образом:

handleOnClick : function(event) {
    actions.call(event)
}
2 голосов
/ 09 апреля 2011

Первое, что приходит на ум, это использование цикла:

var handlers = {
  "widget1": function(event, candidate){},
  "widget2": function(event, candidate){}
}

$.each(handlers, function(cssClass,handler){
  var sel = '.'+cssClass;
  var candidate = target.closest(sel);
  if(candidate.length > 0) {
    handler(event, candidate);
    break;
  }
});
1 голос
/ 30 ноября 2012

jQuery предлагает эту функциональность из коробки:

$('.container').on('click', '.widget1', function() {
    // handle widget 1 interaction
});

$('.container').on('click', '.widget2', function() {
    // handle widget 2 interaction
});

Я недавно написал библиотеку, чтобы извлечь ее, если вы не используете jQuery. Это называется Gator. Вы можете увидеть примеры / документацию по адресу: http://craig.is/riding/gators

Вы можете сделать что-то вроде

Gator(container_element).on('click', '.widget1', function() {
    // handle widget 1 interaction
});

Gator(container_element).on('click', '.widget2', function() {
    // handle widget 2 interaction
});

И jQuery, и Gator привязывают только одно событие щелчка к элементу контейнера и обрабатывают события внутри.

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

Как насчет использования delegate?

$(".container").
    delegate(".widget1", "click", widget_1_handler).
    delegate(".widget2", "click", widget_2_handler)
;
0 голосов
/ 09 апреля 2011

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

<div id="widgetcontainer">
    <div id="widget1">A</div>
    <div id="widget2">B</div>
    <div id="widget3">C</div>
    <div id="widget4">D</div>
    <div id="widget5">E</div>  
</div>

Вот JS

function someAction() {
    alert("Hey");
}


$(function() {
    var wc = $("#widgetcontainer div");
    for (var i = 0; i < wc.length; i++) {
        $(wc[i]).click(function() {
            someAction();
        });
    }
});
0 голосов
/ 09 апреля 2011

HTML

<div class="container">
 <div id="cont1"></div>
 <div id="cont2"></div>
 <div id="cont3"></div>
 <div id="cont4"></div>
 <div id="cont5"></div>
 <div id="cont6"></div>
.
.
.

</div>

JQuery

$(".container").find("div").click(function(){
id = $(this).attr("id");
if(id=="cont1"){
...
}
else if(id=="cont2"){
..
}
..
else{
..
}
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...