如何通过单击而不是悬停来打开 Superfish jQuery 菜单?

发布于 2024-12-03 05:10:30 字数 275 浏览 1 评论 0原文

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

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

https://gist.github.com/917446

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

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

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.

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不知在何时 2024-12-10 05:10:30

Karl 在 GitHub 上发布了一个快速更新来帮助我解决问题:https://gist.github.com/652684对我来说不太管用。

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

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

已更新..以防链接失效..

/*
 * 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,'"> »</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);

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

Grab my working code from the below link.

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,'"> »</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);
依 靠 2024-12-10 05:10:30

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

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

为此:

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

用于单击菜单的完整 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,'"> »</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);

Changing this line (line 21, over function):

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

To this:

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

Full superfish code for clicking the menu:

/*
 * 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,'"> »</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);
黯然 2024-12-10 05:10:30

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

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

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

我不使用 superfish 作为我的移动菜单,因此我没有在移动设备上测试上述内容,但我想您需要做一些工作才能按照您想要的方式获得它。

编辑

由于某种原因,以上内容不适用于 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();
});

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).

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.

$('#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

$('#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();
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文