Javascript 如何在单击而不是悬停时打开 Superfish jQuery 菜单?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7312414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:44:26  来源:igfitidea点击:

How can I open a Superfish jQuery Menu on click rather than hover?

javascriptjquerymenusuperfish

提问by Squiggs.

I've had a quick browse around the web for an implementation of Superfish menu by Joel Birch that works on onclick, rather than hover.

我在网上快速浏览了 Joel Birch 的 Superfish 菜单实现,该菜单适用于点击,而不是悬停。

Found this link by Karl Swedberg at Github, which looks like the ticket.

在 Github 上找到 Karl Swedberg 的这个链接,看起来像票。

https://gist.github.com/917446

https://gist.github.com/917446

It works like a charm, right up to the point where I click on an active link, at that point the menu closes, and appears to return false.

它就像一个魅力,一直到我单击活动链接的时候,然后菜单关闭,并且似乎返回 false。

How can I get it to navigate to the actual link destination?

我怎样才能让它导航到实际的链接目的地?

采纳答案by Jeremiah

Changing this line (line 21, over function):

更改此行(第 21 行,在函数上):

$$.showSuperfishUl().siblings().hideSuperfishUl();

To this:

对此:

$$.click(function(){$(this).showSuperfishUl().siblings().hideSuperfishUl();});

Full superfish code for clicking the menu:

单击菜单的完整 superfish 代码:

/*
 * Superfish v1.4.8 - jQuery menu widget
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 *  http://www.opensource.org/licenses/mit-license.php
 *  http://www.gnu.org/licenses/gpl.html
 *
 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
 */

;(function($){
    $.fn.superfish = function(op){

        var sf = $.fn.superfish,
            c = sf.c,
            $arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
            over = function(){
                var $$ = $(this), menu = getMenu($$);
                clearTimeout(menu.sfTimer);
                $$.click(function(){$(this).showSuperfishUl().siblings().hideSuperfishUl();});
            },
            out = function(){
                var $$ = $(this), menu = getMenu($$), o = sf.op;
                clearTimeout(menu.sfTimer);
                menu.sfTimer=setTimeout(function(){
                    o.retainPath=($.inArray($$[0],o.$path)>-1);
                    $$.hideSuperfishUl();
                    if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
                },o.delay); 
            },
            getMenu = function($menu){
                var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
                sf.op = sf.o[menu.serial];
                return menu;
            },
            addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };

        return this.each(function() {
            var s = this.serial = sf.o.length;
            var o = $.extend({},sf.defaults,op);
            o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
                $(this).addClass([o.hoverClass,c.bcClass].join(' '))
                    .filter('li:has(ul)').removeClass(o.pathClass);
            });
            sf.o[s] = sf.op = o;

            $('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
                if (o.autoArrows) addArrow( $('>a:first-child',this) );
            })
            .not('.'+c.bcClass)
                .hideSuperfishUl();

            var $a = $('a',this);
            $a.each(function(i){
                var $li = $a.eq(i).parents('li');
                $a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
            });
            o.onInit.call(this);

        }).each(function() {
            var menuClasses = [c.menuClass];
            if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
            $(this).addClass(menuClasses.join(' '));
        });
    };

    var sf = $.fn.superfish;
    sf.o = [];
    sf.op = {};
    sf.IE7fix = function(){
        var o = sf.op;
        if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
            this.toggleClass(sf.c.shadowClass+'-off');
        };
    sf.c = {
        bcClass     : 'sf-breadcrumb',
        menuClass   : 'sf-js-enabled',
        anchorClass : 'sf-with-ul',
        arrowClass  : 'sf-sub-indicator',
        shadowClass : 'sf-shadow'
    };
    sf.defaults = {
        hoverClass  : 'sfHover',
        pathClass   : 'overideThisToUse',
        pathLevels  : 1,
        delay       : 200,
        animation   : {opacity:'show'},
        speed       : 'fast',
        autoArrows  : true,
        dropShadows : true,
        disableHI   : false,        // true disables hoverIntent detection
        onInit      : function(){}, // callback functions
        onBeforeShow: function(){},
        onShow      : function(){},
        onHide      : function(){}
    };
    $.fn.extend({
        hideSuperfishUl : function(){
            var o = sf.op,
                not = (o.retainPath===true) ? o.$path : '';
            o.retainPath = false;
            var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
                    .find('>ul').hide().css('visibility','hidden');
            o.onHide.call($ul);
            return this;
        },
        showSuperfishUl : function(){
            var o = sf.op,
                sh = sf.c.shadowClass+'-off',
                $ul = this.addClass(o.hoverClass)
                    .find('>ul:hidden').css('visibility','visible');
            sf.IE7fix.call($ul);
            o.onBeforeShow.call($ul);
            $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
            return this;
        }
    });

})(jQuery);

回答by Squiggs.

Karl posted a quick update to help me out on GitHub.. here: https://gist.github.com/652684that didn't quite work for me.

Karl 在 GitHub 上发布了一个快速更新来帮助我……这里:https: //gist.github.com/652684对我来说不太好用。

Grab my working code from the below link.

从下面的链接中获取我的工作代码。

http://www.nilinks.com/home-owner/wp-content/themes/acheson/js/superfish.js

http://www.nilinks.com/home-owner/wp-content/themes/acheson/js/superfish.js

updated.. just incase that link ever dies..

更新了..以防万一该链接死了..

/*
 * Superfish v1.4.8 - jQuery menu widget
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 *  http://www.opensource.org/licenses/mit-license.php
 *  http://www.gnu.org/licenses/gpl.html
 *
 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
 */

;(function($){
    $.fn.superfish = function(op){

        var sf = $.fn.superfish,
            c = sf.c,
            $arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
            over = function(){
                var $this = $(this), menu = getMenu($this);
                clearTimeout(menu.sfTimer);
                $this.showSuperfishUl().siblings().hideSuperfishUl();
            },
            out = function(){
                var $this = $(this), menu = getMenu($this), o = sf.op;
                clearTimeout(menu.sfTimer);
                menu.sfTimer=setTimeout(function(){
                    o.retainPath=($.inArray($this[0],o.$path)>-1);
                    $this.hideSuperfishUl();
                    if (o.$path.length && $this.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
                },o.delay); 
            },
            getMenu = function($menu){
                var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
                sf.op = sf.o[menu.serial];
                return menu;
            },
            addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };

        return this.each(function() {
          var $this = $(this);
            var s = this.serial = sf.o.length;
            var o = $.extend({},sf.defaults,op);
            o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
                $(this).addClass([o.hoverClass,c.bcClass].join(' '))
                    .filter('li:has(ul)').removeClass(o.pathClass);
            });
            sf.o[s] = sf.op = o;
      // CHANGED: by KARL SWEDBERG
            if ( (o.eventType === 'hoverIntent' && !$.fn.hoverIntent) || !(/^(?:hover|hoverIntent|toggle)$/).test(o.eventType) ) {
              o.eventType = 'hover';
            }
            $this.find('li:has(ul)')[o.eventType](over,out).each(function() {
                if (o.autoArrows) {
                  addArrow( $('>a:first-child',this) );
                 // this.addClass("yourClass");
                }
            })
            .not('.'+c.bcClass)
                .hideSuperfishUl();


            $this.find('a').each(function(i){
                var $a = $(this), $li = $a.parents('li');
                $a.focus(function(){over.call($li);}).blur(function(){out.call($li);});
                $a.click(function(event) {
                  event.preventDefault();
                  if ( !$a.hasClass("sf-with-ul") ) {
                    location.href = this.href;
                  }
                });
            });
            o.onInit.call(this);

        }).each(function() {
            var menuClasses = [c.menuClass];
            if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) {
              menuClasses.push(c.shadowClass);
            }
            $(this).addClass(menuClasses.join(' '));
        });
    };

    var sf = $.fn.superfish;
    sf.o = [];
    sf.op = {};
    sf.IE7fix = function(){
        var o = sf.op;
        if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined) {
            this.toggleClass(sf.c.shadowClass+'-off');
        }
        };
    sf.c = {
        bcClass     : 'sf-breadcrumb',
        menuClass   : 'sf-js-enabled',
        anchorClass : 'sf-with-ul',
        arrowClass  : 'sf-sub-indicator',
        shadowClass : 'sf-shadow'
    };
    sf.defaults = {
        hoverClass  : 'sfHover',
        pathClass   : 'overideThisToUse',
        pathLevels  : 1,
        delay       : 800,
        animation   : {opacity:'show'},     
        speed       : 'normal',
        closeAnimation: {opacity: 'hide'},
        closeSpeed: 0,
        autoArrows  : true,
        dropShadows : true,
    // CHANGED: by KARL SWEDBERG
        eventType   : 'toggle', // one of 'toggle', 'hover', or 'hoverIntent'
    // disableHI  : false,    // true disables hoverIntent detection
        onInit      : function(){}, // callback functions
        onBeforeShow: function(){},
        onShow      : function(){},
        onHide      : function(){}
    };
    $.fn.extend({
        hideSuperfishUl : function(){
            var o = sf.op,
                not = (o.retainPath===true) ? o.$path : '';
            o.retainPath = false;
            var $closingLi = $(['li.',o.hoverClass].join(''),this).add(this).not(not);
            var $ul = $closingLi
                    .find('>ul');
            $ul.animate(o.closeAnimation, o.closeSpeed, function() {
              $closingLi.removeClass(o.hoverClass);
        $ul.css('visibility','hidden');
      });
            o.onHide.call($ul);
            return this;
        },
        showSuperfishUl : function(){
            var o = sf.op,
                sh = sf.c.shadowClass+'-off',
                $ul = this.addClass(o.hoverClass)
                    .find('>ul:hidden').css('visibility','visible');
            sf.IE7fix.call($ul);
            o.onBeforeShow.call($ul);
            $ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
            return this;
        }
    });

})(jQuery);

回答by Ronnie

If anyone comes here looking for this answer while using the superfish module in drupal (I am using the drupal 8 module). I didn't modify the superfish library at all. I did the following is in my js file and it seems to be working fine (tested on chrome and firefox).

如果有人在 drupal 中使用 superfish 模块时来这里寻找这个答案(我正在使用 drupal 8 模块)。我根本没有修改 superfish 库。我在我的 js 文件中做了以下操作,它似乎工作正常(在 chrome 和 firefox 上测试)。

The below code disables the menu dropping down on mouseover. When you click the parent menu item the menu drops down and does not actually go to the parent href.

以下代码禁用鼠标悬停时下拉菜单。当您单击父菜单项时,菜单会下拉,实际上不会转到父 href。

$('#superfish-main > li > a.menuparent').on('mouseover click', function(event) {
  return false;
});

I dont use superfish as my mobile menu so I have not tested the above on mobile, but I'd imagine you'll need to do some work to get it how you want it.

我不使用超级鱼作为我的移动菜单,所以我没有在移动设备上测试过上述内容,但我想你需要做一些工作才能得到你想要的。

EDIT

编辑

The above wasn't working on safari for some reason. The below works on chrome, safari and firefox

由于某种原因,上述内容不适用于 safari。以下适用于 chrome、safari 和 firefox

$('#superfish-main > li > a').on('mouseover', function(event) {
  return false;
});
$('#superfish-main > li > a.menuparent').on('click', function(event) {
  // Close any open dropdown menus.
  $.each($(this), function(index, element) {
    $(element).parent().parent().find('li.menuparent > ul').addClass('sf-hidden');
  });
  // Open the clicked dropdown menu.
  $(this).next().removeClass('sf-hidden');
  event.preventDefault();
});