jQuery не заменит больше после первого раза - PullRequest
2 голосов
/ 29 июня 2009

В качестве пасхального яйца для части одного из моих сайтов, в моем нижнем колонтитуле #left есть «пасхальное» яйцо, которое меняется каждый раз, когда вы нажимаете на него, открывая забавные сообщения:

$('#left').append(" <span><a href='#' id='dontclick1'>Don't click.</a></span>");

// time for some fun
$('#dontclick1').click(function() {
$('#left span').html("<a href='#' id='dontclick2'>I told you not to click.</a>");
return false;
});

$('#dontclick2').click(function() {
$('#left span').html('<a href="#" id="dontclick3">Now you will suffer.</a>');
return false;
});

$('#dontclick3').click(function() {
$('#left span').html('<a href="#" id="dontclick4">Shame!</a>');
return false;
});

$('#dontclick4').click(function() {
$('#left span').html('<a href="#" id="dontclick5">You shouldn't click.</a>');
return false;
});

$('#dontclick5').click(function() {
$('#left span').html('<a href="#" id="dontclick6">But you did. Sigh.</a>');
return false;
});

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

Что я делаю не так? Это из-за return false внутри? Без этого он прыгает на верх страницы. Я в замешательстве.

Ответы [ 5 ]

13 голосов
/ 29 июня 2009

Э-э ... это довольно ужасный способ делать то, что вы хотите, но вы исправите это, заменив все .click на .live('click' - во время добавления событий ко всем элементам, dontclick2, 3 и т. Д. Еще не существует. Читайте на live для дополнительной информации или ищите по этому сайту, так как эта проблема встречается довольно часто.

EDIT

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

лучший способ сделать это (по крайней мере, по моему скромному мнению) будет иметь такую ​​разметку на вашей странице:

<ul id="easter_messages" style="display: none;">
  <li>Don't click</li>
  <li>I told you not to click.</li>
  <li>Now you will suffer.</li>
  <li>Shame!</li>
  <li>You shouldn't click.</li>
  <li>But you did. Sigh.</li>
</ul>

Это будет семантически правильное представление о том, что у вас есть. Вы можете использовать CSS так:

#easter_messages ul, #easter_messages li { margin: 0; padding: 0; }
#easter_messages li { cursor: pointer; list-style-type: none; display: inline; }

И, наконец, используйте этот код jQuery:

$('#easter_messages').show().find('li').hide().click(function() {
    var $li = $(this).next('li');
    if($li.length == 1) {
      $(this).hide();
      $li.show();
    }
}).filter(':first').show();

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

И это пример этого в действии .

7 голосов
/ 29 июня 2009

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

$('#left').append(" <a href='#' id='dontclick'>Don't click.</a>");

// time for some fun
var messageNumber = 0;

$("#dontclick").click(function() {
    var messages = [
        "I told you not to click.",
        "Now you will suffer.",
        "Shame!",
        "You shouldn't click.",
        "But you did. Sigh."
    ];

    $(this).text(messages[messageNumber]);

    // Cycle to the next message unless we're already there.
    if (messageNumber < messages.length - 1) {
        messageNumber += 1;
    }

    return false;
});

Я изменил его, поэтому вы просто создаете <a id='dontclick'> один раз, и ему больше не нужен номер. Обработчик click регистрируется только один раз, и каждый раз, когда он вызывается, в ссылке #dontclick отображается другое сообщение. Кстати, $(this) в строке $(this).text(...) относится к $("#dontclick"). Это просто немного короче, чтобы написать $(this).

3 голосов
/ 29 июня 2009

Поскольку вы устанавливаете хэдлеры событий для элементов, которых еще нет.

Попробуйте

.live("click", function() {
});

вместо .click (function () {...

2 голосов
/ 29 июня 2009

Я бы оставил комментарий, но у меня пока нет представителя, поэтому я скажу это здесь. :)

.live () - БОЛЬШОЙ способ справиться с подобными вещами, но для этого требуется jQuery 1.3. Если вы застряли в jQuery 1.2.6, ответ как , предложенный Дэниелом Моурой , является правильным подходом. :)

2 голосов
/ 29 июня 2009

Элементы создаются после привязки события клика. Вы должны связать после создания элемента.

$('#dontclick2').click(function() {
   $('#left span').html('<a href="#" id="dontclick3">Now you will suffer.</a>');
   $('#dontclick3').click(function() {
   $('#left span').html('<a href="#" id="dontclick4">Shame!</a>');
   return false;
   });

   return false;
});
...