RequireJS影响嵌入式jquery-ui小部件

Lee*_*Lee 5 javascript jquery jquery-ui requirejs

我有一个jQuery小部件,合作伙伴正试图嵌入.我们遇到的问题是合作伙伴正在使用requireJS及其影响小部件.

小部件是匿名函数,需要jquery-ui.在调试之后,我们发现在noConflict调用之后将删除jQuery UI.这是小部件的代码.

(function () {

    // Localize jQuery variable
    var jQueryWidget;

    /******** Load jQuery if not present *********/
    if (window.jQuery === undefined || window.jQuery.fn.jquery !== '3.2.1') {
        var script_tag = document.createElement('script');
        script_tag.setAttribute("type", "text/javascript");
        script_tag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js");
        script_tag.onload = scriptLoadHandler;
        script_tag.onreadystatechange = function () { // Same thing but for IE
            if (this.readyState == 'complete' || this.readyState == 'loaded') {
                scriptLoadHandler();
            }
        };
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
    } else {
        loadJQueryUi();
    }

    function scriptLoadHandler() {
        loadJQueryUi();    
    }

    function loadJQueryUi() {
    /******* Load UI *******/
        jQuery.getScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js', function () {
          jQueryWidget = jQuery.noConflict(true);
          setHandlers(jQueryWidget);
        });


        /******* Load UI CSS *******/
        var css_link = jQuery("<link>", {
            rel: "stylesheet",
            type: "text/css",
            href: "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css"
        });
        css_link.appendTo('head');
    }

    function setHandlers($) {
        $(document).on('focus', '#start-date, #end-date', function(){

      $('#start-date').datepicker({
        dateFormat: "M dd, yy",
        minDate: 'D',
        numberOfMonths: 1,
      });

            $('#end-date').datepicker({
                dateFormat: "M dd, yy",
                minDate:'+1D',
                numberOfMonths:1,
            });
    }
})();
Run Code Online (Sandbox Code Playgroud)

使用chrome调试器,我们可以看到,当调用getScript时,它正确地将jquery-ui添加到加载的版本中.在我们调用noConflict它恢复之前的jQuery但版本不再具有jQueryUI之后.

在没有requireJS的情况下测试其他站点上的小部件是否正常工

以前有人遇到过这个吗?不幸的是我们之前没有使用过RequireJS,但是无法理解为什么它会影响匿名功能.

任何帮助将非常感激.

gus*_*dpk -1

我认为问题在于jQueryWidget = jQuery.noConflict(true);

true 表示从全局范围中删除所有 jQuery 变量。

jQuery.noConflict( [removeAll ] ) removeAll 类型:Boolean 一个布尔值,指示是否从全局范围(包括 jQuery 本身)中删除所有 jQuery 变量。

[无冲突][1]

我们可以尝试删除 true 布尔参数,让知道是否有帮助。

更新 2: 以下方法不需要更改任何合作伙伴代码

<!DOCTYPE html>
        <html>

        <head>
            <title></title>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script>
            <script type="text/javascript">
            (function() {

                // Localize jQuery variable
                var jQueryWidget;
                /*
                *
                *
                *
                    This is plugin's require config. Only used by plugin and
                    will not affect partner config.
                *
                *
                */
                var requireForPlugin = require.config({
                    context: "pluginversion",
                    paths: {
                        "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min",

                        "jquery.ui.widget": "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min"

                    }
                });
                requireForPlugin(["require", "jquery", "jquery.ui.widget"], function() {
                    /******** Load jQuery if not present *********/
                    if (window.jQuery === undefined || window.jQuery.fn.jquery !== '3.2.1') {
                        scriptLoadHandler();
                    } else {
                        loadJQueryUi();
                    }

                    function scriptLoadHandler() {
                        loadJQueryUi();
                    }

                    function loadJQueryUi() {
                        jQueryWidget = jQuery.noConflict(true);
                        setHandlers(jQueryWidget);
                        var css_link = jQueryWidget("<link>", {
                            rel: "stylesheet",
                            type: "text/css",
                            href: "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css"
                        });
                        css_link.appendTo('head');
                    }

                    function setHandlers($) {
                        $('#end-date').on('click', function() {
                            alert('JQUERY--' + $().jquery);
                            alert('JQUERY UI--' + $.ui.version);
                            $('#end-date').datepicker({
                                dateFormat: "M dd, yy",
                                minDate: '+1D',
                                numberOfMonths: 1,
                            });
                        });
                    }
                });
            })();
            </script>
            <script>
            //SAMPLE PARTNER APPLICATION CODE:

            /*
            *
            *
            *
                This is partner's require config
                which uses diffrent version of jquery ui and
                jquery
            *
            *
            */
            require.config({
                paths: {
                    "jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min",

                    "jquery.ui.widget": "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui"

                }
            });
            require(["jquery", "jquery.ui.widget"], function() {
                $('#btn').on('click', function() {
                    alert('JQUERY--' + $().jquery);
                    alert('JQUERY UI--' + $.ui.version);
                });
            })
            </script>
        </head>

        <body>
            <div><span>FOCUS</span>
                <input type="text" name="" id="end-date" />
            </div>
            <button id="btn" style="width: 100px; height:50px; margin:10px">click me</button>
        </body>

        </html>
Run Code Online (Sandbox Code Playgroud)

我修改了插件代码,以便它使用自己的 jquery 和 jquery ui 版本(我在这里使用 requirejs )。

另外,对于演示,我添加了一个示例合作伙伴脚本,该脚本在单击按钮时发出警报。可以看到,在不修改合作伙伴代码和requirejs配置的情况下,插件现在可以工作了。

插件和合作伙伴代码都有独立的 jquery 和 jquery ui 版本。

希望这可以帮助。

参考资料使用多个版本的 jQuery 与 Require.jshttp://requirejs.org/docs/api.html#multiversion

UPDATE3:使用 webpack 和导入加载器 我们可以使用 webpack 捆绑插件 js 代码,在这种情况下插件将有自己的 jquery 版本,我们必须更改插件的构建方式。

使用 npm 安装 webpack、jquery、导入 loader 和 jquery-ui 并构建它,下面是示例代码:

main.js使用导入加载器使定义为 false

require('imports-loader?define=>false!./app.js');
Run Code Online (Sandbox Code Playgroud)

app.js包含插件代码并添加所需的依赖项

 (function() {

     var $ = require('jquery');
     require('jquery-ui');
     require('jquery-ui/ui/widgets/datepicker.js');

     function scriptLoadHandler() {
         loadJQueryUi();
     }

     $(document).ready(function() {
         scriptLoadHandler();
     });

     function loadJQueryUi() {
         setHandlers();
         var css_link = $("<link>", {
             rel: "stylesheet",
             type: "text/css",
             href: "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css"
         });
         css_link.appendTo('head');
     }

     function setHandlers() {
         $('#end-date').on('click', function() {
             alert('JQUERY--' + $().jquery);
             alert('JQUERY UI--' + $.ui.version);
             $('#end-date').datepicker({
                 dateFormat: "M dd, yy",
                 minDate: '+1D',
                 numberOfMonths: 1,
             });
         });
     }
 })();
Run Code Online (Sandbox Code Playgroud)

webpack.config.js

  var webpack = require('webpack');

  module.exports = {
  entry: "./main.js",
  output: {
  filename: "main.min.js"
     }
  };
Run Code Online (Sandbox Code Playgroud)

示例.html

<!DOCTYPE html>
<html>

<head>
    <title></title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script> 
    <script src="main.min.js"></script> 
    <script>
    //SAMPLE PARTNER APPLICATION CODE:

    /*
    *
    *
    *
        This is partner's require config
        which uses diffrent version of jquery ui and
        jquery
    *
    *
    */
    require.config({
        paths: {
            "jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min",

            "jquery.ui.widget": "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui"

        }
    });
    require(["jquery", "jquery.ui.widget"], function() {
        $('#btn').on('click', function() {
            alert('JQUERY--' + $().jquery);
            alert('JQUERY UI--' + $.ui.version);
        });
    })
    </script>
</head>

<body>
    <div><span>FOCUS</span>
        <input type="text" name="" id="end-date" />
    </div>
    <button id="btn" style="width: 100px;"></button>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

完成 webpack 后,它将生成一个 main.min.js 文件,该文件包含在 example.html 文件中