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.
Надеюсь, это имеет смысл.