下拉菜单的更改处理程序工作有点奇怪

发布于 2025-01-04 04:22:01 字数 1262 浏览 1 评论 0原文

这是我所做的:

<html><head><script type="text/javascript"> 
function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      elem.onchange=function(){
          alert(elem.selectedIndex);
       }
     }
} </script></head>
<body onload="loaded()">
<select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option> </select>
 <select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option></select>
 <select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option></select>
</body></html>

我需要使用 JavaScript 获取元素的选定索引。但我对此有一个问题。 这是我的代码: http://jsfiddle.net/aRMpt/139/

Here is what I have done:

<html><head><script type="text/javascript"> 
function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      elem.onchange=function(){
          alert(elem.selectedIndex);
       }
     }
} </script></head>
<body onload="loaded()">
<select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option> </select>
 <select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option></select>
 <select name="select">
      <option>0</option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option></select>
</body></html>

I need to get selected index of element with JavaScript. But I had a problem with that.
Here is my code: http://jsfiddle.net/aRMpt/139/

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

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

发布评论

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

评论(1

丢了幸福的猪 2025-01-11 04:22:01

问题是您的 elem 始终指向最后一个 select 元素。最简单的解决方案是在处理程序中使用 this 而不是 elem 变量 http: //jsfiddle.net/mendesjuan/aRMpt/140/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      elem.onchange=function(){
          // This points to the select element that was changed
          alert(this.selectedIndex);
       }
     }
}

这并不能真正告诉你你的问题是什么。这是一种解决方法(尽管是一个很好的方法)。您的代码不起作用的原因是您的闭包函数 onchange 使用闭包中相同的 elem 。当调用 onchange 时,elem 指向最后一个 select 元素。避免这种情况的一种方法是引入另一个闭包,冻结 onchange 处理程序的 elem http://jsfiddle.net/mendesjuan/aRMpt/142/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      // Freeze the elem variable by creating a function that passes
      // the elem and creates a separate closure for each handler
      elem.onchange= (function(el) {
          // This is the function that will actually be the handler
          return function(){
             // This points to the select element that was changed
             alert(el.selectedIndex);
          }
     }) (elem) 
}

这是另一个示例,可以帮助您了解上述示例的工作原理。

// This is a function that returns another function
// Its only reason is so that we don't use the shared closure 
// variables from the outer scope, it freezes the el
// variable at the moment its called and so that it's available
// when the handler is called
function createOnChangeHandler(el) {
  return function() {
     alert(el.selectedIndex);
  }
}

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      // If we just use elem here, its value will be what it was assigned last
      // in the loop. That is because the handler won't be called until
      // this loop has finished. However, by calling another function, 
      // a new scope is created with the value that we're passing into it
      elem.onchange = createOnChangeHandler(elem);
}

变量的冻结也可以通过使用 Function.bind 来完成,但这仅适用于较新的浏览器;但是,上面的链接向您展示了如何使其适用于不支持它的浏览器。 http://jsfiddle.net/mendesjuan/aRMpt/143/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem = selectElems[i];
      elem.onchange = (function (el) {
        alert("Select index: " + el.selectedIndex)
      }).bind(null, el);
}

The problem is that your elem always points to the last select element. The simplest solution is to use this in the handler instead of the elem variable http://jsfiddle.net/mendesjuan/aRMpt/140/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      elem.onchange=function(){
          // This points to the select element that was changed
          alert(this.selectedIndex);
       }
     }
}

This doesn't really tell you what your problem is though. It's a workaround (though a good one). The reason your code doesn't work is because your closure function onchange uses the same elem from the closure. By the time your onchange is called, elem points to the last select element. A way to avoid this is to introduce another closure that freezes the elem for your onchange handler http://jsfiddle.net/mendesjuan/aRMpt/142/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      // Freeze the elem variable by creating a function that passes
      // the elem and creates a separate closure for each handler
      elem.onchange= (function(el) {
          // This is the function that will actually be the handler
          return function(){
             // This points to the select element that was changed
             alert(el.selectedIndex);
          }
     }) (elem) 
}

Here's another example that may help you understand how the above example works.

// This is a function that returns another function
// Its only reason is so that we don't use the shared closure 
// variables from the outer scope, it freezes the el
// variable at the moment its called and so that it's available
// when the handler is called
function createOnChangeHandler(el) {
  return function() {
     alert(el.selectedIndex);
  }
}

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem=selectElems[i];
      // If we just use elem here, its value will be what it was assigned last
      // in the loop. That is because the handler won't be called until
      // this loop has finished. However, by calling another function, 
      // a new scope is created with the value that we're passing into it
      elem.onchange = createOnChangeHandler(elem);
}

This freezing of variables could also be accomplished by using Function.bind, but this only works in newer browsers; however, the above link shows you how to make it work for browsers that don't support it. http://jsfiddle.net/mendesjuan/aRMpt/143/

function loaded(){
    var selectElems=document.getElementsByName("select");
    for(i=0;i<selectElems.length;i++){
      var elem = selectElems[i];
      elem.onchange = (function (el) {
        alert("Select index: " + el.selectedIndex)
      }).bind(null, el);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文