JavaScript代码未运行

时间:2013-02-13 20:38:18

标签: javascript

我有以下代码:

...<some code>...
...<elements load>...

<script type="text/javascript">

    var selected_city = document.getElementById('jform_city').value;
    var selected_province=document.getElementById('jform_province').value;

    <!-- set the onchange property for all options in provice to activate getCities() -->
    document.getElementById('jform_province').onchange = function() {
        getCities();
    }

    if(selected_province != ''){
        getCities();
    }
</script>

...<more elements load>....

<script type="text/javascript">
    alert("TEST");
    document.getElementById(selected_city).selected="1";
    </script>

它从我有的下拉列表中选择一个选项,问题是,如果我删除了警告(“”)它因某种原因停止工作,有什么想法吗?

1 个答案:

答案 0 :(得分:4)

在尝试使用document.getElementById之前,您需要等待文档加载。警报正在减慢速度,在警报框后面,元素被加载。如果没有警报,当下一行运行时,“selected_city”可能会有 no 元素。

有关等待页面加载的详细信息,请查看this StackOverflow question

修改

首先,当Web浏览器解析页面时会发生的事情是它将收到的HTML元素转换为DOM - 文档对象模型,它是页面的内存中表示形式。只有在元素位于DOM之后才有可能对它进行操作,并且元素将以与它们在HTML中出现的顺序相同的顺序进入DOM不一定是正确的:现代快速浏览器非常异步地运行,只保证页面将最终看起来好像整个事情是同步加载的。这很容易验证:几乎每个浏览器都会加载文本,甚至在它移动和显示图像时显示它。只有在获取图像后,才会将其插入显示屏,如果必须,将文本推送/回流。最终结果是相同的,但页面似乎加载速度更快。

不幸的是,这种“等待它”保证不适用于Javascript(因为JS本身可以改变页面加载的方式)。因此,简单地将脚本标记移动到文档的末尾与等待DOM包含元素不同。

你必须实际上等待浏览器回调并告诉你DOM已经加载 - 这是真正知道你可以操纵DOM的唯一方法。这是window.onload的回调。我可以想到一些不适合你的原因:

如果您实际上只是插入了逐字window.onload = function();,那么您就错过了这一点 - 这不是一个空函数,而是您的函数。我假设你不只是输入,但为了以防万一,你的代码应该是

window.onload = function(){
    document.getElementById(selected_city).selected="1";
};

或者,由于window.onload=[some function]将稍后调用的函数分配给一个变量,因此只能有一个变量。如果您正在加载分配window.onload的其他脚本,则您的回调可能会丢失。

这就是为什么像jquery这样具有ready函数的框架可以接受和回调任意数量的函数,这是前端开发人员的黄金。 Here is another StackOverflow question专门询问有关使用onload的信息。

最后,这一行:

var selected_city = document.getElementById('jform_city').value;

要求在正常运行之前加载DOM。 selected_city本身可能为null或未定义,因为当您要求其值时,不会加载#jform_city。这反过来会导致document.getElementById(selected_city)失败,即使在您尝试选择该元素时加载了该元素。

异步性是Javascript中真正的痛苦。

每当您需要从页面本身获取信息时,根据经验,您必须等待DOM加载。在实践中,这意味着几乎所有代码(除了不以任何方式要求加载页面的代码)都应该在加载页面后调用的函数中。