Несколько версий script на той же странице (d3.js)

Мне нужно иметь несколько версий javascript-библиотеки на одной странице. Как это сделать, если не вручную реорганизовать одну версию, чтобы избежать конфликтов имен?

Существует много примеров того, как это сделать с помощью JQuery (пример). Однако, похоже, это связано с добротой jQuery. Как это сделать для произвольного script?

Подробнее: я использую d3.js, и я подключаю визуализации, которые другие сделали с помощью d3. Проблема в том, что для одной из задач требуется одна версия d3, другая - более новая. Обе эти визжи должны быть доступны на одной странице - пользовательские свопы, которые отображаются на экране, путем нажатия на миниатюру, а затем js используется, чтобы скрыть один из них и построить другой. Таким образом, кажется, что замена script, а не загрузка обоих в стиле без конфликтов также может быть вариантом.

Ответ 1

Если вы посмотрите на основной исходный файл d3: https://github.com/mbostock/d3/blob/master/d3.js

вы видите, что он начинается:

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

Итак, d3 - это просто объект. Я не уверен, что это лучший метод, но я думаю, что следующее будет работать:

  • включить одну версию d3
  • введите строку: d3versionX = d3;
  • включить следующую версию
  • то же, что и 2 с другим номером версии.
  • put d3 = d3versionX, где X - это ваша версия по умолчанию для визуализации, когда страница загружается
  • поместите обработчик событий на миниатюры, которые инициируют переключение версии, и установите для переменной 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>

Ответ 2

Вам необходимо использовать этот общий принцип

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();

on jsfiddle

jquery предлагает свой метод noconflict, и многие библиотеки предлагают одинаковый (не обязательно по имени) метод. Но вы можете сделать это сами, указав мой пример, в зависимости от сложности загружаемого script.

Вот как можно ввести две разные версии и использовать вышеприведенный принцип, чтобы назначить их различным переменным.

<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);

on jsfiddle

Ответ 3

Из версии d3 d3.v4 заголовок script выглядит несколько иначе. Вы можете изменить идентификатор 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.

Ответ 4

У меня была аналогичная проблема, вроде вашей, для некоторой визуализации нужен d3 v3, а другим нужен v4. Так я и добился этого.

  • Включен d3 v3 в index.html(так как большая часть моих визуализаций была на v3)
  • Включить require.js script в index.html//вы можете использовать путь cdn
  • Перейдите на JavaScript, для которого требуется v4.
  • напишите следующий код вверху.

    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);