Событие jQuery click запускается в первый раз, но не во второй - PullRequest
3 голосов
/ 22 января 2011

Это HTML, с которым я работаю:

<ul id="categories">
  <li><a href="#cargo">Cargo Trailers</a></li>
  <div class="dropdown">
    <ul>
      <li><a href="#utility">Utility Trailers</a></li>
    </ul>
  </div>
</ul>

Я написал скрипт jQuery, чтобы скрыть выпадающий элемент div.Выпадающий элемент div появляется при первом запуске события click.После выбора li в выпадающем div и переключения мест с первым li в #categories ul, щелчок по li не вызовет выпадающий div.

Вот jQuery:

jQuery(document).ready(function($) {

// hide the dropdown div
$('#categories > div').hide();

/*
    Click the drop down arrow function
*/
var $listHeader = $('#categories > li');

$listHeader.click(function() {  

    if ( $('#categories > div:hidden') ) {
        //show the drop down
        $('#categories > div').show();
    } else {
        //hide the drop down
        $('#categories > div').hide();
    }
});


/*
    Click a list-item in the drop down function
*/
$('#categories > div a').click(function() {


    /* actions to change the title to the newly selected item */
    // hide the ul
    $('#categories > div').hide();

    // move the clicked item to the header
    $(this).prependTo('#categories > li');

    // move the previous title to the dropdown and sort
    $('#categories > li > a:eq(1)').prependTo('#categories > div > ul > li:empty');

    // Reset the listHeader variable
    $listHeader = $('#categories > li');

    // cancel default browser action
    return false;

});
});

Ответы [ 3 ]

4 голосов
/ 22 января 2011

this $('#categories > div:hidden') всегда будет возвращать объект jQuery (который оценивается как true), даже если нет элементов, соответствующих селектору. Используйте jQuery .toggle() вместо if...else:

$('#categories > div').toggle();

вот пример для игры с


Обновление в ответ на ваш комментарий: Обновленный пример - http://jsfiddle.net/Etkjr/1/

Вы правы, обработчики событий не связаны с изменением DOM. Чтобы предотвратить это, вам нужно использовать 2 функции jQuery: .live() и .delegate. Оба они отслеживают изменения DOM и связывают события с селекторами при изменении DOM.

Вы хотите щелкнуть по первому значку li, чтобы развернуть выпадающее меню - используйте

$('#categories li:first').live('click', function() {})

таким образом, нажатие на первую li активирует ваш обработчик, даже если ваш li только что был перемещен в первую позицию.

$('#categories').delegate('.dropdown a', 'click', functon(evt) {})

Это пример .delegate(). Это означает, что когда кто-то щелкает элемент, соответствующий .dropdown a внутри #categories, будет вызываться этот обработчик.

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

Я также обновил "движущийся" код. Интересным побочным эффектом здесь является то, что вам не нужно .hide() выпадающий внутри второго обработчика. Видите ли, когда вы нажимаете на ссылку внутри выпадающего, ссылка перемещается в первую позицию. .live() обнаруживает это и назначает обработчик click() для ссылки, по которой вы только что щелкнули. Но событие все еще распространяется, поэтому после того, как ваш второй обработчик завершен, событие всплывает до li, и $('.li').live('click', ...) выполняется, скрывая ваш выпадающий div.

Надеюсь, это имеет смысл.

0 голосов
/ 22 января 2011

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

0 голосов
/ 22 января 2011

Это может быть ваше заявление, если нужно. Длина на нем, давая:

If ($ ('селектор'). Длина> 0) // показать выпадающий список

Ваш текущий оператор if не проверяет, существует ли объект. Селекторы возвращают пустую коллекцию элементов, не ноль, если они ничего не соответствуют.

...