Какой самый эффективный способ справиться с отображением диалога / модального в JavaScript? - PullRequest
2 голосов
/ 01 декабря 2011

[ОБНОВЛЕНИЕ:] вот ссылка для проверки (если вы не хотите клонировать репо) http://jsfiddle.net/integralist/g9EPu/

У меня есть много диалогов / модалов, которые необходимо отображать приналожение определенных ссылок в веб-приложении.

оглавление (tl; dr)

  • Как я это делал
  • Как я пыталсяэто недавно
  • Что лучше?
  • А как насчет мышиного / отпускного?

Как раньше я справлялся с этим

Как обычносделать это, чтобы использовать делегирование событий.

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

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

Если событие mouseover (для ссылки) запускается, я отображаю диалоговое окно.

Если событие mouseout (для ссылки) запускается, тогда я скрываю диалоговое окно.

Если я наведите указатель мыши на ссылку, которая активировала обработчик события, то мне обычно нужно установить таймер для задержки скрытия диалога (достаточно долго), чтобы я могзатем наведите указатель мыши на диалоговое окно, которое само очищает таймер, установленный указателем мыши.

Затем у меня есть событие mouseout, связанное с диалоговым окном, поэтому я могу скрыть диалоговое окно, когда пользователь убирает свою мышь с диалогового окна.

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

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

  2. При использовании этого метода для элемента

Как я пытался это сделать недавно

Например, код: https://github.com/Integralist/Mouse-Over-Out-Script (вы можете просто клонировать репозиторий и запустить файл index.html локальнопросто чтобы увидеть, что происходит)

Но для краткого объяснения ...

Мы связываем событие mousemove с элементом document.documentElement (но вы можете сделать это на document.body, еслиВы хотели), а затем мы сохраняем координаты х / у позиции мыши.Мы предоставляем общедоступный API-доступ к методу 'check', который позволяет нам узнать, находится ли позиция мыши над элементом, который мы предоставили для 'check' (мы измеряем размеры элементов и добавляем их в координаты x / y).).

В приведенном выше репо у нас есть календарь, в котором отображается диалог, когда на определенную дату происходит событие.Мы храним все

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

Так что потенциально может быть 31+ (потому что мы показываем первые несколько дней следующего месяца) возможности для отображения диалога и, таким образом, устанавливается более 31 таймера!

Этот репозиторий теперь работает, когда первая версия, в которой я использовал делегирование событий, не была.

Что лучше?

Я беспокоюсь о производительности наверсия 'mousemove', потому что она потенциально может использовать много таймеров (в зависимости от того, сколько диалогов вам нужно на одной странице).В приведенном выше примере с календарем есть до 31+ таймеров, которые могут быть запущены!

А как насчет указателя мыши / выхода?

Я знаю, что эти события существуют, и если бы все браузеры поддерживали их, я мог бы безопасно использовать первую версию и не должен проверять наличие дочерних элементов, вызывающих ошибочные события mouseout / over, которые запускаются.Но, несмотря на то, что я не верю, это исправило бы пример с календарем событий, где слишком быстрое перемещение мыши означало, что события mouseout / over для

не запускались браузером.В любом случае, я знаю, что вы можете заполнить это, так как jQuery предоставляет события mouseenter / exit, но просматривая их код, я не смог заставить это работать для моего скрипта (так как я не использую jQuery или любую другую универсальную библиотеку - ps, иЯ не хочу, поэтому, пожалуйста, не предлагайте это как вариант).

Большое спасибо за любую помощь / совет или руководство, которое кто-то может мне дать.

С уважением, Марк

1 Ответ

0 голосов
/ 07 декабря 2011

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

Чтобы решить эту проблему: в вашем коде события просто используйте функцию «isAncestor» (см. Ниже)

/*
 * element = the "target" in your mouseout event handler
 * other = the node you really want to check if you're over
 */
isAncestor: function(element, other)
{
    while ( element && element != other ) element = element.parentNode;
    return ( element != null && element != undefined );
}

Таким образом, в вашем коде мышки для вашего элемента (назовем его «itemElement»), вы должны проверить его следующим образом:

//We're really mousing out, close dialog
if ( !isAncestor( mouseOutEvent.target, itemElement ) )
{
    ...do something ...
}
...