为什么 class 选择器没有在点击操作时创建?
Why class selector is not created on click action?
下面是HTML代码:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript">
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('done');
}
}, false);
</script>
</head>
<body>
<ul>
<li>Buy milk</li>
<li>Take the dog for a walk</li>
<li>Exercise</li>
<li>Write code</li>
<li>Play music</li>
<li>Relax</li>
</ul>
</body>
</html>
下面是 CSS 代码:
li {
list-style-type: none;
position: relative;
margin: 2px;
padding: 0.5em 0.5em 0.5em 2em;
background: lightgrey;
font-family: sans-serif;
}
li.done {
background: #CCFF99;
}
li.done::before {
content: '';
position: absolute;
border-color: #009933;
border-style: solid;
border-width: 0 0.3em 0.25em 0;
height: 1em;
top: 1.3em;
left: 0.6em;
margin-top: -1em;
transform: rotate(45deg);
width: 0.5em;
}
以上 HTML 代码在浏览器上启动时不会创建 class="done"
点击操作。
在 fiddle 上,相同的代码工作正常。
由于代码包含在 <head>
中,因此在加载 <body>
的内容之前执行。因此,当绑定事件和未绑定事件时,DOM 中找不到元素。
有两种方法可以解决这个问题。
将代码包装在 DOMContentLoaded
事件回调中。
document.addEventListener('DOMContentLoaded', function () {
var list = document.querySelector('ul');
list.addEventListener('click', function (ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('done');
}
}, false);
});
已更新 fiddle:https://jsfiddle.net/tusharj/pr2hw6c1/
阅读有关 DOMContentLoaded 的更多信息:https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
把代码移到<body>
的末尾,这样脚本执行的时候,所有的DOM 个元素已加载。
注意:也可以使用load
事件在DOM后执行脚本代码完全 加载,但这将等待页面上的所有资源(图像、框架等)加载,这不需要在元素上绑定事件。供参考阅读 Difference between DOMContentLoaded and Load events
Why does the same code in jsfiddle works?
jsfiddle 提供了四个选项来决定脚本应该被包含在哪里。您可以在库列表下方的左侧面板中设置此选项。
onLoad
:这与window的load
事件相同。该代码包含在 load
事件的回调中,因此无法从其外部访问 functions/variables。前任。来自 HTML 内联处理程序。
onDomReady
:这与jquery的DOMContentLoaded
或ready
相同,这里也是代码换行
No wrap - in Head
:意思是在head
中加入JS代码。 No wrap
表示代码没有像 load
和 DOMContentLoaded
那样包含在任何函数中。所以定义的functions/variables是全局的。
No wrap - in Body
:脚本在<body>
元素的末尾加载。
现在我们知道了脚本对于每个选项的行为方式,在 fiddle 中,脚本位置的选项设置为 onLoad
,因此代码有效。该代码适用于除 No wrap - in Head
.
之外的所有选项
在 jsfiddle 文档上阅读更多相关信息 http://doc.jsfiddle.net/basic/introduction.html#fiddle-settings-sidebar
尝试移动脚本标签并将其放在正文的最后。他们现在的方式是,脚本试图在页面上的元素加载之前 运行。将脚本标签移动到正文底部将确保其上方的所有 html 元素已正确加载。
下面是HTML代码:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript">
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('done');
}
}, false);
</script>
</head>
<body>
<ul>
<li>Buy milk</li>
<li>Take the dog for a walk</li>
<li>Exercise</li>
<li>Write code</li>
<li>Play music</li>
<li>Relax</li>
</ul>
</body>
</html>
下面是 CSS 代码:
li {
list-style-type: none;
position: relative;
margin: 2px;
padding: 0.5em 0.5em 0.5em 2em;
background: lightgrey;
font-family: sans-serif;
}
li.done {
background: #CCFF99;
}
li.done::before {
content: '';
position: absolute;
border-color: #009933;
border-style: solid;
border-width: 0 0.3em 0.25em 0;
height: 1em;
top: 1.3em;
left: 0.6em;
margin-top: -1em;
transform: rotate(45deg);
width: 0.5em;
}
以上 HTML 代码在浏览器上启动时不会创建 class="done"
点击操作。
在 fiddle 上,相同的代码工作正常。
由于代码包含在 <head>
中,因此在加载 <body>
的内容之前执行。因此,当绑定事件和未绑定事件时,DOM 中找不到元素。
有两种方法可以解决这个问题。
将代码包装在
DOMContentLoaded
事件回调中。document.addEventListener('DOMContentLoaded', function () { var list = document.querySelector('ul'); list.addEventListener('click', function (ev) { if (ev.target.tagName === 'LI') { ev.target.classList.toggle('done'); } }, false); });
已更新 fiddle:https://jsfiddle.net/tusharj/pr2hw6c1/
阅读有关 DOMContentLoaded 的更多信息:https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
把代码移到
<body>
的末尾,这样脚本执行的时候,所有的DOM 个元素已加载。
注意:也可以使用load
事件在DOM后执行脚本代码完全 加载,但这将等待页面上的所有资源(图像、框架等)加载,这不需要在元素上绑定事件。供参考阅读 Difference between DOMContentLoaded and Load events
Why does the same code in jsfiddle works?
jsfiddle 提供了四个选项来决定脚本应该被包含在哪里。您可以在库列表下方的左侧面板中设置此选项。
onLoad
:这与window的load
事件相同。该代码包含在load
事件的回调中,因此无法从其外部访问 functions/variables。前任。来自 HTML 内联处理程序。onDomReady
:这与jquery的DOMContentLoaded
或ready
相同,这里也是代码换行No wrap - in Head
:意思是在head
中加入JS代码。No wrap
表示代码没有像load
和DOMContentLoaded
那样包含在任何函数中。所以定义的functions/variables是全局的。No wrap - in Body
:脚本在<body>
元素的末尾加载。
现在我们知道了脚本对于每个选项的行为方式,在 fiddle 中,脚本位置的选项设置为 onLoad
,因此代码有效。该代码适用于除 No wrap - in Head
.
在 jsfiddle 文档上阅读更多相关信息 http://doc.jsfiddle.net/basic/introduction.html#fiddle-settings-sidebar
尝试移动脚本标签并将其放在正文的最后。他们现在的方式是,脚本试图在页面上的元素加载之前 运行。将脚本标签移动到正文底部将确保其上方的所有 html 元素已正确加载。