我正在尽力学习不引人注目的JavaScript。下面的代码是尝试使用从HTML标记内调用的getArrays函数更改现有的练习片段。这是我唯一可以上班的版本。虽然它很好用,但我觉得可能有一些不必要的部分,并且不完全理解为什么我需要最后一行代码(addEventListener的新东西)。我正在使用Mozilla DOM参考示例,并且已经知道如何在jQuery中执行此操作。谢谢!
JavaScript的:
<script>
function getArrays() {
var ddlValArray = new Array();
var ddlTextArray = new Array();
var ddl = document.getElementById("ddlFlavors");
for (i=0; i<ddl.options.length; i++) {
ddlValArray[i] = ddl.options[i].value;
ddlTextArray[i] = ddl.options[i].text;
alert(ddlValArray[i] + ' ' + ddlTextArray[i]);
}
}
function showArrays() {
var link = document.getElementById("clickHandler");
link.addEventListener("click", getArrays, false);
}
document.addEventListener("DOMContentLoaded", showArrays, false);
</script>
HTML
Select Flavor:
<select id='ddlFlavors'>
<option value="1">Vanilla</option>
<option value="2">Chocolate</option>
<option value="3">Strawberry</option>
<option value="4">Neopolitan</option>
</select>
<br/><br/>
<a id="clickHandler" href="#">Show Flavors</a>
答案 0 :(得分:5)
如果正确构建HTML / JS,则不会。
将脚本标记移动到</body>
标记之前的正文底部,您不再需要等待DOMContentLoaded事件。它上面的html将在JS执行之前被解析。
这会导致其他警告,但对于您的示例,它会起作用。
<body>
Select Flavor:
<select id='ddlFlavors'>
<option value="1">Vanilla</option>
<option value="2">Chocolate</option>
<option value="3">Strawberry</option>
<option value="4">Neopolitan</option>
</select>
<br/><br/>
<a id="clickHandler" href="#">Show Flavors</a>
<script>
function getArrays() {
var ddlValArray = new Array();
var ddlTextArray = new Array();
var ddl = document.getElementById("ddlFlavors");
for (i=0; i<ddl.options.length; i++) {
ddlValArray[i] = ddl.options[i].value;
ddlTextArray[i] = ddl.options[i].text;
alert(ddlValArray[i] + ' ' + ddlTextArray[i]);
}
}
function showArrays() {
var link = document.getElementById("clickHandler");
link.addEventListener("click", getArrays, false);
}
showArrays();
</script>
</body>
将脚本放在底部还有许多其他好处。 Read more about them here。
有一点需要注意:即使解析了iframe和图像的标签,图像本身也可能无法完成下载,因此您必须等待。此外,iframe内容也可能尚未加载。但是,DOMContentLoaded也不会等待这些。我只是觉得这很好。
答案 1 :(得分:2)
这行代码:document.addEventListener("DOMContentLoaded", showArrays, false);
确保您的函数showArrays()
在DOM准备好之前不会开始执行。换句话说,函数showArrays()
将在加载和解析(X)HTML文档后开始执行。
我建议您将JavaScript代码放在单独的文件中,并使用head
部分中的以下HTML代码:<script type="text/javascript" src="yourfilepath.js"></script>
。然后,您还可以使用window.onload
和onclick
个事件代替document.addEventListener()
方法。
当你这样做时,你可以将代码放在showArrays
函数体外,并删除函数。
例如:
window.onload = function()
{
var link = document.getElementById("clickHandler");
link.onclick = getArrays;
}
这被认为是一种更好的做法。
完整示例
在script.js
档案中:
//This is the beginning of the script...
function getArrays() {
var ddlValArray = new Array();
var ddlTextArray = new Array();
var ddl = document.getElementById("ddlFlavors");
for (i=0; i<ddl.options.length; i++) {
ddlValArray[i] = ddl.options[i].value;
ddlTextArray[i] = ddl.options[i].text;
alert(ddlValArray[i] + ' ' + ddlTextArray[i]);
}
}
window.onload = function()
{
var link = document.getElementById("clickHandler");
link.onclick = getArrays;
}
在HTML头部内:
<script type="text/javascript" src="script.js"></script>
在大多数情况下,最好将JavaScript与HTML文件分开编写,就像CSS一样。这样,您就可以使HTML代码看起来更整洁,更有条理。
答案 2 :(得分:2)
事件监听器对JS来说是至关重要的。每当用户与您的页面进行交互时,您都需要了解该事件并对其进行响应。
当然,在这个片段中,你的函数假设在DOM中有一个给定id的元素,准备好,设置和等待。可能不是这种情况,这就是为什么你必须等到JS收到OK(DOMReady
事件)。
这只是一个非常简单的例子,为什么可能会使用addEventListener
。但是当你开始使用Ajax调用时,IMO,事件监听器真的会出现在你的页面中添加新内容:
假设DOM已准备好,但稍后可能会或可能不会请求某些元素(取决于用户输入)。在jQuery中,你会使用这样的东西:
$('#foo').on('click',functionRef);
这个代码运行时不需要 foo 元素,但只要元素添加到dom中,就会根据需要处理点击事件。
在非jQ中,您将使用addEventListener
。由于事件模型(有关传播和冒泡的详细信息,请参阅quirksmode),不需要将侦听器直接附加到元素:
document.body.addEventListener('click',function(e)
{
if ((e.target || e.srcElemet).id === 'foo')
{
//function that deals with clicks on foo element
}
},false);//last param is for bubbling/propagating events
这样,您可以绑定可能异步添加到dom的元素的所有事件,而不必检查每个ajax调用的每个响应...
让我们更进一步:委派。正如您所看到的,在上面的代码段中,我们正在侦听所有点击事件,这些事件发生在 body 中的某个位置。这几乎没有区别:所有点击,因此您不需要为101个元素添加101个不同的点击侦听器,只需添加一个。你需要做的唯一事情就是编写处理程序,使其相应地处理每个元素:
document.body.addEventListener('click',function(e)
{
e = e || window.event;
var elem = e.target || e.srcElement;
switch (true)
{
case elem.id === 'foo':
//either code here or:
return fooCallback.apply(elem,[e]);//use another function as though it were the handler
case elem.id.className.match(/\bsomeClass\b/):
return someClassCallback.apply(elem,[e]);//~= jQuery's $('.someClass').on('click',function);
case elem.type === 'text':
//and so on
}
},false);
相当强大的东西。当然,它还有很多,而且还有缺点(主要是X浏览器的东西),但主要的好处是: