【问题标题】:Can't pass argument to the function onmouseover - javascript无法将参数传递给函数 onmouseover - javascript
【发布时间】:2017-11-05 18:49:27
【问题描述】:

在代码的顶部,我声明了对象表。然后,在函数 setup() 中,我试图为表中的每个对象添加 onmouseover 函数并将每个对象作为函数 pickUp(pick) 的参数传递,但随后我将鼠标悬停在该对象上,控制台显示“pick is不明确的”。这对我来说很奇怪,因为我通过了 pickUps[0] 并且 typeof(pickUps[0]) 给了我“对象”。有人可以解释并帮助将每个对象作为参数传递吗?

代码:

var locked = "#4C8299";
var pickedUp = "#CC1B2B";
var released = "#19FFC8";

var pickUps = document.getElementsByClassName("pickUpSquare");

function pickUp(pick){
    if (pick.style.background == released){
        pick.style.background = pickedUp;
    }
}

function setup(){
    for (var i = 0; i < pickUps.length; i++){
        pickUps[i].onmouseover = function(){
            pickUp(pickUps[i]);
       }
    }   
}

window.onload = setup;

【问题讨论】:

标签: javascript parameter-passing mouseevent onmouseover


【解决方案1】:

问题在于setup 函数循环中的变量i 是内部匿名函数定义的闭包 的一部分。 因此,在使用pickUps[i] 的那一刻, 循环早已结束,i 的值为pickUps.length, 所以pickUps[i] 的值是undefined(它指向一个刚好超出数组边界的值)。

一种解决方法是使用返回函数的函数, 并将ipickUps[i] 作为参数传递给它:

pickUps[i].onmouseover = (function(pick) {
    return function() { pickUp(pick); }
})(pickUps[i]);

如果您可以使用 ES6,那么更简单的解决方案是在 for 循环中将 var i 替换为 let i(感谢 @alex-kudryashev)。

【讨论】:

    【解决方案2】:

    首先,您必须检查rgbrgbahex,因为在不同的浏览器中,计算出的背景颜色可以存储为rgbrgbahex (我也将其转换为rgbrgba,例如,您可以通过此在线转换器进行转换:http://hex2rgba.devoth.com/)。如果你想得到元素的计算样式,你应该这样做:window.getComputedStyle(element).getPropertyValue(property) 而不是pick.style.background。在提供的代码中,pickUp(pickUps[i]); 没有传递给函数元素,并且发生了错误:

    未捕获的类型错误:无法在“窗口”上执行“getComputedStyle”: 参数 1 不是“元素”类型

    所以我用this关键字替换了它。

    下面是工作的sn-p:

    var lockedRgb = "rgb(76, 130, 153)";
    var lockedRgba = "rgba(76, 130, 153, 1)";
    var lockedHex = "#4C8299";
    var pickedUpRgb = "rgb(204, 27, 43)";
    var pickedUpRgba = "rgba(204, 27, 43, 1)";
    var pickedUpHex = "#CC1B2B";
    var releasedRgb = "rgb(25, 255, 200)";
    var releasedRgba = "rgba(25, 255, 200, 1)";
    var releasedHex = "#19FFC8";
    
    var pickUps = document.getElementsByClassName("pickUpSquare");
    
    function pickUp(pick){
        var currentBgc = window.getComputedStyle(pick).getPropertyValue("background-color");
        if (currentBgc === releasedRgb || currentBgc === releasedRgba || currentBgc === releasedHex){
            pick.style.backgroundColor = pickedUpRgb;
        }
    }
    
    function setup(){
        for (var i = 0; i < pickUps.length; i++){
            pickUps[i].onmouseover = function(){
                pickUp(this);
           }
        }   
    }
    
    window.onload = setup;
    .pickUpSquare {
      background-color: rgb(25,255,200);
    }
    <div class="pickUpSquare">1</div>
    <div class="pickUpSquare">2</div>
    <div class="pickUpSquare">3</div>

    【讨论】:

    • 哇,非常感谢!它实际上解决了我的下一个问题:D
    • @Miokloń,很高兴听到,它有帮助!
    • 不确定是否总是 rgb... 取决于浏览器
    • @charlietfl,谢谢你的评论,我已经更新了答案
    • 好吧,根据我的经验,实际上也可以是 rgba 并且永远不会是十六进制
    【解决方案3】:

    问题是你的循环。 "i" 的最后一个值是传入的值。在这种情况下,"i" 比picks 数组的长度大一,因此它始终是未定义的。

    你必须重组你的循环,使其不依赖于 i,而且不产生只是 i 的副本的 var。这似乎有效:

    for (let pu of pickUps){
        pu.onmouseover = function(){
            pickUp(pu);
       }
    }
    

    希望这会有所帮助,或者至少建议一个答案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-02
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 2011-04-16
      • 2012-04-11
      相关资源
      最近更新 更多