Вызов функции вне html объекта
Всем ночи доброй.
Пишу функцию меню, нечто похожее на выпадающие меню во всех программах (например вашем браузере). Суть простая, тыкнули на пункт меню, открылся children. Тыкнули на область вне элемента, на который вызвали функцию, всё вернулось в исходное состояние. Возможно объяснил неочень, но легко понять, если потыкать меню в браузере))) Собственно как грамотно определить саму область вне элемента, пока непонятно, кто-нибудь занимался подобным? |
Тоесть проще говоря нужно взять область элемента "body" и вырезать из неё элемент, пусть будет "div#menu". Пока работаем с "div#menu", работает плагин, когда кликаем вне "div#menu", плагин возвращается в исходное состояние, как буд-то страниу обновили...
|
каждый раз при открытии меню делать:
$(document).one("click", close_menu) |
Octane, собственно зачем? Сейчас получается, что при клике на меню, мы открываем вложенный элемент, а следующей строкой закрываем его...
|
Что непонятного? Открыли меню, повесили обработчик для закрытия. Или меню многоуровневое? Тогда повесьте постоянный обработчик на документ и проверяйте event.target
|
Цитата:
|
Aetae, спасибо )
Octane, и вам) Обрабатывать страницу при каждом действии пользователя, по-моему не очень, а вешать обработчик на одноуровневое меню - вполне. |
Если меню должно закрываться по клику на странице, то в любом случае будет обработчик события click на document или другом общем для всех элементов узле (html, body, …), не понятно к чему вы сказали:
Цитата:
|
Aetae, а кросс-браузерного варианта для отмены всплытия от нижнего элемента к верхнему нету? =\
|
Цитата:
На самом деле нагородить можно всё что угодно, но пока что хотелось бы найти способ вырезать это самое меню из document и один раз вызвать функцию "close_menu", при клике на полученную область в document. И при этом чтобы плагин выключился и не работал, пока мы опять не ткнемся мышкой в меню... |
Цитата:
|
Aetae, либо ночь на дворе, либо: "Остановка всплытия" - кроссбраузерно, а остальное нет... Хотя в моем случае по-моему все равно откуда и куда двигаться... пора спать, завтра выложу результат =\
|
Octane,
Вы это имели ввиду? if($(event.target.nodeName).parent('ul').hasClass('menu')){alert('Нажали на меню')} вместо alerta делаем вызов по умолчанию, в противном случае, выключаем менюшку? |
<script src="http://code.jquery.com/jquery-latest.min.js"></script> <style type="text/css"> body {background: #424A51;} .block {position:absolute;top:20%;left: 40%;width: 200px;height: 50px;} .block a {border: 1px solid #DDD;color: #FFF;display: block;text-align: center;text-decoration:none;width: 140px;height: 20px;} .block img {border: 1px solid #DDD; width: 140px;height: 50px;} </style> <script type="text/javascript"> $(function(){ $('.block').each(function(){ $(this).find('img').hide(); $(this).find('a').mouseover(function(){ $(this).next('img').show(); }); $(document).click(function(e){ (e.target.nodeName != $('.block img').get(0).tagName) && $(this).find('img').hide(); }); }); }); </script> <div class="block"> <a href="#" rel="">link</a> <img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" /> </div> |
monolithed, не пойдет
$("body").click(function(event) { if($(event.target.nodeName).parents('ul').hasClass('menu') || event.target.className == 'menu'){ //открываем меню, сделав еще1 клик } else { //закрываем меню } }); пока рабочий вариант только этот, но, если нужно открыть меню по клику, то приходится делать 2 клика, а если открыть нужно при наводке, то сначала делаем клик, потом немного теребим мышку и вуаля... в общем бред. Как вариант, сделать иначе: //conf - options if(conf.event == 'click') { $("body").click(function(event) { if($(event.target.nodeName).parents('ul').hasClass('menu') || event.target.className == 'menu'){ //открываем меню, без какого-либо event } else { //закрываем меню } }); } else { //юзаем обычный hover для работы с вложенностью } |
Цитата:
|
monolithed,
потому что, если $(this).find('a').mouseover(function(){ заменить на $(this).find('a').click(function(){ картинка не откроется вообще |
Цитата:
Код простейший же: <!DOCTYPE html> <meta charset="UTF-8"> <title>Menu</title> <style> body { font: 14px/24px sans-serif; } .nav { height: 24px; background: #ccc; zoom: 1; /* IE7 clear fix */ } .nav:after { display: block; overflow: hidden; height: 0; clear: both; content: "."; } .menu { position: relative; float: left; margin-right: 10px; } .menu .list, .menu .list li { display: block; margin: 0; padding: 0; list-style: none; } .menu .list { display: none; position: absolute; top: 24px; left: 0; background: #ccf; } .menu .list li { white-space: nowrap; } </style> <div class="nav"> <div class="menu"> <span class="toggler">Menu 1</span> <ul class="list"> <li><a href="#">Menu 1 item 1</a></li> <li><a href="#">Menu 1 item 2</a></li> <li><a href="#">Menu 1 item 3</a></li> <li><a href="#">Menu 1 item 4</a></li> <li><a href="#">Menu 1 item 5</a></li> </ul> </div> <div class="menu"> <span class="toggler">Menu 2</span> <ul class="list"> <li><a href="#">Menu 2 item 1</a></li> <li><a href="#">Menu 2 item 2</a></li> <li><a href="#">Menu 2 item 3</a></li> <li><a href="#">Menu 2 item 4</a></li> <li><a href="#">Menu 2 item 5</a></li> </ul> </div> </div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script> $(function () { $(".menu .toggler").click(function () { var $list = $(this).next(".list").stop(); $list.slideDown(100, function () { $(document).one("click", function () { $list.slideUp(100); }) }); }); }); </script> |
Цитата:
|
Octane, да вот если зохочется внести форму в какой-то пункт меню, то трындец)))
monolithed, именно для этого) |
Цитата:
|
Цитата:
Собственно говоря реализаций море, самого наработок много лежит. Но задача сейчас другая, определить элемент на который вызывается функция '<ul id="menu">'. Пока работаем с ним, открываются вкладки меню: ссылки, формы, текстовые блоки, картинки, грузится ajax в каком-нибудь другом блоке, в общем всё, что угодно. Как-только кликнули куда-нибудь вне блока нашего меню, меню сбрасывается на первоначальный вид. Меню могут вызываться как угодно, а закрываться только при клике вне меню. Меню может быть неограниченной вложенности, точнее не нужен способ, который будет независим от этого... Вот как-то так... |
Сразу все подробности поведения меню конечно трудно было описать… остается проверять event.target и его родителей.
|
Octane, прошу прощения, на счет "клика" внутри меню, моё упущение.
$('ul.menu').menu({/* config */}); $("body").click(function(event) { if(!$(event.target).parents('ul').hasClass('menu')){ $('ul.menu').menu({/* config */}, 'destroy'); } }); Хотя, как мне кажется, это не лучший вараинт) |
Ну можно попробовать подкладывать под меню
div {position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: url(empty.gif); } с прозрачным фоном и по клику на него скрывать меню, если так не хочется вешать обработчик на body или document. |
Octane
$('div#cl').click(function(event) { $('ul.menu').menu({/* config */}, 'destroy'); }); 'div#cl' положил после <body>. В таком варианте не работает, если мы тыкаем на определенный элемент в html документе, ну, что в принципе логично... Если ограничиваться кликами по пустой области в документе, то конечно вариант намного лучше, потому что каждый раз не делаем проверок. |
Часовой пояс GMT +3, время: 01:18. |