PageSourceSearch

https://www.norsknum.org/wp-content/plugins/megamenu/js/maxmegamenu.js?ver=2.5.3.2

js norsknum.org collected 2026-09-25 06:54:08 UTC 20,858 bytes, 516 lines download raw bytes

1/*jslint browser: true, white: true, this: true */
2/*global console,jQuery,megamenu,window,navigator*/
3
4/*! Max Mega Menu jQuery Plugin */
5(function($) {
6    "use strict";
7
8    $.maxmegamenu = function(menu, options) {
9        var plugin = this;
10        var $menu = $(menu);
11        var $toggle_bar = $menu.siblings(".mega-menu-toggle");
12
13        var defaults = {
14            event: $menu.attr("data-event"),
15            effect: $menu.attr("data-effect"),
16            effect_speed: parseInt($menu.attr("data-effect-speed")),
17            effect_mobile: $menu.attr("data-effect-mobile"),
18            effect_speed_mobile: parseInt($menu.attr("data-effect-speed-mobile")),
19            panel_width: $menu.attr("data-panel-width"),
20            panel_inner_width: $menu.attr("data-panel-inner-width"),
21            mobile_force_width: $menu.attr("data-mobile-force-width"),
22            second_click: $menu.attr("data-second-click"),
23            vertical_behaviour: $menu.attr("data-vertical-behaviour"),
24            document_click: $menu.attr("data-document-click"),
25            breakpoint: $menu.attr("data-breakpoint"),
26            unbind_events: $menu.attr("data-unbind")
27        };
28
29        plugin.settings = {};
30
31        var items_with_submenus = $("li.mega-menu-megamenu.mega-menu-item-has-children," +
32                                    "li.mega-menu-flyout.mega-menu-item-has-children," +
33                                    "li.mega-menu-tabbed > ul.mega-sub-menu > li.mega-menu-item-has-children," +
34                                    "li.mega-menu-flyout li.mega-menu-item-has-children", menu);
35
36        plugin.hidePanel = function(anchor, immediate) {
37
38            anchor.parent().triggerHandler("before_close_panel");
39
40            if ( (!immediate && plugin.settings.effect == 'slide') || (plugin.isMobileView() && plugin.settings.effect_mobile == 'slide') ) {
41                var speed = plugin.isMobileView() ? plugin.settings.effect_speed_mobile : plugin.settings.effect_speed;
42
43                anchor.siblings(".mega-sub-menu").animate({'height':'hide', 'paddingTop':'hide', 'paddingBottom':'hide', 'minHeight':'hide'}, speed, function() {
44                    anchor.siblings(".mega-sub-menu").css("display", "");
45                    anchor.parent().removeClass("mega-toggle-on").triggerHandler("close_panel");
46                });
47
48                return;
49            }
50
51            if (immediate) {
52                anchor.siblings(".mega-sub-menu").css("display", "none").delay(plugin.settings.effect_speed).queue(function(){
53                    $(this).css("display", "").dequeue();
54                });
55            }
56
57            // pause video widget videos
58            anchor.siblings(".mega-sub-menu").find('.widget_media_video video').each(function() {
59                this.player.pause();
60            });
61
62            anchor.parent().removeClass("mega-toggle-on").triggerHandler("close_panel");
63            plugin.addAnimatingClass(anchor.parent());
64        };
65
66        plugin.addAnimatingClass = function(element) {
67            if (plugin.settings.effect === "disabled") {
68                return;
69            }
70
71            $(".mega-animating").removeClass("mega-animating");
72
73            var timeout = plugin.settings.effect_speed + parseInt(megamenu.timeout, 10);
74
75            element.addClass("mega-animating");
76
77            setTimeout(function() {
78               element.removeClass("mega-animating");
79            }, timeout );
80        };
81
82        plugin.hideAllPanels = function() {
83            $(".mega-toggle-on > a.mega-menu-link", $menu).each(function() {
84                plugin.hidePanel($(this), false);
85            });
86        };
87
88        plugin.hideSiblingPanels = function(anchor, immediate) {
89            anchor.parent().parent().find(".mega-toggle-on").children("a.mega-menu-link").each(function() { // all open children of open siblings
90                plugin.hidePanel($(this), immediate);
91            });
92        };
93
94        plugin.isDesktopView = function() {
95            return Math.max(window.outerWidth, $(window).width()) > plugin.settings.breakpoint; // account for scrollbars
96        };
97
98        plugin.isMobileView = function() {
99            return !plugin.isDesktopView();
100        };
101
102        plugin.showPanel = function(anchor) {
103            anchor.parent().triggerHandler("before_open_panel");
104
105            $(".mega-animating").removeClass("mega-animating");
106
107            if (plugin.isMobileView() && anchor.parent().hasClass("mega-hide-sub-menu-on-mobile")) {
108                return;
109            }
110
111            if (plugin.isDesktopView() && ($menu.hasClass("mega-menu-horizontal") || $menu.hasClass("mega-menu-vertical"))) {
112                plugin.hideSiblingPanels(anchor, true);
113            }
114
115            if ((plugin.isMobileView() && $menu.hasClass("mega-keyboard-navigation")) || plugin.settings.vertical_behaviour === "accordion") {
116                plugin.hideSiblingPanels(anchor, false);
117            }
118
119            plugin.calculateDynamicSubmenuWidths(anchor);
120
121            // apply jQuery transition (only if the effect is set to "slide", other transitions are CSS based)
122            if ( plugin.settings.effect == "slide" || plugin.isMobileView() && plugin.settings.effect_mobile == 'slide') {
123                var speed = plugin.isMobileView() ? plugin.settings.effect_speed_mobile : plugin.settings.effect_speed;
124
125                anchor.siblings(".mega-sub-menu").css("display", "none").animate({'height':'show', 'paddingTop':'show', 'paddingBottom':'show', 'minHeight':'show'}, speed, function() {
126                    $(this).css("display", "");
127                });
128            }
129
130            anchor.parent().addClass("mega-toggle-on").triggerHandler("open_panel");
131        };
132
133        plugin.calculateDynamicSubmenuWidths = function(anchor) {
134            // apply dynamic width and sub menu position (only to top level mega menus)
135            if (anchor.parent().hasClass("mega-menu-megamenu") && anchor.parent().parent().hasClass("max-mega-menu") && plugin.settings.panel_width && $(plugin.settings.panel_width).length > 0) {
136                if (plugin.isDesktopView()) {
137                    var submenu_offset = $menu.offset();
138                    var target_offset = $(plugin.settings.panel_width).offset();
139
140                    anchor.siblings(".mega-sub-menu").css({
141                        width: $(plugin.settings.panel_width).outerWidth(),
142                        left: (target_offset.left - submenu_offset.left) + "px"
143                    });
144                } else {
145                    anchor.siblings(".mega-sub-menu").css({
146                        width: "",
147                        left: ""
148                    });
149                }
150            }
151
152            // apply inner width to sub menu by adding padding to the left and right of the mega menu
153            if (anchor.parent().hasClass("mega-menu-megamenu") && anchor.parent().parent().hasClass("max-mega-menu") && plugin.settings.panel_inner_width && $(plugin.settings.panel_inner_width).length > 0) {
154                var target_width = 0;
155
156                if ($(plugin.settings.panel_inner_width).length) {
157                    // jQuery selector
158                    target_width = parseInt($(plugin.settings.panel_inner_width).width(), 10);
159                } else {
160                    // we"re using a pixel width
161                    target_width = parseInt(plugin.settings.panel_inner_width, 10);
162                }
163
164                var submenu_width = parseInt(anchor.siblings(".mega-sub-menu").innerWidth(), 10);
165
166                if (plugin.isDesktopView() && target_width > 0 && target_width < submenu_width) {
167                    anchor.siblings(".mega-sub-menu").css({
168                        "paddingLeft": (submenu_width - target_width) / 2 + "px",
169                        "paddingRight": (submenu_width - target_width) / 2 + "px"
170                    });
171                } else {
172                    anchor.siblings(".mega-sub-menu").css({
173                        "paddingLeft": "",
174                        "paddingRight": ""
175                    });
176                }
177            }
178        }
179
180        var bindClickEvents = function() {
181            var dragging = false;
182
183            $(document).on({
184                "touchmove": function(e) { dragging = true; },
185                "touchstart": function(e) { dragging = false; }
186            });
187
188            $(document).on("click touchend", function(e) { // hide menu when clicked away from
189                if (!dragging && plugin.settings.document_click === "collapse" && ! $(e.target).closest(".max-mega-menu li").length && ! $(e.target).closest(".mega-menu-toggle").length ) {
190                    plugin.hideAllPanels();
191                    plugin.hideMobileMenu();
192                }
193                dragging = false;
194            });
195
196            $("> a.mega-menu-link", items_with_submenus).on("touchend.megamenu", function(e) {
197                plugin.unbindHoverEvents();
198                plugin.unbindHoverIntentEvents();
199            });
200
201            $("> a.mega-menu-link", items_with_submenus).on("click.megamenu", function(e) {
202                if (plugin.isDesktopView() && $(this).parent().hasClass("mega-toggle-on") && $(this).parent().parent().parent().hasClass("mega-menu-tabbed") ) {
203                    if (plugin.settings.second_click === "go") {
204                        return;
205                    } else {
206                        e.preventDefault();
207                        return;
208                    }
209                }
210                if (dragging) {
211                    return;
212                }
213                if (plugin.isMobileView() && $(this).parent().hasClass("mega-hide-sub-menu-on-mobile")) {
214                    return; // allow all clicks on parent items when sub menu is hidden on mobile
215                }
216                if ((plugin.settings.second_click === "go" || $(this).parent().hasClass("mega-click-click-go")) && $(this).attr('href') !== undefined) { // check for second click
217                    if (!$(this).parent().hasClass("mega-toggle-on")) {
218                        e.preventDefault();
219                        plugin.showPanel($(this));
220                    }
221                } else {
222                    e.preventDefault();
223
224                    if ($(this).parent().hasClass("mega-toggle-on")) {
225                        plugin.hidePanel($(this), false);
226                    } else {
227                        plugin.showPanel($(this));
228                    }
229                }
230            });
231        };
232
233        var bindHoverEvents = function() {
234            items_with_submenus.on({
235                "mouseenter.megamenu" : function() {
236                    plugin.unbindClickEvents();
237                    if (! $(this).hasClass("mega-toggle-on")) {
238                        plugin.showPanel($(this).children("a.mega-menu-link"));
239                    }
240                },
241                "mouseleave.megamenu" : function() {
242                    if ($(this).hasClass("mega-toggle-on") && ! $(this).hasClass("mega-disable-collapse") && ! $(this).parent().parent().hasClass("mega-menu-tabbed")) {
243                        plugin.hidePanel($(this).children("a.mega-menu-link"), false);
244                    }
245                }
246            });
247        };
248
249        var bindHoverIntentEvents = function() {
250            items_with_submenus.hoverIntent({
251                over: function () {
252                    plugin.unbindClickEvents();
253                    if (! $(this).hasClass("mega-toggle-on")) {
254                        plugin.showPanel($(this).children("a.mega-menu-link"));
255                    }
256                },
257                out: function () {
258                    if ($(this).hasClass("mega-toggle-on") && ! $(this).hasClass("mega-disable-collapse") && ! $(this).parent().parent().hasClass("mega-menu-tabbed")) {
259                        plugin.hidePanel($(this).children("a.mega-menu-link"), false);
260                    }
261                },
262                timeout: megamenu.timeout,
263                interval: megamenu.interval
264            });
265        };
266
267        var bindKeyboardEvents = function() {
268            var tab_key = 9;
269            var escape_key = 27;
270
271            $("body").on("keyup", function(e) {
272                var keyCode = e.keyCode || e.which;
273
274                if (keyCode === escape_key) {
275                    $menu.parent().removeClass("mega-keyboard-navigation");
276                    plugin.hideAllPanels();
277                }
278
279                if ( $menu.parent().hasClass("mega-keyboard-navigation") && ! ( $(e.target).closest(".max-mega-menu li").length || $(e.target).closest(".mega-menu-toggle").length ) ) {
280                    $menu.parent().removeClass("mega-keyboard-navigation");
281                    plugin.hideAllPanels();
282
283                    if ( plugin.isMobileView() ) {
284                        plugin.hideMobileMenu();
285                    }
286                }
287            });
288
289            $menu.parent().on("keyup", function(e) {
290                var keyCode = e.keyCode || e.which;
291                var active_link = $(e.target);
292
293                if (keyCode === tab_key) {
294                    $menu.parent().addClass("mega-keyboard-navigation");
295
296                    if ( active_link.parent().is(items_with_submenus) ) {
297                        plugin.showPanel(active_link);
298                    } else {
299                        plugin.hideSiblingPanels(active_link);
300                    }
301
302                    if ( active_link.hasClass("mega-menu-toggle") ) {
303                        plugin.showMobileMenu();
304                    }
305                }
306            });
307        };
308
309        plugin.unbindAllEvents = function() {
310            $("ul.mega-sub-menu, li.mega-menu-item, li.mega-menu-row, li.mega-menu-column, a.mega-menu-link, span.mega-indicator", menu).off().unbind();
311        };
312
313        plugin.unbindClickEvents = function() {
314            $("> a.mega-menu-link", items_with_submenus).off("click.megamenu touchend.megamenu");
315        };
316
317        plugin.unbindHoverEvents = function() {
318            items_with_submenus.unbind("mouseenter.megamenu mouseleave.megamenu");
319        };
320
321        plugin.unbindHoverIntentEvents = function() {
322            items_with_submenus.unbind("mouseenter mouseleave").removeProp('hoverIntent_t').removeProp('hoverIntent_s'); // hoverintent does not allow namespaced events
323        };
324
325        plugin.unbindMegaMenuEvents = function() {
326            if (plugin.settings.event === "hover_intent") {
327                plugin.unbindHoverIntentEvents();
328            }
329
330            if (plugin.settings.event === "hover") {
331                plugin.unbindHoverEvents();
332            }
333
334            plugin.unbindClickEvents();
335        }
336
337        plugin.bindMegaMenuEvents = function() {
338            if (plugin.isDesktopView() && plugin.settings.event === "hover_intent") {
339                bindHoverIntentEvents();
340            }
341
342            if (plugin.isDesktopView() && plugin.settings.event === "hover") {
343                bindHoverEvents();
344            }
345
346            bindClickEvents(); // always bind click events for touch screen devices
347            bindKeyboardEvents();
348        };
349
350        plugin.monitorView = function() {
351            if (plugin.isDesktopView()) {
352                $menu.data("view", "desktop");
353            } else {
354                $menu.data("view", "mobile");
355                plugin.switchToMobile();
356            }
357
358            plugin.checkWidth();
359
360            $(window).resize(function() {
361                plugin.checkWidth();
362            });
363        };
364
365        plugin.checkWidth = function() {
366            if ( plugin.isMobileView() && $menu.data("view") === "desktop" ) {
367                $menu.data("view", "mobile");
368                plugin.switchToMobile();
369            }
370
371            if ( plugin.isDesktopView() && $menu.data("view") === "mobile" ) {
372                $menu.data("view", "desktop");
373                plugin.switchToDesktop();
374            }
375
376            plugin.calculateDynamicSubmenuWidths($("> li.mega-menu-megamenu > a.mega-menu-link", $menu));
377        };
378
379        plugin.reverseRightAlignedItems = function() {
380            if ( ! $('body').hasClass('rtl') ) {
381                $menu.append($menu.children("li.mega-item-align-right").get().reverse());
382            }
383        };
384
385        plugin.addClearClassesToMobileItems = function() {
386            $(".mega-menu-row", $menu).each(function() {
387                $("> .mega-sub-menu > .mega-menu-column:not(.mega-hide-on-mobile)", $(this)).filter(":even").addClass('mega-menu-clear'); // :even is 0 based
388            });
389        }
390
391        plugin.switchToMobile = function() {
392            plugin.unbindMegaMenuEvents();
393            plugin.bindMegaMenuEvents();
394            plugin.reverseRightAlignedItems();
395            plugin.addClearClassesToMobileItems();
396            plugin.hideAllPanels();
397        };
398
399        plugin.switchToDesktop = function() {
400            plugin.unbindMegaMenuEvents();
401            plugin.bindMegaMenuEvents();
402            plugin.reverseRightAlignedItems();
403            plugin.hideAllPanels();
404
405            $menu.css({
406                width: '',
407                left: '',
408                display: ''
409            });
410
411            $toggle_bar.removeClass('mega-menu-open');
412        };
413
414        plugin.initToggleBar = function() {
415            // mobile menu
416            $toggle_bar.on("click", function(e) {
417                if ( $(e.target).is(".mega-menu-toggle, .mega-menu-toggle-block, .mega-menu-toggle-animated-block, .mega-menu-toggle-animated-block *, .mega-toggle-blocks-left, .mega-toggle-blocks-center, .mega-toggle-blocks-right, .mega-toggle-label, .mega-toggle-label span") ) {
418                    if ($(this).hasClass("mega-menu-open")) {
419                        plugin.hideMobileMenu();
420                    } else {
421                        plugin.showMobileMenu();
422                    }
423                }
424            });
425        };
426
427        plugin.hideMobileMenu = function() {
428            if ( ! $toggle_bar.is(":visible")) {
429                return;
430            }
431
432            $('body').removeClass($menu.attr('id') + "-mobile-open");
433
434            if (plugin.settings.effect_mobile == 'slide') {
435                $menu.animate({'height':'hide'}, plugin.settings.effect_speed_mobile, function() {
436                    $menu.css({
437                        width: '',
438                        left: '',
439                        display: ''
440                    });
441                });
442            }
443
444            $toggle_bar.removeClass("mega-menu-open");
445        };
446
447        plugin.showMobileMenu = function() {
448            if ( ! $toggle_bar.is(":visible")) {
449                return;
450            }
451
452            $('body').addClass($menu.attr('id') + "-mobile-open");
453
454            plugin.toggleBarForceWidth();
455
456            if (plugin.settings.effect_mobile == 'slide') {
457                $menu.animate({'height':'show'}, plugin.settings.effect_speed_mobile);
458            }
459
460            $toggle_bar.addClass("mega-menu-open");
461        };
462
463        plugin.toggleBarForceWidth = function() {
464            if ($(plugin.settings.mobile_force_width).length) {
465                var submenu_offset = $toggle_bar.offset();
466                var target_offset = $(plugin.settings.mobile_force_width).offset();
467
468                $menu.css({
469                    width: $(plugin.settings.mobile_force_width).outerWidth(),
470                    left: (target_offset.left - submenu_offset.left) + "px"
471                });
472            }
473        };
474
475        plugin.init = function() {
476            $menu.triggerHandler("before_mega_menu_init");
477            plugin.settings = $.extend({}, defaults, options);
478            $menu.removeClass("mega-no-js");
479
480            plugin.initToggleBar();
481            
482            if (plugin.settings.unbind_events == 'true') {
483                plugin.unbindAllEvents();
484            }
485
486            $("span.mega-indicator", $menu).on('click', function(e) {
487                e.preventDefault();
488                e.stopPropagation();
489                plugin.hidePanel($(this).parent(), false);
490            });
491
492            $(window).on("load", function() {
493                plugin.calculateDynamicSubmenuWidths($("> li.mega-menu-megamenu > a.mega-menu-link", $menu));
494            });
495
496            plugin.bindMegaMenuEvents();
497            plugin.monitorView();
498            $menu.triggerHandler("after_mega_menu_init");
499        };
500
501        plugin.init();
502    };
503
504    $.fn.maxmegamenu = function(options) {
505        return this.each(function() {
506            if (undefined === $(this).data("maxmegamenu")) {
507                var plugin = new $.maxmegamenu(this, options);
508                $(this).data("maxmegamenu", plugin);
509            }
510        });
511    };
512
513    $(function() {
514        $('.max-mega-menu').maxmegamenu();
515    });
516})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.