1

小提琴:http: //jsfiddle.net/4PMwP/

我正在为导航栏使用以下脚本:

(function($){

  var timeout    = 500;
  var closetimer = 0;
  var ddmenuitem = null;

  // From https://github.com/Modernizr/Modernizr/blob/master/modernizr.js
  var isTouch = ('ontouchstart' in window) ||
                window.DocumentTouch && document instanceof DocumentTouch;

  // jsddm funcs from http://javascript-array.com/scripts/jquery_simple_drop_down_menu/
  function jsddm_open($this){
    jsddm_canceltimer();
    jsddm_close();
    ddmenuitem = $this.find('ul').css('visibility', 'visible');
  }

  function jsddm_close() {
    if(ddmenuitem){
      ddmenuitem.css('visibility', 'hidden');
      ddmenuitem = null;
    }
  }

  function jsddm_timer() { 
    closetimer = window.setTimeout(jsddm_close, timeout);
  }

  function jsddm_canceltimer() { 
    if(closetimer)
    {  window.clearTimeout(closetimer);
       closetimer = null;
    }
  }

  function jsddm_toggle($this) {
    if (ddmenuitem && $this.has(ddmenuitem[0]).length){
      jsddm_close();
    }
    else {
      jsddm_open($this);
    }
  }

  $.fn.make_dropdown = function(options){

    return this.each(function(){

      if (options && options['timeout']){
        timeout = options['timeout'];
      }

      $(this).click(function(event){
        jsddm_toggle($(this));
        event.stopPropagation();
      });
      if (!isTouch){
        $(this).mouseover(function(){ jsddm_open($(this)) }).mouseout(jsddm_timer);
      }

    });
  }

  $(document).click(jsddm_close);

})(jQuery);

悬停或单击时会显示下拉菜单,这对于桌面和移动浏览器非常有用。问题是我的下拉菜单将包括用于搜索、登录等的输入框,单击这些不应关闭下拉菜单。由于下拉列表中的所有内容都是监听点击的 li 的孩子,因此无论如何都会关闭。

当单击子元素时,我需要下拉菜单保持可见,但在单击主父 li 时仍会切换。

谢谢

4

2 回答 2

0

尝试这个:

$(document).ready(function () {
    $('#menubar > li').make_dropdown();
    $('li  input').click(function (e) {
        e.stopPropagation();
    })
});

小提琴

event.stopPropagation您可以通过在输入级别禁用它来阻止单击事件冒泡父树。这将阻止执行其他父单击处理程序。

另外,我不确定这是否适合您的情况,但是:

使用mouseenter/mouseleave( hover) 事件而不是mouseover/mouseout事件,因为即使您将鼠标悬停在绑定事件的父级内的子级上,后者也会被触发。

来自文档

mouseenter 事件在处理事件冒泡的方式上与 mouseover 不同。如果在这个例子中使用了 mouseover,那么当鼠标指针移动到 Inner 元素上时,将触发处理程序。这通常是不受欢迎的行为。另一方面,mouseenter 事件仅在鼠标进入它所绑定的元素而不是后代元素时触发其处理程序。所以在这个例子中,当鼠标进入 Outer 元素而不是 Inner 元素时,会触发处理程序。

更新

根据您在问题中的评论:当输入框处于活动状态时,不会出现菜单,这也会在鼠标移出时隐藏。只有在 int 框中按下 enter 键时,菜单才会被隐藏。只是基于我的假设

    // on Search Box click    
    $('li  .searchBox').click(function (e) {
        e.stopPropagation();
    }).keypress(function (e) {
        if (e.which == 13) // on enter key press close
        {
            $('.searchBox').closest('ul').css('visibility', 'hidden'); // SInce you are using visility for you menus. You can also try calling your method to hide, But this is a pointer
        }
    });

并在打开关闭

function jsddm_open($this) {
        if ($('.searchBox').css('visibility') == 'hidden') { // Dont show any other menu when searchbox is active
            jsddm_canceltimer();
            jsddm_close();
            ddmenuitem = $this.find('ul').css('visibility', 'visible');
        }
    }

    function jsddm_close() {
        if ($('.searchBox').css('visibility') == 'hidden') { // check if the input is visible if not then do this.

            if (ddmenuitem) {
                ddmenuitem.css('visibility', 'hidden');
                ddmenuitem = null;
            }
        }
    }

小提琴

于 2013-06-22T03:22:18.430 回答
0

Check this DEMO, http://jsfiddle.net/4PMwP/12/

Give an ID to your input and added in one line $('#showInput').click(jsddm_open); after your $(document).click(jsddm_close); script.

(function($){

  var timeout    = 500;
  var closetimer = 0;
  var ddmenuitem = null;

  // From https://github.com/Modernizr/Modernizr/blob/master/modernizr.js
  var isTouch = ('ontouchstart' in window) ||
                window.DocumentTouch && document instanceof DocumentTouch;

  // jsddm funcs from http://javascript-array.com/scripts/jquery_simple_drop_down_menu/
  function jsddm_open($this){
    jsddm_canceltimer();
    jsddm_close();
    ddmenuitem = $this.find('ul').css('visibility', 'visible');
  }

  function jsddm_close() {
    if(ddmenuitem){
      ddmenuitem.css('visibility', 'hidden');
      ddmenuitem = null;
    }
  }

  function jsddm_timer() { 
    closetimer = window.setTimeout(jsddm_close, timeout);
  }

  function jsddm_canceltimer() { 
    if(closetimer)
    {  window.clearTimeout(closetimer);
       closetimer = null;
    }
  }

  function jsddm_toggle($this) {
    if (ddmenuitem && $this.has(ddmenuitem[0]).length){
      jsddm_close();
    }
    else {
      jsddm_open($this);
    }
  }

  $.fn.make_dropdown = function(options){

    return this.each(function(){

      if (options && options['timeout']){
        timeout = options['timeout'];
      }

      $(this).click(function(event){
        jsddm_toggle($(this));
        event.stopPropagation();
      });
      if (!isTouch){
        $(this).mouseover(function(){ jsddm_open($(this)) }).mouseout(jsddm_timer);
      }

    });
  }

  $(document).click(jsddm_close);
  $('#showInput').click(jsddm_open);

})(jQuery);

$(document).ready(function(){   $('#menubar > li').make_dropdown(); });
于 2013-06-22T03:52:54.317 回答