【问题标题】:Javascript AddEventListener Fires only onceJavascript AddEventListener 只触发一次
【发布时间】:2015-02-10 21:08:14
【问题描述】:

我有以下 HTML

...
    <div class="content-row"><div class="col-md-4"></div>
            <div class="col-md-4">
                <form>
                    <div id='undiv' class="form-group"><label for="uname">Name:</label><input id="uname" type="text" class="form-control"/></div>
                    <div class="form-group"><label for="email">Email (optional):</label><input id="email" type="text" class="form-control" /></div>
                    <div class="form-group"><label for="gamecode">Game Code:</label><input id="gamecode" type="text" class="form-control" /></div>
                    <div class="form-group pull-right"><input id="join" type="button" value="Join" class="btn btn-primary btn-lg btn btn-primary btn-lg" /></div>
                </form>
            </div><div class="col-md-4"></div>
    </div>
....

body中HTML下面的Javascript

<script type='text/javascript'>
            var uname = document.getElementById("uname");
            var email = document.getElementById("email");
            var gamecode = document.getElementById("gamecode");
            var joinbtn = document.getElementById("join");
            var notify = document.getElementById("notify");
            var undiv = document.getElementById("undiv");
...


    uname.addEventListener("blur",function(evt) {
                console.log('onblur');
                var un = uname.value;
                console.log(un);
                if(un.length >= 2) {
                    undiv.className += " has-success has-feedback";
                    undiv.innerHTML += '<span id="mark" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>';
                }
                else {
                    undiv.className += " has-error has-feedback";
                    undiv.innerHTML += '<span id="mark" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>';
                }
                //uname.value = un;
            });

            uname.addEventListener("focus",function(evt) {
                console.log('onfocus');
                undiv.className = "form-group";
                var mark = document.getElementById("mark");
                if(mark !=null) {
                    mark.parentNode.removeChild(mark);      
                    console.log("mark="+mark);  
                }   
            });
    </script>

onfocus 和 onblur 事件上的 uname 仅触发一次。

我在button click event 上有另一个eventListener,它工作正常。

我不明白为什么 focus 和 blur eventListeners 在事件发生时不触发?

Chrome 和 Firefox 上的调试器没有显示错误或警告...我不明白出了什么问题?

http://jsfiddle.net/ddf5h2nu/

【问题讨论】:

  • uname 输入被您的 onblur 处理程序覆盖(删除并重新创建),因为您正在设置其容器 div 的 innerHTML。

标签: javascript html twitter-bootstrap


【解决方案1】:

一个好的做法是在办公桌上放一把尺子,如果您发现自己在输入element.innerHTML += "...",只需抓住尺子并拍打您的手背。

;-)

说真的,在.innerHTML 之后使用+= 是非常具有破坏性和不必要的,并且如您所见会导致意想不到的结果。

另一个答案显示了如何使用 DOM 创建方法,这是一个好方法,但是如果你想使用 HTML 标记,那么使用 .insertAdjacentHTML() 而不是 .innerHTML。

uname.addEventListener("blur",function(evt) {
    console.log('onblur');
    var un = uname.value;
    console.log(un);
    if(un.length >= 2) {
        undiv.className += " has-success has-feedback";
        undiv.insertAdjacentHTML("beforeend", '<span id="mark" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>');
    }
    else {
        undiv.className += " has-error has-feedback";
        undiv.insertAdjacentHTML("beforeend", '<span id="mark" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>');
    }
    //uname.value = un;
});

您会注意到第一个参数是"beforeend",第二个是您的 HTML。 .insertAdjacentHTML() 方法接受四个不同的字符串作为第一个参数。它们如下:

  • "beforebegin" (将标记放在元素之前)
  • "afterbegin" (将标记放在开头的元素内)
  • "beforeend" (将标记放在最后的元素内)
  • "afterend" (将标记放在元素之后)

因此,相对于调用该方法的元素,可以在四个位置插入 HTML。这些不会破坏任何现有元素,这就是为什么它比 .innerHTML 更好。

【讨论】:

  • 感谢您花时间解释详细信息。真的很感激。下次我使用 DOM 时,我会记住你关于标尺的建议。
  • 如此被低估的答案。我花了几个月和几个月的时间被引导到错误的方向,最终在一大堆不正确(并且高度赞成)的答案中找到了这个。这比使用 innerHTML、append、prepend 等来实现它们不应该用于的东西要灵活得多。 insertAdjacentHTML() 很棒。
  • 谢谢老师@Lye-Fish
【解决方案2】:

当您更改 undiv 的 innerHTML 属性时,会导致从 HTML 重新创建 &lt;input&gt; 元素,从而丢失事件侦听器。

这是一个不错的选择:

var newItem = document.createElement('span');
newItem.id = 'mark';
newItem.className = 'glyphicon glyphicon-ok form-control-feedback';
newItem.setAttribute('aria-hidden', true);
undiv.appendChild(newItem);

Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-09
    • 2018-07-06
    • 2022-10-23
    • 1970-01-01
    • 2022-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    相关资源
    最近更新 更多