3

以下代码适用于所有浏览器,包括 Mac 上的 Safari,但 iPhone 上的 Safari 除外。

我有一个可能正在运行的计时器对象,其定义如下:

//delay background change until animation is finished
lastTimer = setTimeout(function () {
  $('#' + targetDiv).removeClass('open');
}, 150);

稍后,我需要检查计时器是否正在运行,如果是,请取消它。这是我正在使用的代码:

if (lastTimer != null) { clearTimeout(lastTimer); }

这是 IOS Safari 生成 JavaScript 错误的地方:

“ReferenceError:找不到变量:lastTimer”。

关于为什么检查 null 不能防止错误的任何想法,就像其他浏览器似乎一样?

以下是回答以下回复的两个相关函数的完整代码:(使用解决方案编辑)

// Class for handling the animations for the drop down menus
var dropDownMenu = {
lastTimer: null,
openMenu: function (targetDiv) {
    if (targetDiv != null) {
        var targetHeight = $('#' + targetDiv).height();
        $('#' + targetDiv).stop(true); //stop an previous animations and clear queue
        if (this.lastTimer != null) { clearTimeout(this.lastTimer); } //stop possible pending timer to prevent background change
        console.log("testing b");
        $('#mainNavigation #dropDownMenu ul').removeClass('open'); // make sure all closed menus show corrent bgd
        $('#' + targetDiv).animate({
            bottom: -(targetHeight + 30)
        }, 200, 'swing');
        $('#' + targetDiv).addClass('open');
    }

},
closeMenu: function (targetDiv) {
    if (targetDiv != null) {
        $('#' + targetDiv).stop(true); //stop an previous animations and clear queue
        $('#' + targetDiv).animate({
            bottom: 0
        }, 200, 'swing');
        //delay background change until animation is finished
        this.lastTimer = setTimeout(function () {
            $('#' + targetDiv).removeClass('open');
        }, 150);
    }
}
}

当 iOS 中发生错误时,执行停止并且我的测试console.log之后立即不会执行。

4

5 回答 5

10

我想插话解释一下。使用简单检查检查未定义时,Mobile Safari 的宽容度较低,

if variable

当您遇到这样的情况时,请使用,

if typeof variable === "undefined"

将变量附加到“this”是这里的一种解决方案,但它只是利用了definedVariable.undefinedProperty 返回未定义的事实,而直接引用未定义的变量会在某些运行时环境中导致引用错误。

如果没有必要,我建议不要养成依附于“这个”的习惯。

于 2012-06-13T21:04:55.653 回答
1

您的问题似乎是在IOS上,openMenu首先被调用。

这意味着您正在尝试获取未声明变量的值,从而导致ReferenceError.

奇怪的是,您可以分配给未声明的变量,这隐含地使其成为全局变量。因此,如果closeMenu首先调用,则首先进行赋值,从而隐式声明变量。

正确的解决方案是始终在使用变量之前声明它们。

var lastTimer;

但事实证明,您更喜欢在当前对象上使用属性而不是变量。因此,解决方案是访问方法中的属性......

this.lastTimer

ReferenceError即使未声明该属性,这也永远不会抛出 a 。

于 2012-06-13T19:41:03.233 回答
1

我认为还有一个潜在的问题需要说明。iOS* 上的 Safari 可以非常积极地缓存而不是重新加载代码的干净副本。

例如,如果您在没有定义变量的情况下执行了一个版本的代码,然后修复了代码,但重新加载时错误继续显示(即使您关闭浏览器/重新启动手机)

要解决此问题,请点击并按住(又名长按)地址栏中的重新加载图标,然后会弹出一个菜单,其中包含 2 个选项Request Desktop SiteReload without Content Blockers。选择其中任何一个都会导致所有内容的真正重新加载......这解决了任何缓存错误代码的问题。

*不仅仅是Safari。iOS 上的 Chrome(基于 Apple 的 WebKit 版本)可能会出现同样的问题。

于 2018-07-30T13:53:54.460 回答
0

您的代码中有一个全局变量。不声明 var 使其成为全局变量。

尝试改变:

if (lastTimer != null)

if (typeof lastTimer !=="undefined" && lastTimer)

如果你坚持它是全球性的。

于 2012-06-13T19:29:46.453 回答
0

就我而言,Safari 13 不适用于 ES6,const因此我需要将其替换为var

于 2020-03-04T11:00:15.603 回答