Прикрепить событие close к div, к которому уже прикреплен fadeOut - PullRequest
2 голосов
/ 08 августа 2010

Я реализовал пример всплывающего окна «рычание» из книги «jquery: новичок для ниндзя», в основном он показывает всплывающее окно со стилем рычания в вашем браузере, которое можно закрыть, щелкнув в нем ссылку «закрыть».Код работает отлично, но я хочу улучшить его, через некоторое время появившееся всплывающее окно fadeOut, ЕСЛИ пользователь никогда не нажимал на него, чтобы закрыть его (это может быть довольно раздражающим, когда приходится закрывать их).Исходный код выглядит следующим образом:

У меня есть этот простой div в моем HTML, и он стилизован в соответствии с примером в книге

   <div id="message_box">
   </div>

, а вот код jquery (опять-таки прямойиз книги):

/**
* function that adds notices to growl like message box in bottom right corner
*/
function addNotice(notice) {
   $('<div class="notice"></div>')
      .append('<div class="skin"></div>')
      .append('<a href="#" class="close">close</a>')
      .append($('<div class="content"></div>').html($(notice)))
      .hide()
      .appendTo('#message_box')
      .fadeIn(1000)
}

/**
* event handler for closing growl like message box
*/
$('#message_box')
   .find('.close')
   .live('click', function() {
      $(this)
         .closest('.notice')
         .animate({
            border: 'none',
            height: 0,
            marginBottom: 0,
            marginTop: '-6px',
            opacity: 0,
            paddingBottom: 0,
            paddingTop: 0,
            queue: false
         }, 1000, function() {
            $(this).remove();
         });
});


/* Give it a whirl */
$(document).ready(function() {
   addNotice("<p>Welcome</p>");
});

Я просто изменил функцию addNotice следующим образом, добавив fadeOut с задержкой (я тоже пытался без задержки, та же проблема):

function addNotice(notice) {
   $('<div class="notice"></div>')
      .append('<div class="skin"></div>')
      .append('<a href="#" class="close">close</a>')
      .append($('<div class="content"></div>').html($(notice)))
      .hide()
      .appendTo('#message_box')
      .fadeIn(1000)
/* This works but seems to disable the close functionality */
      .delay(10000).fadeOut(1000, function(){$(this).remove();});
} .delay(10000).fadeOut(1000, function(){$(this).remove();});

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

Может кто-нибудь сказать мне, что я делаю неправильно?Почему событие закрытия никогда не вызывается / не срабатывает?

Приветствия, Марк.

Ответы [ 2 ]

2 голосов
/ 08 августа 2010

Вам нужно добавить .clearQueue().stop() к действию закрытия. Анимации выполняются по порядку, последовательно, а не параллельно. Поскольку вы ставите в очередь fadeIn и сразу fadeOut, оба они будут выполняться до того, как будет выполнен ваш вызов close animate(). stop() остановит текущую анимацию (задержку или затухание), clearQueue очистит очередь анимации, поэтому все, что вы вызовете следующим animate, будет запущено немедленно:

$('#message_box')
   .find('.close')
   .live('click', function() {
      $(this)
         .closest('.notice')
         .clearQueue()
         .stop()
         .animate({
            border: 'none',
            height: 0,
            marginBottom: 0,
            marginTop: '-6px',
            opacity: 0,
            paddingBottom: 0,
            paddingTop: 0,
            queue: false
         }, 1000, function() {
            $(this).remove();
         });
});
0 голосов
/ 08 августа 2010

Из документации по delay():

Установить таймер для задержки выполнения последующих элементов в очереди

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

В вашем исходном случае происходит следующее:

  1. В вашем уведомлении отображается
  2. При нажатии кнопки закрытия
  3. Уведомление анимировано и исчезает

Что происходит, когда вы добавляете код задержки:

  1. Отображается ваше уведомление.
  2. Затем добавляется задержка на 10 секунд.Это предотвратит запуск любых анимаций в течение следующих 10 секунд
  3. Это добавляет fadeOut(1000, function(){$(this).remove();}); в очередь анимаций (это будет следующая анимация, которая будет запущена после истечения 10 секунд задержки)
  4. Вы нажимаете на кнопку закрытия.
  5. Закрывающая анимация ставится в очередь под номером 2 в очереди после первого fadeOut, который вы добавили ранее.Другими словами, он не запускается, поскольку вы по-прежнему устанавливаете задержку
Проходит задержка в 10 секунд Ваша первая анимация, fadeOut(1000, function(){$(this).remove();});, запускается - удаление уведомления Ваша вторая анимация (та, которая запускается нажатием кнопки «Закрыть») запускается.Поскольку вы уже удалили уведомление в последней анимации, оно не имеет смысла

Решение.Используйте setTimeout, чтобы установить тайм-аут для закрывающей анимации, если вы не нажали на ссылку закрытия до того, как истекло время ожидания. См. Принятый ответ.Оставляя мой ответ для книг по истории

function addNotice(notice) {
   var notice =
   $('<div class="notice"></div>')
      .append('<div class="skin"></div>')
      .append('<a href="#" class="close">close</a>')
      .append($('<div class="content"></div>').html($(notice)))
      .hide()
      .appendTo('#message_box')
      .fadeIn(1000)

    /* Close the timeout after 10 seconds */
    setTimeout(function() {
        notice.fadeOut(1000, function(){$(this).remove();});
    }, 10000);
}

Редактировать: В этом случае ответ Майка был более элегантным.Мне не очень нравится использовать setTimeout, хотя, если вы будете использовать другие анимации в уведомлении, использование задержки может создать некоторые проблемы.

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