1

我正在尽最大努力学习不显眼的 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>
4

3 回答 3

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>

将脚本放在底部还有许多其他好处。在此处阅读有关它们的更多信息

需要注意的一点:即使 iframe 和图像的标签被解析,图像本身可能还没有完成下载,所以你必须等待。iframe 内容也可能尚未加载。但是 DOMContentLoaded 也不等待这些。我只是觉得很高兴注意到。

于 2012-12-20T20:28:35.260 回答
2

这行代码:document.addEventListener("DOMContentLoaded", showArrays, false);确保你的函数showArrays()在 DOM 准备好之前不会开始执行。换句话说,函数showArrays()将在 (X)HTML 文档被加载和解析后开始执行。

我建议您将 JavaScript 代码放在一个单独的文件中,并在该head部分中使用以下 HTML 代码:<script type="text/javascript" src="yourfilepath.js"></script>. 然后你也可以使用window.onloadonclick事件来代替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 代码就会看起来更整洁、更有条理。

于 2012-12-20T20:21:05.727 回答
2

事件监听器对JS至关重要。每次用户与您的页面交互时,您都需要了解该事件并做出响应。
当然,在这个片段中,您的函数假设 DOM 中有一个具有给定 id 的元素,准备好、设置和等待。情况可能并非如此,这就是为什么您必须等到 JS 收到 OK(DOMReady事件)。

这只是一个非常简单的示例,说明为什么可以使用addEventListener. 但是 IMO,当您开始使用 Ajax 调用向您的页面添加新内容时,事件侦听器真正发挥作用:
假设 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内某处发生的所有点击事件。这几乎没有区别:all clicks,因此您无需为 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 浏览器的东西),但主要好处是:

  1. 处理动态添加/删除的元素的事件
  2. 处理所有元素的所有事件的单个事件侦听器使您的代码高效,有时会大大提高性能。这是一个很好的例子,说明什么时候委托是有序的,可悲的是,它也显示了 X-browser 开发给聚会带来的痛苦……
于 2012-12-20T20:39:49.300 回答