17

我需要在同一页面上有多个版本的 javascript 库。除了手动重构一个版本以避免命名冲突之外,我该如何实现这一点?

有很多关于如何使用 Jquery 执行此操作的示例(示例)。然而,这似乎依赖于 jQuery 的优点。如何为任意脚本执行此操作?

更多细节:我正在使用d3.js,并且我正在插入其他人使用 d3 制作的可视化。问题是,其中一个可视化需要一个 d3 版本,另一个需要更新版本。这两个可视化应该在同一页面上可用 - 用户通过单击缩略图交换显示哪个可视化,然后使用 js 隐藏一个可视化并构建另一个可视化。因此,似乎也可以选择交换脚本而不是以无冲突的方式加载两者。

4

4 回答 4

26

如果您看一下主要的 d3 源文件:https ://github.com/mbostock/d3/blob/master/d3.js

你看到它开始了:

d3 = function() {
  var d3 = {
    version: "3.1.5"
  };
  //.....

所以 d3 只是一个对象。我不确定这是否是最好的方法,但我认为以下方法可行:

  1. 包括一个版本的 d3
  2. 把这条线:d3versionX = d3;
  3. 包括下一个版本
  4. 与 2 相同,但版本号不同。
  5. d3 = d3versionXX 放置在页面加载时可视化的默认版本的位置
  6. 在触发版本切换的缩略图上放置一个事件处理程序,并将 d3 变量设置为适当的版本号作为发生的第一件事。

使用示例代码更新

有关工作示例,请参阅此 jsbin 。相关代码:

  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
  <script>
    d3version4 = d3
    window.d3 = null
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
  <script>
    d3version3 = d3
    window.d3 = null
    // test it worked
    console.log('v3', d3version3.version)
    console.log('v4', d3version4.version)
  </script>
于 2013-04-22T20:57:00.320 回答
1

我遇到了和你类似的问题,一些可视化需要 d3 v3,而另一些需要 v4。这就是我实现它的方式。

  1. 在 index.html 中包含 d3 v3(因为我的大部分可视化都在 v3 上)
  2. 在 index.html 上包含 require.js 脚本 //你可以使用 cdn 路径
  3. 转到需要 v4 的 JavaScript。
  4. 在顶部写下以下代码。

    function graphicviz(id) {   
        require.config({
            paths: {
                d3: "https://d3js.org/d3.v4.min"
            }
        });
    
        require(["d3"], function(d3) {
            //... D3 Code Here...
        });
    }
    
    //Call The Function
    graphicviz(id); 
    
于 2017-08-01T12:01:34.327 回答
0

你需要使用这个一般原则

var x = {
    version: 1,
    alert1: function() {
        alert("1hi1");
    },
    alert2: function() {
        alert("1hi2");
    }
};

var y = x;

var x = {
    version: 2,
    alert1: function() {
        alert("2hi1");
    },
    alert2: function() {
        alert("2hi2");
    }
};

y.alert1();
x.alert1();

jsfiddle上

jquery 提供了它的noconflict方法,许多库提供了相同的(不一定是名称)方法。但是您可以通过参考我的示例自己完成,具体取决于您正在加载的脚本的复杂性。

以下是如何注入 2 个不同的版本,并使用上述原理将它们分配给不同的变量。

<div id="version1"></div>
<div id="version2"></div>

var script1 = document.createElement("script"),
    script2 = document.createElement("script"),
    oldD3;

function noConflict() {
    oldD3 = d3;
    console.log("loaded old");
    script2.type = 'text/javascript';
    script2.src = "http://d3js.org/d3.v3.min.js";
    script2.addEventListener("load", ready, false);
    document.head.appendChild(script2);
}

function ready() {
    console.log("loaded new");
    console.log(d3, oldD3);
    document.getElementById("version1").textContent = oldD3.version;
    document.getElementById("version2").textContent = d3.version;
}

script1.type = 'text/javascript';
script1.src = "http://d3js.org/d3.v2.min.js";
script1.addEventListener("load", noConflict, false);
document.head.appendChild(script1);

jsfiddle上

于 2013-04-22T20:57:20.870 回答
0

从 d3 版本 d3.v4 开始,脚本的标题看起来有点不同。您可以将标识符global.d3更改为global.d3v4,使其看起来像这样

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (factory((global.d3v4 = global.d3v4 || {})));
}(this, (function (exports) { 'use strict';

var version = "4.8.0";
...

现在你可以调用d3函数了d3v4

于 2017-05-12T15:28:39.767 回答