简体   繁体   English

IE移动样式菜单问题JQuery

[英]IE Mobile-Style Menu Issue JQuery

I have the following JQuery: 我有以下JQuery:

function Dropdown(opts) {
    this.opts = opts;
    this.trigger = $(opts.trigger);
    this.menu = $(opts.menu);

    this.hide = this.hide.bind(this);
    this.hideCallbacks = [];
    this.onHide = this.hideCallbacks.push.bind(this.hideCallbacks);
}

Dropdown.prototype.alignMenu = function () {
    if (!this.opts.position) return;

    var pos = this.trigger.position();

    var x = pos.left;
    var y = pos.top;

    var current = this.opts.position === 'activeItem' && this.menu.find('.active');
    if (!current.length) current = this.menu.children(':first');
    y -= current.position().top + (current.outerHeight(true) - this.trigger.outerHeight(true)) / 2;

    this.menu.css({ top: y, left: x });
};

Dropdown.prototype.show = function () {
    this.menu.show();
    this.alignMenu();
    this.menu.find('.active').focus();

    var doc = $(document);

    // If a dropdown trigger is only visible on :hover, hide the menu when the trigger vanishes.
    this.activeBind(doc, 'mouseout', function (e) {
        if (!$.contains(e.target, this.trigger[0])
            && e.target !== this.menu[0] && !$.contains(this.menu[0], e.target))    // Only catch mouseouts on parents of the trigger
            return;
        if (this.trigger.css('visibility') === 'hidden' || this.trigger.is(':hidden'))
            this.hide();
    }.bind(this));

        this.activeBind(this.menu.children(), 'click', this.hide);

    //Prevent the handler that opened the menu in the first place from opening it again.
    // Wait until this event finishes, in case we were shown before bubbling up to here.
    setTimeout(function () {
        this.activeBind(this.trigger, 'click', function (e) {
            e.stopImmediatePropagation();
            this.hide();
            return false;
        }.bind(this));

        // Hide on outer mouse click
        this.activeBind(doc, 'click', function (e) {
            if (e.target === this.menu[0] || $.contains(this.menu[0], e.target))
                return; // Ignore clicks inside the menu
            this.hide();
            return false;
        }.bind(this));
    }.bind(this), 1);

    // Make keyboard start from hovered item
    this.activeBind(this.menu.children(), 'mouseenter', function (e) {
        e.target.focus();
    }.bind(this));
    // Allow navigation via keyboard
    this.activeBind(doc, 'keydown', function (e) {
        if (e.keyCode === 27) this.hide();
        if (!/(38|40)/.test(e.keyCode)) return;

        var items = this.menu.children();

        if (!items.length) return;

        var index = items.index(document.activeElement || items.filter('.active'));

        if (e.keyCode === 38 && index > 0) index--;                               // up
        if (e.keyCode === 40 && index < items.length - 1) index++;                // down
        if (index < 0) index = 0;

        items.eq(index).focus();

        return false;
    }.bind(this));
};

Dropdown.prototype.hide = function () {
    this.menu.hide();
    this.hideCallbacks.forEach(Function.call.bind(Function.call));
};

Dropdown.prototype.activeBind = function (elem, eventName, handler) {
    elem.bind(eventName, handler);
    this.hideCallbacks.push(function () { elem.unbind(eventName, handler); });
};

$(document).on('click', '.UserTrigger', function () {
    var menu = $('#userMenu'), trigger = $(this);

    var header = $(this).closest('header');
    header.addClass("MenuOpen");

    var dropdown = new Dropdown({ trigger: trigger, menu: menu });
    dropdown.onHide(function () { header.removeClass("MenuOpen"); });
    setScrollDisabled(true, true);
    dropdown.onHide(function () { setScrollDisabled(false, true); });

    dropdown.show();

    // automatically stops propagation
    return false;
});

function setScrollDisabled(value, mobileOnly) {
    var className = mobileOnly ? "OverlaidBase-Mobile" : "OverlaidBase";
    if (value) {
        $('.BaseContent').css('top', -$(window).scrollTop()).addClass(className);
        $(window).scrollTop($(window).scrollTop());
    } else {
        var y = parseInt($('.BaseContent').css('top'), 10);
        $('.BaseContent').removeClass(className);
        setTimeout(function () { $(window).scrollTop(-y); }, 0);
    }
}

However in IE i get the following js error: 但是在IE中,我收到以下js错误:

Webpage error details
Message: Object doesn't support this property or method
Line: 387
Char: 2
Code: 0
URI: http://new.dpwebdev.co.uk/new-brand/business-sites/dorset-dub-fest/js/dorset-core.js

Line 387 is this: this.hideCallbacks.forEach(Function.call.bind(Function.call)); 第387行是这样的: this.hideCallbacks.forEach(Function.call.bind(Function.call));

What is the issue, and how can I fix it? 有什么问题,我该如何解决? Any Ideas SO? 有什么想法吗?

Thanks to @varinder, this is the solution: 感谢@varinder,这是解决方案:

By adding this at the top of the script: 通过在脚本顶部添加以下内容:

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisArg */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
      if (i in t)
        fun.call(thisArg, t[i], i, t);
    }
  };
}

It resolved the issue, for anyone wanting to know the issue is caused because Internet Explorer doesn't support "for each" loops. 它解决了该问题,对于任何想知道此问题是由于Internet Explorer不支持“ for each”循环而引起的。

This snippet is from the MDN Docs and is from ECMA-262. 该摘录来自MDN文档和ECMA-262。 The Snippet is the equivalent to the ECMA-262 foreach function. 该代码段等效于ECMA-262 foreach功能。

See Here for more info. 有关更多信息,请参见此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM