在 setInterval 中为匿名函数提供多个参数
Providing multiple arguments to an anonymous function in setInterval
我不确定之前是否有人问过这个 Javascript 问题 - 我找不到它,但如果我错过了,我很抱歉。
我正在尝试创建一个带有复选框的页面,这些复选框会淡出 in/out 相应的图像。淡出会持续1秒,每100ms,图像的不透明度增加或减少0.1;当不透明度达到 0 或 1 时,setInterval 调用将停止。但是,我不确定如何将参数传递给匿名函数调用。我试图传递两个变量 - 第一个是图像的 ID,从复选框值获得,另一个是复选框是否被选中,以便函数知道是淡入还是淡出。
但是,我 运行 遇到了代码的问题(见下文),我认为这是由于 setInterval 函数调用中的变量范围所致 - 这就是我询问的原因将多个参数传递到调用中。
例如:
<form action="">
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>
而函数如下(到目前为止)
function handleClick(cb)
{
var myInterval = setInterval(function ()
{
if (cb.checked) // tick box checked - fade in.
{
document.getElementById( cb.value ).style.opacity+=0.1; // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( cb.value ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( cb.val ).style.opacity-=0.1;
if( document.getElementById( cb.val ).style.opacity<0 )
{
document.getElementById( cb.val ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100);
}
图像的名称如下:
<img id="aurora" src="aurora.png" />
您可以使用setInterval(function(arg1, arg2, ..){...}, intervalTime, arg1, arg2,...)
函数的可选参数
function handleClick(cb)
{
var myInterval = setInterval(function (checked, imgId)
{
if (checked) // tick box checked - fade in.
{
document.getElementById( imgId ).style.opacity+=0.1; // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( imgId ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( imgId ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( imgId ).style.opacity-=0.1;
if( document.getElementById( imgId ).style.opacity<0 )
{
document.getElementById( imgId ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100, cb.checked, cb.value);
}
您可以只在现有代码中使用 cb.checked,但要按要求回答您的问题:使用 setInterval 和 setTimeout,您只需使用闭包功能将变量传入,因为来自外部作用域的值 (功能)在评估时可供您使用。在非常简单的级别上,您可以执行以下操作:
function myTimeoutClosure(greeting, subject) {
return function() {
console.log(greeting + " " + subject);
};
}
// ...
setTimeout(myTimeoutClosure("Hello", "World"), 500);
这是一个有效的示例,您的方法可能会导致人们反复单击复选框并在彼此之上堆叠一堆间隔时出现一些问题。在这种情况下,您有一个函数,它通过超时调用自身并逐步完成转换,而不是完全依赖间隔。
function fadeElement(elem, increment) {
elem.style.opacity = parseFloat(elem.style.opacity) + increment;
if (elem.style.opacity >= 1) {
elem.style.opacity = 1
} else if (elem.style.opacity <= 0) {
elem.style.opacity = 0
} else {
clearTimeout(elem.getAttribute('data-timeout'))
elem.setAttribute('data-timeout', setTimeout(function() {
fadeElement(elem, increment)
}, 100))
}
}
function handleClick(cb) {
var chkbox = document.getElementById(cb.value);
var direction = cb.checked ? 0.1 : -0.1;
fadeElement(chkbox, direction)
}
<form action="">
<input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>
<p id="aurora" style="opacity:1">Aurora</p>
<p id="mainindex" style="opacity:1">Main Index</p>
举个例子。我希望这就是您要找的。请告诉我。
<form action="">
<input type="checkbox" class='imageSelect' name="skymap" value="aurora">Aurora
<input type="checkbox" class= 'imageSelect' name="skymap" value="mainindex">Main Index
</form>
<div id="aurora" style="background:yellow; width:150px; height:40px; float:left; display:none;">Aurora Image </div>
<div id="mainindex" style="background:blue; width:150px; height:40px;float:left; display:none;">MainIndex Image </div>
JS:
function CheckBoxClick(){
$(".imageSelect").click(function(){
/*if(this.checked){
$("#"+$(this).val()+" ").fadeIn();
}else{
$("#"+$(this).val()+" ").fadeOut();
}*/
$("#"+$(this).val()+" ").toggle(this.checked)
});
};
淡入淡出效果看起来更好,但使用与否由您决定,两者都有效。这是要玩的代码:https://jsfiddle.net/dzgppqap/
PD:记得在页面准备好时添加事件:
$(document).ready(CheckBoxClick());
你运行遇到了一个棘手的问题。
首先,您在 else 部分写了 "cb.val" 而不是 "cb.value"
其次,对象"cb"的不透明度属性是字符串类型。 -= 操作将不透明度值转换为数字,因为您不能对字符串执行减号操作。相反,+= 操作将数字 (0.1) 转换为字符串并添加到不透明度字符串的末尾(例如,如果不透明度为 0.1,则结果将为“0.10.1”)。由于此值无效,它将被设置为最后一个有效值并且您陷入循环
这是一个工作示例:
function handleClick(cb)
{
var myInterval = setInterval(function ()
{
if (cb.checked) // tick box checked - fade in.
{
document.getElementById( cb.value ).style.opacity = parseFloat(document.getElementById( cb.value ).style.opacity) + 0.1 // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( cb.value ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( cb.value ).style.opacity-=0.1;
if( document.getElementById( cb.value ).style.opacity<0 )
{
document.getElementById( cb.value ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100);
}
您可能 运行 遇到的另一个问题是,不透明度 属性 不是默认设置的(或者至少您不能确定)。所以第一次,opacity = "", 空字符串。这将导致您的动画跳跃。如果检测到空字符串,请务必初始化不透明度。
我不确定之前是否有人问过这个 Javascript 问题 - 我找不到它,但如果我错过了,我很抱歉。
我正在尝试创建一个带有复选框的页面,这些复选框会淡出 in/out 相应的图像。淡出会持续1秒,每100ms,图像的不透明度增加或减少0.1;当不透明度达到 0 或 1 时,setInterval 调用将停止。但是,我不确定如何将参数传递给匿名函数调用。我试图传递两个变量 - 第一个是图像的 ID,从复选框值获得,另一个是复选框是否被选中,以便函数知道是淡入还是淡出。
但是,我 运行 遇到了代码的问题(见下文),我认为这是由于 setInterval 函数调用中的变量范围所致 - 这就是我询问的原因将多个参数传递到调用中。
例如:
<form action="">
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>
而函数如下(到目前为止)
function handleClick(cb)
{
var myInterval = setInterval(function ()
{
if (cb.checked) // tick box checked - fade in.
{
document.getElementById( cb.value ).style.opacity+=0.1; // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( cb.value ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( cb.val ).style.opacity-=0.1;
if( document.getElementById( cb.val ).style.opacity<0 )
{
document.getElementById( cb.val ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100);
}
图像的名称如下:
<img id="aurora" src="aurora.png" />
您可以使用setInterval(function(arg1, arg2, ..){...}, intervalTime, arg1, arg2,...)
函数的可选参数
function handleClick(cb)
{
var myInterval = setInterval(function (checked, imgId)
{
if (checked) // tick box checked - fade in.
{
document.getElementById( imgId ).style.opacity+=0.1; // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( imgId ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( imgId ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( imgId ).style.opacity-=0.1;
if( document.getElementById( imgId ).style.opacity<0 )
{
document.getElementById( imgId ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100, cb.checked, cb.value);
}
您可以只在现有代码中使用 cb.checked,但要按要求回答您的问题:使用 setInterval 和 setTimeout,您只需使用闭包功能将变量传入,因为来自外部作用域的值 (功能)在评估时可供您使用。在非常简单的级别上,您可以执行以下操作:
function myTimeoutClosure(greeting, subject) {
return function() {
console.log(greeting + " " + subject);
};
}
// ...
setTimeout(myTimeoutClosure("Hello", "World"), 500);
这是一个有效的示例,您的方法可能会导致人们反复单击复选框并在彼此之上堆叠一堆间隔时出现一些问题。在这种情况下,您有一个函数,它通过超时调用自身并逐步完成转换,而不是完全依赖间隔。
function fadeElement(elem, increment) {
elem.style.opacity = parseFloat(elem.style.opacity) + increment;
if (elem.style.opacity >= 1) {
elem.style.opacity = 1
} else if (elem.style.opacity <= 0) {
elem.style.opacity = 0
} else {
clearTimeout(elem.getAttribute('data-timeout'))
elem.setAttribute('data-timeout', setTimeout(function() {
fadeElement(elem, increment)
}, 100))
}
}
function handleClick(cb) {
var chkbox = document.getElementById(cb.value);
var direction = cb.checked ? 0.1 : -0.1;
fadeElement(chkbox, direction)
}
<form action="">
<input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>
<p id="aurora" style="opacity:1">Aurora</p>
<p id="mainindex" style="opacity:1">Main Index</p>
举个例子。我希望这就是您要找的。请告诉我。
<form action="">
<input type="checkbox" class='imageSelect' name="skymap" value="aurora">Aurora
<input type="checkbox" class= 'imageSelect' name="skymap" value="mainindex">Main Index
</form>
<div id="aurora" style="background:yellow; width:150px; height:40px; float:left; display:none;">Aurora Image </div>
<div id="mainindex" style="background:blue; width:150px; height:40px;float:left; display:none;">MainIndex Image </div>
JS:
function CheckBoxClick(){
$(".imageSelect").click(function(){
/*if(this.checked){
$("#"+$(this).val()+" ").fadeIn();
}else{
$("#"+$(this).val()+" ").fadeOut();
}*/
$("#"+$(this).val()+" ").toggle(this.checked)
});
};
淡入淡出效果看起来更好,但使用与否由您决定,两者都有效。这是要玩的代码:https://jsfiddle.net/dzgppqap/
PD:记得在页面准备好时添加事件:
$(document).ready(CheckBoxClick());
你运行遇到了一个棘手的问题。
首先,您在 else 部分写了 "cb.val" 而不是 "cb.value"
其次,对象"cb"的不透明度属性是字符串类型。 -= 操作将不透明度值转换为数字,因为您不能对字符串执行减号操作。相反,+= 操作将数字 (0.1) 转换为字符串并添加到不透明度字符串的末尾(例如,如果不透明度为 0.1,则结果将为“0.10.1”)。由于此值无效,它将被设置为最后一个有效值并且您陷入循环
这是一个工作示例:
function handleClick(cb)
{
var myInterval = setInterval(function ()
{
if (cb.checked) // tick box checked - fade in.
{
document.getElementById( cb.value ).style.opacity = parseFloat(document.getElementById( cb.value ).style.opacity) + 0.1 // I'll refactor all these style.opacity calls later on :)
if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
{
document.getElementById( cb.value ).style.opacity = 1;
clearInterval(myInterval);
}
}
else // fade out
{
document.getElementById( cb.value ).style.opacity-=0.1;
if( document.getElementById( cb.value ).style.opacity<0 )
{
document.getElementById( cb.value ).style.opacity = 0;
clearInterval(myInterval);
}
}
}, 100);
}
您可能 运行 遇到的另一个问题是,不透明度 属性 不是默认设置的(或者至少您不能确定)。所以第一次,opacity = "", 空字符串。这将导致您的动画跳跃。如果检测到空字符串,请务必初始化不透明度。