Javascript:打开和关闭输入标签仅适用于表单中的最后一个标签

时间:2011-02-16 20:40:09

标签: javascript forms toggle

我正在尝试在点击各自的输入时打开和关闭标签。 但是我的代码只是关闭了表单中的最后一个标签。我知道jQuery将是最好的解决方案,但我正试图掌握Javascript。我非常感谢任何帮助。 非常感谢! :)

<html>
<head>
<script type="text/javascript">
window.onload=foo;

function foo(){ 

    function ToggleLabels(form){
        var oForm = document.forms[form];

        // this function will add events to objects.
        function addEvent(object,eType,eWindowsType,func,bubble){
            if(window.addEventListener){
                object.addEventListener(eType,func,bubble);
            }
            if(window.attachEvent){
                object.attachEvent(eWindowsType,func);
            }
        }

        //toggles the display of the labels
        function toggle(input,label){
        alert(label.innerHTML)
            if(input.value == ''){
                if(label.style.display == 'none'){
                    label.style.display = 'inline';
                }
                else{
                    label.style.display = 'none';
                }
            }
            else{
                label.style.display = 'none';
            }
        }

        // Loop through all text inputs in the form and add the toggle functionality
        for(var i=0; i < oForm.length; i++){
            if(oForm.elements[i].type == 'text'){               
                var oInput = oForm.elements[i];
                var oLabel = oInput.previousSibling;
                addEvent(oInput,'click','onclick',function(){toggle(oInput,oLabel)},false);

            }               
        }
    }

    new ToggleLabels(0);
}
</script>
</head>
<body>
<form>
    <label for="name" id="nameL">Name: </label><input id="name" type="text" name="name"/>
    <label for="age">Age: </label><input type="text" name="age"/>
    <label for="gender">Gender: </label><input type="text" name="gender"/>
</form>
</body>
</html>

3 个答案:

答案 0 :(得分:2)

对代码进行这种简单的更改就可以解决问题了:

// Loop through all text inputs in the form and add the toggle functionality
    for(var i=0; i < oForm.length; i++){
        if(oForm.elements[i].type == 'text'){               
            var oInput = oForm.elements[i];
            addEvent(oInput,'click','onclick',function(){toggle(this,this.previousSibling)},false);

        }               
    }

答案 1 :(得分:1)

你犯了在循环中创建函数的典型错误。 JavaScript只有函数作用域,而不是块作用域。这样做

for(...) {
    var value = "something";
}

相同
var value;
for(...) {
    value = "something";
}

这意味着每个匿名函数都引用相同的oInputoLabel。那些将具有循环的最后一次迭代的值。

您必须引入新范围,例如使用立即功能

for(var i=0; i < oForm.length; i++){
    if(oForm.elements[i].type == 'text'){             
        addEvent(oInput,'click','onclick',(function(oInput, oLabel) {
            return function(){toggle(oInput,oLabel)},false);
        }(oForm.elements[i], oInput.previousSibling)));
     }               
}

但更具可读性的是创建一个专用函数:

function getHandler(oInput, oLabel) {
    return function(){toggle(oInput,oLabel)},false);
}

// later

for(var i=0; i < oForm.length; i++){
    if(oForm.elements[i].type == 'text'){             
        addEvent(oInput,'click','onclick',getHandler(oForm.elements[i], oInput.previousSibling));         
}

答案 2 :(得分:0)

:)前两个关于闭包的答案解释了你做错了什么。

我更改了你的toggle方法以接受一个元素作为它的输入(而不是你试图传入的2个元素)。

然后我改变了你的toggle方法来检索传递给方法的元素的父节点中的所有Label元素(使用getElementsByTagName方法)。然后,我检索传入的元素的ID,并将其与检索到的每个标签元素进行比较。如果元素的ID与标签的For属性匹配,我将标签的样式设置为“display:none”...否则我将标签的样式设置为“display:inline”。

哦是的,我改变的最后一件事......我给你的​​输入“ids”:)

<html>
<head>
<script type="text/javascript">
window.onload=foo;

function foo(){ 

    function ToggleLabels(form){
        var oForm = document.forms[form];

        // this function will add events to objects.
        function addEvent(object,eType,eWindowsType,func,bubble){
            if(window.addEventListener){
                object.addEventListener(eType,func,bubble);
            }
            if(window.attachEvent){
                object.attachEvent(eWindowsType,func);
            }
        }

        //toggles the display of the labels
        function toggle(element){
            var labels= element.parentNode.getElementsByTagName("label");
            var elementName = String(element.id);

            for(i=0; i<labels.length; i++)
            {  
              var labelFor = String(labels[i].htmlFor);

              if(labelFor  == elementName )
              {  hideLabel(labels[i])
              }else{
                  displayLabel(labels[i]);
              }
            }
        }

        function displayLabel(label){
           if(label != undefined){
            label.style.display = 'inline';
           }
        }
        function hideLabel(label){
           if(label != undefined){
            label.style.display = 'none';
           }
        }

        // Loop through all text inputs in the form and add the toggle functionality
        for(var i=0; i < oForm.length; i++){
            if(oForm.elements[i].type == 'text'){               
                var oInput = oForm.elements[i];
                var oLabel = oInput.previousSibling;
                addEvent(oInput,'click','onclick',function(){toggle(this)},false);

            }               
        }
    }

    new ToggleLabels(0);
}


</script>
</head>
<body>
<form>
    <label for="name">Name: </label><input id="name" type="text" name="name"/>
    <label for="age">Age: </label><input type="text" id="age" name="age"/>
    <label for="gender">Gender: </label><input type="text" id="gender" name="gender"/>
</form>
</body>
</html>

-Frinny