jquery绑定事件的问题

时间:2012-09-20 18:53:23

标签: javascript jquery jquery-ui

我是前端编程的新手。当我学习Jquery时,我遇到了这个问题。 这是我的下面代码

<script type="text/javascript">
$(document).ready(function(){
  var msg ="hi";
  $("#test1").click(function(){alert(msg)});
  msg ="hello";
  $("#test2").click(function(){alert(msg)});
});
</script>
</head>
<body>

<button id="test1">test1</button>
<button id="test2">test2</button>

在运行此代码时,两个警报都会打印“hello”。我点击的第一个按钮除了“hi”警告。有人能解释我为什么会这样吗?这是礼仪行为吗?是因为范围限制吗?请帮帮我。

5 个答案:

答案 0 :(得分:5)

您有范围问题。

当您到达实际点击 msg === "hello"

的代码时

答案 1 :(得分:2)

执行处理程序代码时,msg的值为“hello”。

或者你可以将它作为数据传递给处理函数访问它..

$(document).ready(function(){
  var msg ="hi";
  $("#test1").click({msg: msg}, function(e){alert(e.data.msg)});
  msg ="hello";
  $("#test2").click({msg: msg}, function(e){alert(e.data.msg)});
});

DEMO: http://jsfiddle.net/h36pf/

答案 2 :(得分:1)

在准备好文档时,您的javascript代码已执行。此时,单击函数绑定到两个按钮,msg首先设置为hi,然后执行下一行,msg被hello覆盖。
触发点击时msg已经被覆盖,因此输出你好。

这是正确的和预期的行为。您可以通过使用两个变量或在单击时(在单击功能中)设置它们来克服此问题。

答案 3 :(得分:1)

这里有很多大致正确的解释,但令我惊讶的是,没有人抛出关键概念:封闭。

基本上发生的事情是当你声明你的两个函数时,它们声明的范围形成一个闭包。这意味着该闭包内的变量仍然可用于函数。换句话说:

$(document).ready(function(){
    // this begins a closure
    var msg ="hi";
    // you are simply declaring a function here, not calling it
    $("#test1").click(function(){alert(msg)});
    msg ="hello";
    // ditto
    $("#test2").click(function(){alert(msg)});
    // the end of the closure...msg has the value "hello"
});

然后一段时间过去了,点击事件就会被调用。附加到click事件的函数仍然可以访问闭包(其中msg的值是“hello”)。

在闭包内“捕获”变量值的传统方法是创建"Immediately Invoked Function Expression" (IIFE)。基本上你可以把它想象成创建一个包含变量的直接值的全新闭包。您可以重新编写代码以使用这样的IIFE:

$(document).ready(function(){
    // this begins a closure
    var msg ="hi";
    // the following creates an anonymous function with a single parameter
    // AND invokes it immediately, creating another closure in which the
    // value of msg1 is "hi".
    (function(msg1){
        $("#test1").click(function(){alert(msg1)});
    })(msg);
    msg ="hello";
    // ditto
    (function(msg2){
        $("#test2").click(function(){alert(msg2)});
    })(msg);
});

我希望这会使发生的事情变得更加清晰,以及如何获得你想要的东西。

答案 4 :(得分:0)

这是预期的行为。它通常不直观,但是javascript是如何工作的。获得预期结果的最简单方法是使用如下函数:

$(document).ready(function(){
  var msg ="hi";
  $("#test1").click(getCallback(msg));
  msg ="hello";
  $("#test2").click(getCallback(msg));
});

function getCallback(msg){
    return function(){
        alert(msg);
    }
}

msg中的getCallback参数为每个调用都有一个单独的msg变量,它将为每个单独的调用保持正确的值。