下拉菜单'的更改处理程序工作起来有点奇怪
Dropdown's change handler is working a bit weird
以下是我所做的:
<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/
问题是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处理程序冻结elemhttp://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);
}
相关文章:
- Javascript:selenium Web驱动程序isDisplayed()不工作
- jQuery UI自动完成突然停止工作
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- JavaScript打印功能使日历停止工作
- Javascript.getHours()工作不正常
- 为什么这在IE中的工作方式与在Firefox中不同
- 视频HTML没有'无法在Internet Explorer 11上工作
- 扩展移相器按钮类不工作
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 正在尝试使用if和else添加类,但无法正常工作
- Jquery FadeIn FadeOut 只工作一次
- 当我用鼠标左键点击时,让这个功能工作起来
- 图像看起来像一个只在firefox中工作的按钮
- 如何获得EaselJS'鼠标事件是否正常工作?它看起来可以工作,但它不断返回一个位图ID,而不是正确的
- 下拉菜单'的更改处理程序工作起来有点奇怪
- jQuery在Firefox中看起来/工作得很好,但在IE (Internet Explorer)中就不行
- 如何将html、css和javascript编码结合起来使我的旋转木马工作
- javascript表单验证不工作,即使一切看起来都很好(JS在浏览器中没有禁用)