【问题标题】:Windows 8 click event hander only works once WinJSWindows 8 点击事件处理程序仅适用于一次 WinJS
【发布时间】:2012-11-12 12:11:44
【问题描述】:

我正在用 JavaScript 和 HTML5 编写一个 Windows 8 应用程序。我希望在单击按钮时显示一个对话框。

我在default.js 文件中指定了事件处理程序,如下所示:

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

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;
    WinJS.strictProcessing();

    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().done(function () {

                // Get the login button on the home page
                var login_button = document.getElementById("login_submit");

                // Set an event handler on the login button
                login_button.addEventListener("click", UserActionLogin, 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 UserActionLogin(mouseEvent) {

        var message_dialog = new Windows.UI.Popups.MessageDialog("Sorry, we were unable to log you in!" + mouseEvent.y.toString()).showAsync();
    }

    app.start();
})();

我的 HTML 标记如下:

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

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

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>

    <script type="text/javascript">

    </script>
</head>
<body>
<div id="wrapper">
    <div class="login_box">
        <form method="post">
            <input type="text" name="login_username" />
            <input type="password" name="login_password" />
            <input type="submit" id="login_submit" name="login_submit" />
        </form>
    </div>
</div>
</body>
</html>

当我在应用程序加载时单击login_submit 按钮时,它会很好地显示对话框。

但是当我第二次单击它时它不起作用,就像它忘记了事件处理程序一样。

【问题讨论】:

    标签: html windows-8 winjs


    【解决方案1】:

    问题在于其中有元素,您在应用程序中不需要该元素,因为您不希望提交按钮重新发布/重新加载包含表单内容的页面。您实际上是在重新加载页面,但在这种情况下没有调用激活的处理程序(页面作为帖子而不是请求加载),因此您丢失了事件处理程序。

    如果您删除该元素,那么它就可以正常工作。我还被告知,如果你使用 type="button" 而不是 type="submit" 那么它应该可以工作。但在应用程序中,您通常会从控件收集数据并将其保存在其他变量中,使用 WInJS 导航和页面控制机制导航到应用程序中的另一个“页面”,这使您无需更改脚本即可使用 default.html上下文。

    另外,我注意到您仍然指的是 WinJS 的 RC 版本。由于Win8现已正式发布,请务必针对已发布的系统版本并使用最新的工具进行开发。

    【讨论】:

      【解决方案2】:

      问题在于您使用了 form 元素,这会导致您在单击按钮时重新加载 HTML - 这会替换您为其设置事件处理程序的元素,这意味着后续单击不会调用您的处理函数。

      去掉表单元素,你会得到你期望的行为,如下:

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8" />
          <title>App7</title>
      
          <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
          <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
          <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script>
      
          <link href="/css/default.css" rel="stylesheet" />
          <script src="/js/default.js"></script>
      </head>
      <body>
          <div id="wrapper">
          <div class="login_box">
              <input type="text" name="login_username" />
              <input type="password" name="login_password" />
              <input type="submit" id="login_submit" name="login_submit" />
          </div>
      </div>
      </body>
      </html>
      

      如果您出于某种原因确实需要form 元素(可能是因为您使用的 JS 库需要它),那么您可以通过停止在事件处理函数中提交的表单来防止该问题,如下所示:

      function UserActionLogin(mouseEvent) {
          var message_dialog = new Windows.UI.Popups.MessageDialog("Sorry, we were unable to log you in!" + mouseEvent.y.toString()).showAsync();
          mouseEvent.preventDefault();
      }
      

      调用 preventDefault 会停止发布表单,但允许您将表单元素保留在文档中。

      【讨论】:

        猜你喜欢
        • 2022-01-24
        • 1970-01-01
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多