4

这是我从文章中获取的示例,并进行了一些更改。这个例子完美地工作

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" media="screen">
        <script type="text/javascript">
            dojoConfig = {
                parseOnLoad: false,
                async: true
            };
        </script>   
        <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js" type="text/javascript"></script>
        <script type="text/javascript">
            /// Require the registry, parser, Dialog, and wait for domReady
            require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog"], function (registry, parser, JSON, config) {
                // Explicitly parse the page
                parser.parse();
                // Find the dialog
                var dialog = registry.byId("dialog");
                // Set the content equal to what dojo.config is
                dialog.set("content", "<b>it works!</b>");
                // Show the dialog
                dialog.show();
            });
        </script>
    </head>
    <body class="claro">
        <div id="dialog" data-dojo-type="dijit.Dialog"></div>
    </body>
</html>

现在我想修改它并使用 jQuery 动态加载 Dojo。这是我如何执行此操作的示例:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" media="screen">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            dojoConfig = {
                parseOnLoad: false,
                async: true
            };

            $.getScript("http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js")
            .done(function (script, textStatus) {
                /// Require the registry, parser, Dialog, and wait for domReady
                require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog"], function (registry, parser, JSON, config) {
                    // Explicitly parse the page
                    parser.parse();
                    // Find the dialog
                    var dialog = registry.byId("dialog");
                    // Set the content equal to what dojo.config is
                    dialog.set("content", "<b>it works!</b>");
                    // Show the dialog
                    dialog.show();
                });
            })
            .fail(function (jqxhr, settings, exception) {
                alert('Cannot load Dojo.js');
            });
        });
    </script>
</head>
<body class="claro">
    <div id="dialog" data-dojo-type="dijit.Dialog">
    </div>
</body>
</html>

但看起来我做错了什么,因为它引发了下一个错误

NotFoundError: Node was not found
http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js
Line 2 

我怀疑 Dojo 还没有准备好,但也许我错了......是否可以使用 jQuery 来动态加载 Dojo?

4

2 回答 2

1

“未找到节点”错误是由加载程序试图定位加载它的脚本标签引起的。这是 Dojo 在从 CDN(如您使用的谷歌)加载时使用的一种技巧,以尝试找到加载模块的 url 路径。

jQuery $.getScript() 函数实际上并不是将脚本标签注入页面,而是通过 XHR 加载然后评估代码。因此,找不到 Dojo 正在寻找的标签。这仅在使用 CDN 时发生。如果您使用自己的 Dojo 本地副本而不是 CDN,则可以使其正常工作。

我不确定通过 jQuery 加载 Dojo 是一种好习惯。最好分别加载它们或以相反的方式加载它们(即在 Dojo 中加载 jQuery)。我假设你需要两者的功能,否则你不会尝试这个。

要将 jQuery 作为 Dojo 模块加载,您可以按如下方式更改代码:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <link
        rel="stylesheet"
        href="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css"
        media="screen"
    />
    <script type="text/javascript">
        var dojoConfig = {
            "parseOnLoad": false,
            "async": true,
                "packages": [{
                    "name": "jquery",
                    "location": "//ajax.googleapis.com/ajax/libs/jquery/1.9.0",
                    "main": "jquery.min"
                }]
        };
    </script>
    <script
        type="text/javascript"
        src="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"
    ></script>
    <script type="text/javascript">
        define.amd.jQuery = true;  // jQuery will be loaded as an AMD module

        require([
            "jquery",
        ], function($){
            // NB: $ is only available within the scope it has been loaded
            // as it is loading as an AMD module.  Hence, $ is not globally
            // available and must be required into any scope it is used.

            $(document).ready(function () {
                require([
                    "dijit/registry",
                    "dojo/parser",
                    "dojo/json",
                    "dojo/_base/config",
                    "dijit/Dialog"
                ], function (registry, parser, JSON, config) {
                    // Explicitly parse the page
                    parser.parse();
                    // Find the dialog
                    var dialog = registry.byId("dialog");
                    // Set the content equal to what dojo.config is
                    dialog.set("content", "<b>it works!</b>");
                    // Show the dialog
                    dialog.show();
                });
            });
        })
    </script>
</head>
<body class="claro">
    <div id="dialog" data-dojo-type="dijit/Dialog">
    </div>
</body>
</html>

坚持使用 Dojo 可能比同时使用两者要好。但是,以上将允许两者一起使用。Dojo,有它自己的准备函数(dojo/ready),可以替代 $(document).ready()。jQuery 的大部分功能都在 Dojo 中的某个庄园中复制。

将 jQuery 作为 Dojo 模块加载意味着它仅在 require 回调中可用。因此,$ 不像通常情况那样被放置在全局范围内。您必须将其要求到您需要的任何 JavaScript 中。

注意:我将代码中的 dijit.Dialog 更改为 dijit/Dialog,因为如果您使用点格式,它将不会在 1.8 版中加载。

于 2013-02-01T11:48:26.167 回答
0

好的,最后看起来我找到了基于文章的可靠解决方案......这是工作示例:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" media="screen">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script type="text/javascript">
        function loadScript(url, callback) {
            var script = document.createElement("script")
            script.type = "text/javascript";

            if (script.readyState) {  //IE
                script.onreadystatechange = function () {
                    if (script.readyState == "loaded" ||
                    script.readyState == "complete") {
                        script.onreadystatechange = null;
                        callback();
                    }
                };
            } else {  //Others
                script.onload = function () {
                    callback();
                };
            }

            script.src = url;
            document.body.appendChild(script);
        }

        $(document).ready(function () {
            dojoConfig = {
                parseOnLoad: false,
                async: true
            };

            loadScript("http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js", function () {
                /// Require the registry, parser, Dialog, and wait for domReady
                require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog"], function (registry, parser, JSON, config) {
                    // Explicitly parse the page
                    parser.parse();
                    // Find the dialog
                    var dialog = registry.byId("dialog");
                    // Set the content equal to what dojo.config is
                    dialog.set("content", "<b>it works!</b>");
                    // Show the dialog
                    dialog.show();
                });
            });
        });
    </script>
</head>
<body class="claro">
    <div id="dialog" data-dojo-type="dijit.Dialog">
    </div>
</body>
</html>

这不是纯粹的 jQuery 解决方案,但它对我来说更好,然后在页面上包含 Dojo 脚本......

于 2013-02-01T15:23:22.170 回答