Могу ли я уменьшить свой код jQuery из многих инструкций .on?

#jquery

#jquery

Вопрос:

В настоящее время я создаю веб-приложение, и в основном я создаю его, используя множество ajax-запросов, которые требуют от меня использования .on() селектора из jQuery для динамического использования элементов. Однако я заметил, что мой скрипт становится ужасно длинным, и это почти тот же код, но разные функции для выполнения.

Например, код продолжается следующим образом:

$(функция() {

 $(document).on('click', '.el01', function() {
 executeFunctionA($(this).data('x'));
 });

 $(document).on('click', '.el02', function() { 
 showDivFunction();
 executeFunctionB(true);
 });

 $(document).on('click', '.el03', function() {
 executeFunctionC($(this).data('x'), 300, false, функция() { 
 Возвращает methomethingfromfunctiond();
 });
 });

 ............. Продолжается еще 600 строк

});

Мне было интересно, есть ли способ сократить все эти $(document).on() инструкции? С моей стороны было бы глупо продолжать в том же духе, если бы существовал более простой способ уменьшить объем кода. Может быть, что-то вроде создания $(document).on('click') селектора, который я могу вызывать с помощью __c('el', f() {}) или что-то в этом роде?

Комментарии:

1. предоставьте код для всех связанных функций. я выведу вас на свет.

2. В основном это происходит, как описано выше.. У меня есть 200 .on('click') событий, каждое с другим элементом DOM в качестве триггера. Затем также есть несколько событий .on('mouseenter') и .on('submit') , но в основном этот вопрос был скорее вопросом, можно ли каким-то образом повысить производительность, уменьшив объем реплицируемого кода, как показано выше.

3. вы можете объединить все эти функции, включая событие click, в одно событие, которое выполняет разные действия в зависимости от класса элемента clicked. следовательно, почему я попросил больше кода. смириться или заткнуться.

Ответ №1:

Короткий ответ: нет, вы не можете. [на самом деле вы можете, но не должны]

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

Максимум, что вы можете сделать, это уменьшить объем ввода, который вы выполняете, используя «карту», например:

 var myEventHandlers = {
    '.el01': function() {
         executeFunctionA($(this).data('x'));
    },
    '.el02': function() {
        showDivFunction();
        executeFunctionB(true);
    },
    '.el03': function() {
        executeFunctionC($(this).data('x'), 300, false, function() {
            returnSomethingFromFunctionD();
        });
    }
};
  

А затем добавить единый обработчик событий, который делегирует объекту «отображение»:

 $(document).on('click', Object.keys(myEventHandlers).join(","), function(e) {
    var classList = $(this).attr('class').split(" ");
    for(var i in classList) {
        myEventHandlers["."   i] amp;amp; $.proxy(myEventHandlers["."   i], this, e);
    }
});
  

( for Цикл может быть устранен с помощью дополнительного атрибута html, например, data-event-handler если у вас есть такая возможность; или если вы гарантированно будете иметь только один класс на элемент)


Этот рефакторинг сэкономит вам по одной строке на обработчик событий (что было бы неплохо, если у вас 600 обработчиков событий), но это не особенно читаемо, поэтому, если вы все-таки выберете что-то в этом роде, обязательно вставьте комментарий, объясняющий, почему


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

 function __c(selector, handler) {
    $(document).on('click', selector, handler);
}
__c('.el01', function(event) { /*...*/ });
  

Однако это подвержено ошибкам и очень сложно для чтения. Вы не должны делать это только для того, чтобы сэкономить пару нажатий клавиш — поскольку это больше ничего вам не даст. Описанный выше подход, по крайней мере, позволяет легко увидеть, какой обработчик работает с каким классом — этот способ этого не сделал бы.

Комментарии:

1. Большое спасибо .. 🙂 Так что, я думаю, в конце концов, нет смысла это делать.. Код просто показался немного неэффективным, но я думаю, что мне следует придерживаться того способа, которым я делаю это сейчас..

Ответ №2:

Можно минимизировать вашу функцию on click. Но так или иначе вы должны написать свои подфункции внутри каждой обертки if.

 function ClkElmt(element) {
this.el = $(element);
this.check = function(){

  if (this.el.hasClass('el01')) {
      executeFunctionA($(this).data('x'));   
      console.log('el01'); 
  }

  if (this.el.hasClass('el02')) {
      showDivFunction();
      executeFunctionB(true);
      console.log('el02'); 
  }

  if (this.el.hasClass('el03')){       
      executeFunctionC($(this).data('x'), 300, false, function() {
      returnSomethingFromFunctionD();
      console.log('el03');
  }


 };
}


(function(){
   $('.el01, .el02, .el03, ....').on('click', function(){
   elemts = new ClkElmt(this);
   elemts.check();
  });
})();