子输入框关闭点击导航下拉菜单

时间:2013-06-22 03:20:08

标签: jquery events drop-down-menu navigation

小提琴: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时仍然切换。

由于

2 个答案:

答案 0 :(得分:0)

试试这个:

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

Fiddle

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

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

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

来自 docs

  

mouseenter事件在处理事件冒泡的方式上与鼠标悬停不同。如果在此示例中使用鼠标悬停,则当鼠标指针移过Inner元素时,将触发处理程序。这通常是不受欢迎的行为。另一方面,mouseenter事件仅在鼠标进入绑定的元素而不是后代时触发其处理程序。因此,在此示例中,处理程序在鼠标进入外部元素时触发,而不是内部元素。

更新

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

    // 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;
            }
        }
    }

<强> Fiddle

答案 1 :(得分:0)

检查此演示,http://jsfiddle.net/4PMwP/12/

为您的输入添加ID,并在$('#showInput').click(jsddm_open);脚本后添加一行$(document).click(jsddm_close);

(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(); });