在页面上具有相同的小部件多个时间/变量冲突

时间:2016-02-24 16:46:38

标签: javascript jquery namespaces widget

我创建了一个JavaScript / jQuery小部件,它需要能够多次嵌入页面,每个小部件都有不同的自己设置的变量。目前,由最后加载的小部件覆盖了各种变量。

这是一个减少版本,仅用于示例目的。

(function () {

    var scriptName = "my.widget.js";
    var TGW;
    var jqueryPath = "https://ajax.googleapis.com/yada_yada..."; 
    var scriptTag;
    var jScript;

    /******** Get reference to self (scriptTag) *********/
    var allScripts = document.getElementsByTagName('script');
    var targetScripts = [];
    for (var i in allScripts) {
        var name = allScripts[i].src
        if(name && name.indexOf(scriptName) > 0)
            targetScripts.push(allScripts[i]);
    }

    scriptTag = targetScripts[targetScripts.length - 1];

    /******** Set jQuery noConflict *********/
    if (window.TGW === undefined || window.TGW.fn.jquery !== jqueryVersion) {
        loadScript(jqueryPath, initTGW);
    } else {
        initTGW();
    }

    function initTGW() {
        TGW = window.jQuery.noConflict(true);
        main();
    }

    function main() {
        TGW(document).ready(function ($) {
            loadParams();
        });
    }

    function loadParams() {
        jScript = TGW(scriptTag);
        comments = jScript.data("comment");
    }

})();

以下是使用评论数据属性的不同设置将其添加到网页两次的方式。

<script src='https://...my.widget.js' data-comment='yes'></script>
<script src='https://...my.widget.js' data-comment='no'></script>

通过上述操作,如果小部件中有一个假设按钮,显示变量comments的内容,则变量将随机包含/显示&#34;是&#34;或&#34;不&#34;取决于最后加载的小部件。

按下第一个小部件上的按钮时需要发生什么,是否显示&#34;是&#34;。当按下第二个小部件上的按钮时,它会显示&#34; no&#34;。

我认为这与命名空间或其他东西有关,但我并不是真的理解它。我认为将(function () {中的整个窗口小部件作为匿名函数包含在运行中,这意味着所有变量都是独立的。

任何帮助表示赞赏

2 个答案:

答案 0 :(得分:1)

如果没有可靠的document.currentScript,您可以尝试使用以下内容替换allScripts = ....; for() {...}

var marker = 'data-r_e_a_d'; // something unique, that won't overwrite any data- attribs delivered in the HTML

var scriptTag = Array.prototype.slice.call(document.getElementsByTagName('script')).reduce(function(prev, current) {
    var tag = (!prev && !current.getAttribute(marker) && current.src && current.src.indexOf(scriptName) > 0) ? current : prev;
    if(tag === current) current.setAttribute(marker, true);//mark "self" as read
    return tag;
}, null);

将提供最新未读的合格脚本 - 即&#34; self&#34;。

在此过程中,此过程将在窗口小部件的脚本标记中留下标记属性。如果需要,可以在阅读完最后<script>后清理这些内容,但将它们留在那里应该没有任何害处。

答案 1 :(得分:0)

我相信你的scriptTag(对自我的引用)可能永远是页面上的最后一个脚本。

如果您支持较新的浏览器,则只能使用document.currentScript。否则,您可能必须为每个脚本标记分配唯一的ID, 有关获取脚本参考https://stackoverflow.com/a/22745553/4297908的不同方法,请参阅此答案。