在函数内使用循环变量,javascript 作用域混乱

发布于 2024-10-07 22:03:36 字数 900 浏览 1 评论 0原文

我已经构建了一个下拉菜单系统,在独立测试时一切正常,我遇到的问题在下面的代码中。我使用 jQuery Ready 函数从外部数组 (menubar[]) 构建菜单栏。在这里,我尝试让鼠标悬停事件调用 dropdown() 函数,但为每个锚标记使用不同的参数。

因此,滚动第一个应该调用 dropdown(0),第二个 dropdown(1) 等等。

$(document).ready(function () {
    for (i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
                          '" class="menutitle">' + menubar[i].name + '</a>';
        var a = $(declaration).mouseover(function () {
            dropdown(i);
        }).mouseout(function () {
            activeTimer = setTimeout("removedropdowns()", 100);
        });
        $("#menu").append(a);
    }
});

该代码正在调用 dropdown(6);每次翻转时。如何将循环变量 (i) 作为文字/静态值传递到鼠标悬停函数中!

我通过使用在 FF 中正常工作,

.attr('onMouseOver','javascript:dropdown('+i+');')

但对于某些版本的 IE 并没有触发,所以我切换到 jQuery mouseover,它会触发,但我遇到了上面的问题:(

I have built a dropdown menu system, everything works when tested independently, the problem I have is in the code below. I use the jQuery ready function to build the menu bar from an external array (menubar[]). Here I am trying to get the mouseover event to call the dropdown() function, but using a different argument for each anchor tag.

So rolling over the first should call dropdown(0), the second dropdown(1) and so on.

$(document).ready(function () {
    for (i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
                          '" class="menutitle">' + menubar[i].name + '</a>';
        var a = $(declaration).mouseover(function () {
            dropdown(i);
        }).mouseout(function () {
            activeTimer = setTimeout("removedropdowns()", 100);
        });
        $("#menu").append(a);
    }
});

The code is calling dropdown(6); on each rollover. How can I pass the loop variable (i) into the mouseover function as a literal/static value!

I got this working fine in FF by using

.attr('onMouseOver','javascript:dropdown('+i+');')

but that wasn't firing for some versions of IE, so I switched to the jQuery mouseover, which fires, but I have the issue above :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

三生池水覆流年 2024-10-14 22:03:36

您的实际问题是,您的每个鼠标悬停回调都使用相同 i,您将 i 一直增加到 6,回调仍然指向相同的 i,因此都使用 6 作为值。

您需要复制 i,可以使用匿名函数来完成此操作。

$(document).ready(function () {
    // you should use (for(var i = 0, l = menubar.length; i < l; i++) here in case menubar is an array
    for (var i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
                          '" class="menutitle">' + menubar[i].name + '</a>';


        (function(e) { // e is a new local variable for each callback
            var a = $(declaration).mouseover(function () {
                dropdown(e);

            }).mouseout(function () {
                activeTimer = setTimeout(removedropdowns, 100); // don't use strings for setTimeout, since that calls eval
            });
            $("#menu").append(a);
        })(i); // pass in the value of i
    }
});

Your actual problem is that each of your mouseover callbacks uses the same i you increase i all the way up to 6, the callbacks still point to the same i and therefore all use 6 as the value.

You need to make a copy of the value of i, you can do this by using an anonymous function.

$(document).ready(function () {
    // you should use (for(var i = 0, l = menubar.length; i < l; i++) here in case menubar is an array
    for (var i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
                          '" class="menutitle">' + menubar[i].name + '</a>';


        (function(e) { // e is a new local variable for each callback
            var a = $(declaration).mouseover(function () {
                dropdown(e);

            }).mouseout(function () {
                activeTimer = setTimeout(removedropdowns, 100); // don't use strings for setTimeout, since that calls eval
            });
            $("#menu").append(a);
        })(i); // pass in the value of i
    }
});
别忘他 2024-10-14 22:03:36
$(function() {
    $(menubar).each(function(i){
        $("#menu").append('<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>');
    });

    $("#menu a").hover(
        function(){
            dropdown($(this).index());
        },
        function(){
            activeTimer = setTimeout("removedropdowns()", 100);
        }
    );
});
$(function() {
    $(menubar).each(function(i){
        $("#menu").append('<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>');
    });

    $("#menu a").hover(
        function(){
            dropdown($(this).index());
        },
        function(){
            activeTimer = setTimeout("removedropdowns()", 100);
        }
    );
});
养猫人 2024-10-14 22:03:36

首先,不要使用 for..in 而是使用普通循环。

其次,我只是先附加链接,然后再应用事件:

$(document).ready(function() {
    for (var i = 0; i < menubar.length; i++) {
        $("#menu").append('<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>');
    }

    $("#menu a").each(function(index) {
        $(this).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
    });
});

First, don't use for..in but rather ordinary loop.

Second, I would just append the links first then apply the events later:

$(document).ready(function() {
    for (var i = 0; i < menubar.length; i++) {
        $("#menu").append('<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>');
    }

    $("#menu a").each(function(index) {
        $(this).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
    });
});
各自安好 2024-10-14 22:03:36

看看这里此处

要捕获 i 的当前值,您需要将其作为参数传递给另一个函数,在该函数中可以将其捕获为局部变量:

Have a look here and here.

To capture the current value of i, you need to pass it as a parameter to another function where it can be captured as a local variable:

舂唻埖巳落 2024-10-14 22:03:36

尝试使用 jQuery 的 each() 函数:

jQuery(function() {
  jQuery.each(menubar, function(index, element) {
    var declaration = '<a href="' + baseurl + '/' + element.url + '" class="menutitle">' + element.name + '</a>';
    var a = $(declaration).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
    $("#menu").append(a);
  });
});

Try using jQuery's each() function:

jQuery(function() {
  jQuery.each(menubar, function(index, element) {
    var declaration = '<a href="' + baseurl + '/' + element.url + '" class="menutitle">' + element.name + '</a>';
    var a = $(declaration).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
    $("#menu").append(a);
  });
});
夜灵血窟げ 2024-10-14 22:03:36

在 JavaScript 中,如果您不声明变量,它将被全局定义。要解决此问题,请在 i 循环变量前面添加“var”,如下所示。更新:正如 Sime 注意到的(参见注释),您还需要将变量传递到函数中,否则您会在 i 上形成一个闭包。

$(document).ready(function() {
    for(var i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>';
        var a = $(declaration).mouseover(function(i) { dropdown(i); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
        $("#menu").append(a);
    }
});

In JavaScript, if you don't declare your variable, it is defined globally. To fix this, add "var" in front of your i looping variable like this. UPDATE: As Sime noticed (see comment), you also need to pass the variable into the function, otherwise you form a closure on the i.

$(document).ready(function() {
    for(var i in menubar) {
        var declaration = '<a href="' + baseurl + '/' + menubar[i].url + '" class="menutitle">' + menubar[i].name + '</a>';
        var a = $(declaration).mouseover(function(i) { dropdown(i); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
        $("#menu").append(a);
    }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文