为什么这个Javascript会抛出错误?

时间:2012-08-05 13:01:00

标签: javascript html5 microdata

我正在使用最新版本的Opera。它支持Microdata API,但是当我输入以下代码时,它不起作用。

<head>
<script type="text/javascript">
        var user = document.getItems('http://schema.org/Person')[0];
        alert('Hi there ' + user.properties['name'][0].textContent + '!');
        function supports_microdata_api() {
             return !!document.getItems;
        }
        alert(supports_microdata_api());
        </script>
    </head>
<body>
<div itemscope itemtype="http://schema.org/Person">
  <span itemprop="name">Fatima Zohra</span>
  <img src="" itemprop="image" />
</div>

谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:2)

您需要等到页面加载;你在呼唤一些东西:

document.getItems('http://schema.org/Person')[0]

那还不是DOM的一部分;您的代码在DOM知道“尚未看到的”元素之前运行。

使用window.onload等待页面onload事件触发,这在解析元素之后发生。

window.onload = function(){
    var user = document.getItems('http://schema.org/Person')[0];
    console.log(user);
    console.log('user.properties Name: ' + user.properties['name'][0].textContent);
    function supports_microdata_api() {
        return !!document.getItems;
    }
    console.log(supports_microdata_api());
};

http://jsfiddle.net/eY63s/2/

或者,或者按照页面顺序将代码放在 DOM元素之后。

更现代的方法是使用事件委派:

window.addEventListener('load', function(){
    var user = document.getItems('http://schema.org/Person')[0];
    console.log(user);
    console.log('user.properties Name: ' + user.properties['name'][0].textContent);
    function supports_microdata_api() {
        return !!document.getItems;
    }
    console.log(supports_microdata_api());
});

http://jsfiddle.net/eY63s/3/

虽然至少早期版本的IE支持element.attachEvent,但IE9 or later浏览器支持element.addEventListener

这是检查和调用方法的更安全的方法:

window.addEventListener('load', function(){
    var user;

    function supports_microdata_api() {
        return !!document.getItems;
    }

    console.log('Microdata support: ' + supports_microdata_api());

    if (supports_microdata_api()) {
        user = document.getItems('http://schema.org/Person')[0];
        console.log(user);
        console.log('user.properties Name: ' + user.properties['name'][0].textContent);
    }
});

http://jsfiddle.net/eY63s/4/

请注意在匿名函数中使用var user,它会创建一个闭包并阻止user转义到全局范围。这是处理变量的“更好”方式,可以帮助防止它们因全局共享而被意外覆盖。另一方面,您将无法从该范围外调用user。但是,要坚持将其推向全球范围的冲动,这可能会更容易,但却是一种坏习惯,有时很难发现错误。