Mit ‘JavaScript’ getaggte Artikel

Superfish Menüs im jQuery noConflict Modus

Montag, 08. Februar 2010

Hatte gerade ein paar Probleme mit Superfish jQuery Menüs und prototype.js auf der selben Webseite. Die Ursache ist, dass sich beide Javascript Bibliotheken um die Variable namens “$” streiten. Um jQuery das auszutreiben, kann man die Bibliothek in den noConflict Modus setzen:

1
jQuery.noConflict();

Nun hat man allerdings das Problem, dass die Superfish Menüs nicht mehr funktionieren, da diese alle noch “$” verwenden. Das muss jetzt durchgängig durch “jQuery” ersetzt werden. Wer Superfish/Supersubs im jQuery noConflict Modus braucht:

superfish.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * 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(jQuery){
    jQuery.fn.superfish = function(op){

        var sf = jQuery.fn.superfish,
            c = sf.c,
            $arrow = jQuery(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
            over = function(){
                var $$ = jQuery(this), menu = getMenu($$);
                clearTimeout(menu.sfTimer);
                $$.showSuperfishUl().siblings().hideSuperfishUl();
            },
            out = function(){
                var $$ = jQuery(this), menu = getMenu($$), o = sf.op;
                clearTimeout(menu.sfTimer);
                menu.sfTimer=setTimeout(function(){
                    o.retainPath=(jQuery.inArray($$[0],o.$path)>-1);
                    $$.hideSuperfishUl();
                    if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length&lt;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 = jQuery.extend({},sf.defaults,op);
            o.$path = jQuery('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
                jQuery(this).addClass([o.hoverClass,c.bcClass].join(' '))
                    .filter('li:has(ul)').removeClass(o.pathClass);
            });
            sf.o[s] = sf.op = o;
           
            jQuery('li:has(ul)',this)[(jQuery.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
                if (o.autoArrows) addArrow( jQuery('>a:first-child',this) );
            })
            .not('.'+c.bcClass)
                .hideSuperfishUl();
           
            var $a = jQuery('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  && !(jQuery.browser.msie && jQuery.browser.version < 7)) menuClasses.push(c.shadowClass);
            jQuery(this).addClass(menuClasses.join(' '));
        });
    };

    var sf = jQuery.fn.superfish;
    sf.o = [];
    sf.op = {};
    sf.IE7fix = function(){
        var o = sf.op;
        if (jQuery.browser.msie && jQuery.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',
        autoArrows  : true,
        dropShadows : true,
        disableHI   : false,        // true disables hoverIntent detection
        onInit      : function(){}, // callback functions
        onBeforeShow: function(){},
        onShow      : function(){},
        onHide      : function(){}
    };
    jQuery.fn.extend({
        hideSuperfishUl : function(){
            var o = sf.op,
                not = (o.retainPath===true) ? o.$path : '';
            o.retainPath = false;
            var $ul = jQuery(['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);

supersubs.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * Supersubs v0.2b - jQuery plugin
 * 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
 *
 *
 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
 * their longest list item children. If you use this, please expect bugs and report them
 * to the jQuery Google Group with the word 'Superfish' in the subject line.
 *
 */


;(function(jQuery){ // $ will refer to jQuery within this closure

    jQuery.fn.supersubs = function(options){
        var opts = jQuery.extend({}, jQuery.fn.supersubs.defaults, options);
        // return original object to support chaining
        return this.each(function() {
            // cache selections
            var $$ = jQuery(this);
            // support metadata
            var o = jQuery.meta ? jQuery.extend({}, opts, $$.data()) : opts;
            // get the font size of menu.
            // .css('fontSize') returns various results cross-browser, so measure an em dash instead
            var fontsize = jQuery('<li id="menu-fontsize">&#8212;</li>').css({
                'padding' : 0,
                'position' : 'absolute',
                'top' : '-999em',
                'width' : 'auto'
            }).appendTo($$).width(); //clientWidth is faster, but was incorrect here
            // remove em dash
            jQuery('#menu-fontsize').remove();
            // cache all ul elements
            $ULs = $$.find('ul');
            // loop through each ul in menu
            $ULs.each(function(i) {
                // cache this ul
                var $ul = $ULs.eq(i);
                // get all (li) children of this ul
                var $LIs = $ul.children();
                // get all anchor grand-children
                var $As = $LIs.children('a');
                // force content to one line and save current float property
                var liFloat = $LIs.css('white-space','nowrap').css('float');
                // remove width restrictions and floats so elements remain vertically stacked
                var emWidth = $ul.add($LIs).add($As).css({
                    'float' : 'none',
                    'width' : 'auto'
                })
                // this ul will now be shrink-wrapped to longest li due to position:absolute
                // so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
                .end().end()[0].clientWidth / fontsize;
                // add more width to ensure lines don't turn over at certain sizes in various browsers
                emWidth += o.extraWidth;
                // restrict to at least minWidth and at most maxWidth
                if (emWidth > o.maxWidth)       { emWidth = o.maxWidth; }
                else if (emWidth < o.minWidth)  { emWidth = o.minWidth; }
                emWidth += 'em';
                // set ul to width in ems
                $ul.css('width',emWidth);
                // restore li floats to avoid IE bugs
                // set li width to full width of this ul
                // revert white-space to normal
                $LIs.css({
                    'float' : liFloat,
                    'width' : '100%',
                    'white-space' : 'normal'
                })
                // update offset position of descendant ul to reflect new width of parent
                .each(function(){
                    var $childUl = jQuery('>ul',this);
                    var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
                    $childUl.css(offsetDirection,emWidth);
                });
            });
           
        });
    };
    // expose defaults
    jQuery.fn.supersubs.defaults = {
        minWidth        : 9,        // requires em unit.
        maxWidth        : 25,       // requires em unit.
        extraWidth      : 0         // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
    };
   
})(jQuery); // plugin code ends