javascript - DOM0级处理事件一定要使用匿名函数吗?
迷茫
迷茫 2017-04-10 17:10:03
[JavaScript讨论组]

今天在学习JS动画做一个简单的Demo时遇到一个问题
<script type="text/javascript">

    window.onload = function(){
        var aLi = document.getElementsByTagName("li");
        for(var i =0;i<aLi.length;i++){
            aLi[i].timer = null;
            aLi[i].onmouseover = function(){//这里一定要使用匿名函数吗?
                starMove(this,400);
            }
            aLi[i].onmouseout =function(){
                starMove(this,200);
            }
            
        }
    }
    function starMove(obj,iTarget){
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
            var speed = (iTarget-obj.offsetWidth)/8;
            speed=speed>0?Math.ceil(speed):Math.floor(speed);
            if(obj.offsetWidth==iTarget){
                clearInterval(obj.timer);
            }
            else{
                obj.style.width=obj.offsetWidth+speed+'px';
            }
        },30);
    }
</script>

如上段代码注释出,如果之间写成

aLi[i].onmouseover = starMove(this,400);

则没有反应出错。这里给事件的监听赋值一定要使用匿名函数的形式吗?不可以直接调用函数吗?
我查了很多网上的示例,都是写在匿名函数中的

btn.onclick = function(){
    alert(this.value);
}

直接写成

btn.onclick = alert('123');

则会直接弹出一个提示框,这又是什么原因呢?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(5)
天蓬老师

js初学者往往容易混淆函数申明(定义)函数执行

创造一个函数

function foo(){}

或者

var foo = function(){}

这是最基本的两种方法。

函数执行就是在这个函数后面加一个(),如果需要传参数,就是(a,b,c...)

现在,回到问题上。onmouseover如果是一个函数,那么在鼠标移上去的时候,会触发这个函数;否则,没有任何效果。aLi[i].onmouseover = starMove(this,400),这行代码,先执行starMove(this,400),然后将其返回值赋给aLi[i].onmouseover。因为starMove(this,400)返回值不是一个函数,所以没有任何效果。

至于函数是否需要名称,这个可有可无。但是,匿名函数没法重用。所以,如果不是一次性使用,我建议具名。代码稍作调整

// 这样做的好处是,可以把确定的参数提前传进去
aLi[i].onmouseover = starMove.bind(aLi[i],400)

function starMove(iTarget){
    var obj = this;
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var speed = (iTarget-obj.offsetWidth)/8;
        speed=speed>0?Math.ceil(speed):Math.floor(speed);
        if(obj.offsetWidth==iTarget){
            clearInterval(obj.timer);
        }
        else{
            obj.style.width=obj.offsetWidth+speed+'px';
        }
    },30);
}
PHP中文网

aLi[i].onmouseover = starMove(this,400);
这是执行starMove函数,然后将函数的返回结果赋值给aLi[i].onmouseover

btn.onclick = alert('123');直接跳出一个提示框也是这个原因

绑定回调不一定要使用匿名函数,具名的也可以的
绑定的时候把函数名赋值过去就好

aLi[i].onmouseover=starMove;
PHP中文网

不一定!你也可以写个不带参数的函数,然后让aLi[i].onmouseover = functionName;(这个的意思就是,发生该事件时才会触发这个函数)。如果你要带参数的那么你必须给个匿名函数,在匿名函数里面调用带参数的函数。btn.onclick = alert('123')直接弹出123,是因为alert('123')这条语句直接被调用了。 就好比你写 btn.onclick = functionName(),不用点击,这个函数也已经被调用。

黄舟
function click_alert() {
    alert('123');
}
btn.onclick = click_alert;

这样试一下

PHP中文网
window.onload = function(){
  var aLi = document.getElementsByTagName("li");
  for(var i =0;i<aLi.length;i++){
    aLi[i].timer = null;
    aLi[i].onmouseover = starMove(400);
    aLi[i].onmouseout = starMove(200);
  }
}
function starMove(iTarget){
  // iTarget in this scope
  return function(){
    var obj = this;
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
      var speed = (iTarget-obj.offsetWidth)/8;
      speed=speed>0?Math.ceil(speed):Math.floor(speed);
      if(obj.offsetWidth==iTarget){
        clearInterval(obj.timer);
      }
      else{
        obj.style.width=obj.offsetWidth+speed+'px';
      }
    },30);
  }
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号