【问题标题】:multiple versions of a script on the same page (d3.js)同一页面上的多个版本的脚本 (d3.js)
【发布时间】:2013-04-15 21:44:37
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript jquery d3.js


    【解决方案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); 
      

    【讨论】:

      【解决方案2】:

      如果你看一下主要的 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 = d3versionX 其中 X 是页面加载时可视化的默认版本
      6. 在触发版本切换的缩略图上放置一个事件处理程序,并将 d3 变量设置为适当的版本号作为发生的第一件事。

      用示例代码更新

      有关工作示例,请参阅 this 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>
      

      【讨论】:

      • 这对我们有用。很抱歉延迟接受您的回答!
      • 你能发布一个示例代码来说明你是如何让它工作的吗?我遇到了完全相同的问题,我想为页面上的两个不同图表使用两个不同版本的 D3.js。这个可以吗?
      • 您好!我也很欣赏这里的一些示例代码。我有同样的问题,这似乎是最好的解决方法。
      【解决方案3】:

      从 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";
      ...
      

      现在您可以通过d3v4 调用d3 函数。

      【讨论】:

        【解决方案4】:

        你需要使用这个一般原则

        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

        【讨论】:

        • 有没有办法创建 newD3 而不是 oldD3?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        • 2017-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多