var widget = document.createElement('script');
widget.src = "//domain.ru/load.js";
widget.type = "text/javascript";
widget.language = "javascript";
var head = document.getElementsByTagName('head')[0];
head.appendChild(widget);
(function () {
if (window.jQuery) {
window.jQuery.noConflict();
}
//тут вставляем jquery
$.ajax({...})
....
}):
(function(exports) {
console.log("Require", exports);
"use strict";
// создаем адресное пространство модуля
exports.require = load.bind(this);
/* функция загружает набор произвольных скриптов
options может содержать:
baseurl - адресс сервера на котором находятся скрипты
вида "http://server/"
если не задано берется из window.location
path - путь к папке со скриптами
вида "your/path/to/scriptd/"
если не задано берется ""
modules - массив с названиями загружаемых скриптов
вида ["script1","script2",...,"scriptN"]
onready - callback функция, вызываемая по завершении загрузки
всех модулей указанных в modules
*/
function load( options ) {
// выход если не указан ни один скрипт для загрузки
if( !options.modules )
return;
// если скрипт для загрузки указан в виде строки - переделываем в массив
if( typeof options.modules === 'string' )
options.modules = [options.modules];
// выход если скрипты для загрузки не массив
if( typeof options.modules != 'object' )
return;
// если не указан URL сервера - берем его из window.location
if( !options.baseurl || typeof options.baseurl != 'string')
options.baseurl = window.location;
// если не указан путь к скриптам - берем ""
if( !options.path || typeof options.path != 'string')
options.path = '';
// если не указана callback функция - создаем заглушку
if( !options.onready || typeof options.onready != 'function')
options.onready = function(){};
// создадим промис, который всегда выполнится
var sequence = Promise.resolve();
// Пройдемся по всем загружаемым модулям (скриптам)
for ( let name of options.modules ) {
const url =
options.baseurl
+ options.path
+ name;
// Добавляем действия с ними в конец последовательности
sequence = sequence.then( function() {
return loadScript( url );
} );
// .then(function(chapter) {
// addHtmlToPage(chapter.html);
// });
}
sequence.then( function() {
// все загрузились
options.onready();
} );
}
/* функция загружает произвольный скрипт по URL и выдает promise */
function loadScript( url ) {
let promise = new Promise( function( resolve, reject ) {
// Adding the script tag to the head as suggested before
let head = document.getElementsByTagName( 'head' )[ 0 ];
let script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = cb;
script.onload = cb;
function cb() {
resolve();
}
// Fire the loading
head.appendChild( script );
} );
return promise;
}
// создаем ссылки на функции модуля в адресном пространстве модуля
})(this.libs=this.libs||{});
<!DOCTYPE html>
<html>
<head>
<title>graph eginere</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="js/require.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
...
</body>
</html>
window.libs.require({
path: "js/",
modules: [
"polyfill.setimmediate.js",
"vector.js",
"events.js",
],
onready:()=>{
console.log("LOAD OK");
}
});
/**
* Полифил для setImmediate
* (единственное что в неизмененном виде было взято гдето в Интернете)
*/
if (!window.setImmediate) window.setImmediate = (function() {
var head = { }, tail = head; // очередь вызовов, 1-связный список
var ID = Math.random(); // уникальный идентификатор
function onmessage(e) {
if(e.data != ID) return; // не наше сообщение
head = head.next;
var func = head.func;
delete head.func;
func();
}
if(window.addEventListener) { // IE9+, другие браузеры
window.addEventListener('message', onmessage);
} else { // IE8
window.attachEvent( 'onmessage', onmessage );
}
return function(func) {
tail = tail.next = { func: func };
window.postMessage(ID, "*");
};
}());
(function(exports) {
console.log("Flow.Events");
"use strict";
/**
* класс емиттера событий(почти eventemitter)
* содержит функции on, once и emit
*/
exports.Events = Events;
function Events(){
// конструктор
//console.log("Events.constructor");
this.e = { };
};
/**
* Установить слушатель для события @name
* @param {String} name стороковый идентификатор события
* @param {Function} cb функция-слушатель. Вызывается при возникновении события @name
* @param {Number} timeout функция-слушатель может быть вызвана 3-я разными способами
* 1. незамедлительно при возникновении события (timeout не задан)
* 2. асинхронно, с незначительной отсрочкой (timeout равен 0)
* 3. асинхронно, через установленный интервал времени (timeout больше 0)
* @param {Boolean} isOnce если true, то слушатель будет вызван 1 раз, после чего будет удален
* @return {Function} функция, вызов которой удалит слушателя.
*/
Events.prototype.on = function(name, cb, timeout, isOnce) {
if (typeof cb !== 'function')
throw new Error('listener is not a function');
const e = this.e[name] = this.e[name]||[];
const d = this.mode(timeout);
if(isOnce) d.isOnce = true;
d.cb = cb;
e.push(d);
return function () {
const i = e.indexOf(d);
if(i!==-1) e.splice(i, 1);
}
};
/**
* вычислить режим вызова обработчиков события
* @param {Number} timeout функция-слушатель может быть вызвана 3-я разными способами
* 1. незамедлительно при возникновении события (timeout не задан)
* 2. асинхронно, с незначительной отсрочкой (timeout равен 0)
* 3. асинхронно, через установленный интервал времени (timeout больше 0)
* @return {Function} Объект, может содержать поля поля timeout и isTimeout или isAsync или isSync
*/
Events.prototype.mode = function(timeout) {
const d = {};
if(typeof timeout === "number"){
if(timeout>0){
d.timeout = Math.ceil(timeout);
d.isTimeout = true;
}
else d.isAsync = true;
}
else d.isSync = true;
return d;
};
/**
* установить глобальный режим вызова обработчиков события
* @param {Number} timeout функция-слушатель может быть вызвана 3-я разными способами
* 1. незамедлительно при возникновении события (timeout не задан)
* 2. асинхронно, с незначительной отсрочкой (timeout равен 0)
* 3. асинхронно, через установленный интервал времени (timeout больше 0)
*/
Events.prototype.setmode = function(timeout) {
this.m = this.mode(timeout);
};
/**
* отменить глобальный режим вызова обработчиков события
*/
Events.prototype.clearmode = function() {
this.m = undefined;
};
/**
* Установить одноразовый слушатель для события @name
* @param {String} name стороковый идентификатор события
* @param {Function} cb функция-слушатель. Вызывается при возникновении события @name
* @param {Number} timeout функция-слушатель может быть вызвана 3-я разными способами
* 1. незамедлительно при возникновении события (timeout не задан)
* 2. асинхронно, с незначительной отсрочкой (timeout равен 0)
* 3. асинхронно, через установленный интервал времени (timeout больше 0)
*/
Events.prototype.once = function(name, cb, timeout) {
const off = this.on(name, function(){
off();
cb.apply(this,arguments);
}, timeout,true);
};
/**
* Вызвать всех слушателей для события @name
* @param {String} name стороковый идентификатор события
*/
Events.prototype.emit = function(name) {
const e = this.e[name];
if(!e || !e.length) return;
const args = [].slice.call(arguments,1);
e.some( function(l) {
if(l.isEmitted) return;
if(l.isOnce) l.isEmitted = true;
const mode = this.m||l;
if(mode.isTimeout) {
setTimeout(function() { l.cb.apply(this, args); }, mode.timeout);
} else if(mode.isAsync) {
window.setImmediate(function() { l.cb.apply(this, args); });
} else {
l.cb.apply(this, args);
}
const event = args[0];
if(event.__stopImmediatePropagation) return true;
return false;
});
};
})(this.libs=this.libs||{});