在这种情况下,为什么document.getElementById的结果为null?

时间:2013-04-25 15:33:03

标签: javascript windows-8 windows-runtime winjs

我基本上是JavaScript和WinJs的新手。按照this教程学习。

我的default.html位于

之下
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>HelloWorld</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <h1 class="headerClass">Hello, World!</h1>
    <div class="mainContent">
        <p>What's your name</p>
        <input id="nameInput" type="text" />
        <button id="helloButton">Say "Hello"</button>
        <div id="greetingOutput" />
        <label for="ratingControlDiv">
            Rate this greeting:
        </label>
        <div id="ratingControlDiv" data-win-control="WinJS.UI.Rating" />
        <div id="ratingOutput" />
    </div>
</body>
</html>

我的default.js如下

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    WinJS.Binding.optimizeBindingReferences = true;

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll().then(function completed() {

                // Retrieve the div that hosts the Rating control.
                var ratingControlDiv = document.getElementById("ratingControlDiv");

                // Retrieve the actual Rating control.
                var ratingControl = ratingControlDiv.winControl;

                // Register the event handler. 
                ratingControl.addEventListener("change", ratingChanged, false);

                // Retrieve the button and register our event handler. 
                var helloButton = document.getElementById("helloButton");
                helloButton.addEventListener("click", buttonClickHandler, false);

            }));

        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    function buttonClickHandler(eventInfo) {
        var userName = document.getElementById("nameInput").value;
        var greetingString = "Hello, " + userName + "!!!";
        document.getElementById("greetingOutput").innerText = greetingString;

    }

    function ratingChanged(eventInfo) {

        var ratingOutput = document.getElementById("ratingOutput");
        ratingOutput.innerText = eventInfo.detail.tentativeRating;
    }

    app.start();
})();

我在ratingChanged中将ratingOutput视为null。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

正如其他评论所示,一定要用来关闭,因为自闭的div不是valud HTML5。在Jeffrey提供的链接中,有一个来自验证器的引用,我相信:“非自动关闭语法(/&gt;)用于非void HTML元素。忽略斜杠并将其视为开始标记。”

问题不在于ratingOutput div,而是在它之前用于评级控制的那个。我将您的代码放入一个新项目并重现您的结果,并且可以在Visual Studio的DOM Explorer中看到,ratingOutput div根本不存在于DOM中。

为什么会这样?它是上面的引用加上WinJS.UI.processAll在ratingControlDiv中创建WinJS控件的方式的组合。 WinJS实例化过程(在processAll中)有效地将ratingOutput视为ratingControlDiv的子项,并将其替换为实际控制内容。

换句话说,您所看到的行为就像您编写此标记一样:

<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
    <div id="ratingOutput"></div>
</div>

除非WinJS控件明确表示它以某种方式使用子元素(如语义缩放控件),否则无法保证子元素将被保留。

因此,ratingOutput将通过评级控制实例化从DOM中删除。

使用正确的关闭标签解决问题:

<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating"></div>
<div id="ratingOutput"></div>

很棒的问题 - 我会将此说明添加到我正在处理的第二版中。

的Kraig (作者,Programming Windows 8 Apps with HTML, CSS, and JavaScript,Microsoft Press的免费电子书)