以下代码在包括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
立即不执行。
您的问题似乎是在IOS上,openMenu
首先被调用。
这意味着您正在尝试获取未声明变量的值,从而导致ReferenceError
。
奇怪的是,您可以分配到一个未声明的变量,这隐式地使其成为全局变量。因此,如果首先调用closeMenu
,则首先执行赋值,使变量隐式声明。
正确的解决方案是始终在使用变量之前声明它们。
var lastTimer;
但是事实证明,您倾向于在当前对象上使用属性而不是变量。因此,解决方案是在方法中访问属性...
this.lastTimer
即使未声明该属性,也永远不会抛出ReferenceError
。
我想对此进行说明。使用简单检查检查undefined时,Mobile Safari的宽容度较低。
if variable
当您遇到这种情况时,请使用,
if typeof variable === "undefined"
这里将变量附加到“ this”是一个解决方案,但它只是利用了defineVariable.undefinedProperty返回undefined的事实,而直接引用未定义的变量将在某些运行时环境中导致引用错误。
如果不必要,我建议不要养成附加到“ this”的习惯。
我认为还有一个潜在的问题需要说明。 iOS *上的Safari在缓存和不重新加载代码的干净副本方面可能非常积极。
例如如果您执行了未定义变量的代码的一个版本,则修复了该代码,但是错误仍然在重新加载时显示(即使您关闭浏览器/重新启动电话)
要解决此问题,请点击并按住(也可以长按)地址栏中的重新加载图标,然后弹出带有2个选项的菜单:请求桌面站点和不带内容阻止程序重新加载。选择其中一种会导致Real重新加载所有内容...这可以解决所有缓存的错误代码的问题。
*不只是Safari。 iOS上的Chrome(基于Apple的WebKit版本构建)可能会出现相同的问题。
您的代码中有一个全局变量。不声明var使其变为全局。
尝试更改:
if (lastTimer != null)
to
if (typeof lastTimer !=="undefined" && lastTimer)
如果您坚持要全球化的话。
就我而言,Safari 13无法与ES6 const
配合使用,因此我需要将其替换为var