2

我正在阅读这本书“Javascript Ninja 的秘密”,其中大部分代码都使用自定义断言进行了演示。代码如下:

(function () {
    var queue = [],
        paused = false,
        results;

    this.test = function test(name, fn) {
        queue.push(function () {
            results = document.getElementById("results");
            results = assert(true, name).appendChild(
            document.createElement("ul"));
            fn();
        });
        runTest();
    };

    this.pause = function () {
        paused = true;
    };

    this.resume = function () {
        paused = false;
        setTimeout(runTest, 1);
    };

    function runTest() {
        if (!paused && queue.length) {
            queue.shift()();
            if (!paused) {
                resume();
            }
        }
    }

    this.assert = function assert(value, desc) {
        var li = document.createElement("li");
        li.className = value ? "pass" : "fail";
        li.appendChild(document.createTextNode(desc));

        if (results === undefined) results = document.getElementById("results");

        results.appendChild(li);

        if (!value) li.parentNode.parentNode.className = "fail";

        return li;
    };
})();

如您所见,这是一个自调用函数。

我一直在玩它,我无法理解的是为什么如果在相同的标签之间,我这样做:

<script type="text/javascript">

    ... previously shown code ...

    window.onload = function(){
       assert(true, "this works");
    };

</script>

如果我只是这样断言:

<script type="text/javascript">

    ... previously shown code ...
    assert(true, "this does not work");

</script>

当我尝试在不使用 window.onload 事件的情况下执行断言时,我在断言方法的“results.appendChild(li)”行上收到错误“Uncaught TypeError: Cannot call method 'appendChild' to null”。

非常感谢你的帮助。

4

2 回答 2

1

因为您在呈现页面上的元素之前调用代码。因此,当代码查找时,document.getElementById("results")它什么也没找到并返回 null。

于 2012-08-06T18:46:12.177 回答
1

元素标记(with id="results")在代码运行时没有被解析,因此尝试使用 return 来获取它getElementByIdnull这反过来又会.appendChild导致失败。

当您将代码放入window.onload处理程序时,它(处理程序函数中的代码)保证仅在加载窗口后运行,此时文档标记也被完全解析并且元素可用。

或者,您可以简单地将脚本元素放在目标元素之后:

<ul id="results"></ul>
<script>
//your code
</script>

因为脚本元素在目标元素之后,所以目标元素在脚本运行时保证存在。

于 2012-08-06T18:46:34.590 回答