javascript всплытие - Что такое делегирование событий DOM?




всплывание js (6)

Делегат в C # похож на указатель на функции в C или C ++. Использование делегата позволяет программисту инкапсулировать ссылку на метод внутри объекта делегата. Затем объект делегата может быть передан в код, который может вызвать ссылочный метод, без необходимости знать во время компиляции, какой метод будет вызываться.

См. Эту ссылку -> http://www.akadia.com/services/dotnet_delegates_and_events.html

Может ли кто-нибудь объяснить делегирование событий в JavaScript и как это полезно?


Delegation - это метод, при котором объект выражает определенное поведение снаружи, но на деле делегирует ответственность за реализацию этого поведения для связанного объекта. Это звучит вначале очень похоже на прокси-шаблон, но он выполняет совершенно другую цель. Делегирование - это механизм абстракции, который централизует поведение объекта (метода).

Обычно говорят: используйте делегирование как альтернативу наследованию. Наследование - хорошая стратегия, когда близкие отношения существуют между родительским и дочерним объектами, однако наследование очень близко переносит объекты. Часто делегация является более гибким способом выражения отношений между классами.

Этот шаблон также известен как «сети прокси». Некоторые другие шаблоны проектирования используют делегирование - от этого зависят состояние, стратегия и шаблоны посетителей.


dom событие отличается от определения компьютерной науки.

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


Концепция делегации

Если внутри одного родителя есть много элементов, и вы хотите обрабатывать события на них, не привязывайте обработчики к каждому элементу. Вместо этого привяжите одиночный обработчик к своему родительскому объекту и получите дочерний элемент из event.target. На этом сайте представлена ​​полезная информация о том, как реализовать делегирование событий. http://javascript.info/tutorial/event-delegation


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

Пример JavaScript:

Предположим, что у нас есть родительский элемент UL с несколькими дочерними элементами:

<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>

Давайте также скажем, что что-то должно произойти, когда щелкнут каждый дочерний элемент. Вы можете добавить отдельный прослушиватель событий для каждого отдельного элемента LI, но что, если элементы LI часто добавляются и удаляются из списка? Добавление и удаление прослушивателей событий было бы кошмаром, особенно если код добавления и удаления находится в разных местах вашего приложения. Лучшее решение - добавить прослушиватель событий в родительский элемент UL. Но если вы добавите прослушиватель событий к родительскому объекту, как вы узнаете, какой элемент был нажат?

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

// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
    // List item found!  Output the ID!
    console.log("List item ", e.target.id.replace("post-"), " was clicked!");
       }
 });

Начните с добавления прослушивателя событий щелчка к родительскому элементу. Когда прослушиватель событий запускается, проверьте элемент события, чтобы убедиться, что это тип элемента, на который реагирует. Если это элемент LI, бум: у нас есть то, что нам нужно! Если это не тот элемент, который мы хотим, событие можно игнорировать. Этот пример довольно прост - UL и LI - прямое сравнение. Давайте попробуем что-нибудь более сложное. Давайте иметь родительский DIV с большим количеством детей, но все, о чем мы заботимся, это тег A с классом CSS класса:

  // Get the parent DIV, add click listener...
  document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
    // Get the CSS classes
    var classes = e.target.className.split(" ");
    // Search for the CSS class!
    if(classes) {
        // For every CSS class the element has...
        for(var x = 0; x < classes.length; x++) {
            // If it has the CSS class we want...
            if(classes[x] == "classA") {
                // Bingo!
                console.log("Anchor element clicked!");
                // Now do something here....
            }
        }
    }

  }
});

http://davidwalsh.name/event-delegate


В этом ответе я предлагаю несколько решений с описаниями. Не стесняйтесь задавать вопросы, если что-то неясно
PS: К сожалению, кто-то слил это с верхним ответом, не отдавая должного.

Быстрое и грязное решение:

Date.now() /1000 |0

Предупреждение : оно может сломаться в 2038 году и вернуть отрицательные числа, если вы делаете магию |0 . Вместо этого используйте Math.floor()

Решение Math.floor() :

Math.floor(Date.now() /1000);

Некоторые другие варианты Derek 朕 會 功夫 взяты из комментариев ниже этого ответа:

new Date/1e3|0

Polyfill для получения Date.now() :

Чтобы заставить его работать в IE, вы можете это сделать (Polyfill from MDN ):

if (!Date.now) {
    Date.now = function now() {
        return new Date().getTime();
    };
}

Если вам не нравится год / день недели / летнее время, вы можете снять его и использовать после 2038 года:

var now = (function () {
    var year = new Date(new Date().getFullYear().toString()).getTime();
    return function () {
        return Date.now() - year
    }
})();

Некоторые результаты, как это будет выглядеть:

new Date()
Thu Oct 29 2015 08:46:30 GMT+0100 (Mitteleuropäische Zeit )
new Date(now())
Thu Oct 29 1970 09:46:30 GMT+0100 (Mitteleuropäische Zeit )

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

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

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

var relativeTime = (function () {
    var start = Date.now();
    return function () {
        return Date.now() - start
    }
})();

Если вы используете jQuery, вы можете использовать $.now() как описано в Документах jQuery, что делает полипол устаревшим, так как $.now() внутренне делает то же самое: (new Date).getTime()

Если вы просто довольны версией jQuery, подумайте над this ответом, так как я не нашел его сам.

Теперь крошечное объяснение того, что |0 :

Предоставляя | , вы говорите интерпретатору о выполнении двоичной операции ИЛИ. Операции бит требуют абсолютных чисел, которые превращают десятичный результат из Date.now() / 1000 в целое число.

Во время этого преобразования десятичные знаки удаляются, что приводит к тому же результату, что и к использованию Math.floor() но с использованием меньшего количества кода.

Однако будьте осторожны: он преобразует 64-битное двойное число в 32-битное целое число. Это приведет к потере информации при работе с огромными числами. Временные метки будут разрываться после 2038 из-за 32-битного целочисленного переполнения.

Для получения дополнительной информации о Date.now перейдите по этой ссылке: MDN





javascript javascript-events event-handling event-delegation