Имейте в виду, что независимо от сценария причина всегда одинакова в .NET:
Вы пытаетесь использовать ссылочную переменную, значение которой
Nothing
/null
. Если для ссылочной переменной значениеNothing
/null
, это означает, что на самом деле оно не содержит ссылку на экземпляр любого объекта, который существует в куче.Вы либо никогда не присваивали какую-либо переменную, никогда не создавали экземпляр значения, присвоенного переменной, или вы вручную устанавливали переменную, равную
blockquote>Nothing
/null
, или вы вызывали функцию, которая установите для этой переменной значениеNothing
/null
.
Вот немного polyfill, который использует document.CurrentScript
, если он существует, и возвращается к поиску скрипта по идентификатору.
<script id="uniqueScriptId">
(function () {
var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');
// your code referencing thisScript here
());
</script>
Если вы включите это в начало каждого тега скрипта, я верю вы сможете точно знать, какой скриптовый тег уволен, и вы также сможете ссылаться на тег сценария в контексте асинхронного обратного вызова.
Не проиндексирован, поэтому оставляйте отзыв для других, если вы пытаетесь это сделать.
Поскольку сценарии выполняются последовательно, текущий исполняемый тег скрипта всегда является последним тегом скрипта на странице до тех пор. Итак, чтобы получить тег скрипта, вы можете сделать:
var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
Сценарий выполняется последовательно, только если у них нет атрибута «отложить» или «асинхронный». Знание одного из возможных атрибутов ID / SRC / TITLE тега скрипта также может работать в этих случаях. Итак, оба предложения Грега и Джастина верны.
В списке WHATWG уже есть предложение для document.currentScript
.
EDIT: Firefox> 4 уже реализует это очень полезное свойство, но он недоступен в IE11, который последний раз я проверял и доступен только в Chrome 29 и Safari 8.
EDIT: Никто не упомянул коллекцию document.scripts, но я считаю, что следующая альтернатива может быть хорошей альтернативой перекрестного браузера для запуска текущего скрипта:
var me = document.scripts[document.scripts.length -1];
Следуйте этим простым шагам, чтобы получить ссылку на текущий исполняемый блок сценариев:
Пример (ABCDE345678 является уникальным ID) :
<script type="text/javascript">
var A=document.getElementsByTagName('script'),i=count(A),thi$;
for(;i;thi$=A[--i])
if((thi$.innerText||thi$.textContent).indexOf('ABCDE345678'))break;
// Now thi$ is refer to current script block
</script>
btw, для вашего случая вы можете просто использовать старомодный метод document.write () для включения другого скрипта. Поскольку вы упомянули, что DOM пока не отображается, вы можете воспользоваться тем фактом, что браузер всегда выполняет скрипт в линейной последовательности (за исключением отложенного, который будет отображаться позже), поэтому остальная часть вашего документа по-прежнему «не существует». Все, что вы пишете через document.write (), будет размещено сразу после сценария вызывающего абонента.
Пример исходной HTML-страницы :
<!doctype html>
<html><head>
<script src="script.js"></script>
<script src="otherscript.js"></script>
<body>anything</body></html>
Содержание script.js :
document.write('<script src="inserted.js"></script>');
После визуализации структура DOM станет:
HEAD
SCRIPT script.js
SCRIPT inserted.js
SCRIPT otherscript.js
BODY
Вероятно, проще всего было бы дать вашему тегу скрипта атрибут id
.
Он должен работать при загрузке страницы и при добавлении тега скрипта с помощью javascript (например, с ajax)
<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>
Если вы можете считать имя файла сценария, вы можете его найти. До сих пор я только что протестировал следующую функцию в Firefox.
function findMe(tag, attr, file) {
var tags = document.getElementsByTagName(tag);
var r = new RegExp(file + '$');
for (var i = 0;i < tags.length;i++) {
if (r.exec(tags[i][attr])) {
return tags[i][attr];
}
}
};
var element = findMe('script', 'src', 'scripts.js');
Рассмотрим этот алгоритм. Когда ваш скрипт загружается (если есть несколько идентичных скриптов), просмотрите document.scripts, найдите первый скрипт с правильным атрибутом «src» и сохраните его и пометьте как «посещенный» атрибутом данных или уникальным именем класса.
Когда следующий скрипт загружается, снова сканируйте документы document.scripts, передавая любой скрипт, уже отмеченный как посещенный. Возьмите первый невидимый экземпляр этого скрипта.
Предполагается, что идентичные сценарии, скорее всего, выполняются в том порядке, в котором они загружаются, от головы до тела, сверху вниз, от синхронного до асинхронного.
(function () {
var scripts = document.scripts;
// Scan for this data-* attribute
var dataAttr = 'data-your-attribute-here';
var i = 0;
var script;
while (i < scripts.length) {
script = scripts[i];
if (/your_script_here\.js/i.test(script.src)
&& !script.hasAttribute(dataAttr)) {
// A good match will break the loop before
// script is set to null.
break;
}
// If we exit the loop through a while condition failure,
// a check for null will reveal there are no matches.
script = null;
++i;
}
/**
* This specific your_script_here.js script tag.
* @type {Element|Node}
*/
var yourScriptVariable = null;
// Mark the script an pass it on.
if (script) {
script.setAttribute(dataAttr, '');
yourScriptVariable = script;
}
})();
Это сканирует весь скрипт для первого сопоставимого скрипта, который не помечен специальным атрибутом.
Затем отметьте этот узел, если он найден, с атрибутом данных поэтому последующие сканирования не будут выбирать его. Это похоже на алгоритмы BFS и DFS с обходным трафиком, где узлы могут быть помечены как «посещенные», чтобы предотвратить повторный просмотр.
Подход для решения проблемы с асинхронным и отложенные сценарии - использовать обработчик onload - установить обработчик onload для всех тегов скриптов, а первый из них должен быть вашим.
function getCurrentScript(callback) {
if (document.currentScript) {
callback(document.currentScript);
return;
}
var scripts = document.scripts;
function onLoad() {
for (var i = 0; i < scripts.length; ++i) {
scripts[i].removeEventListener('load', onLoad, false);
}
callback(event.target);
}
for (var i = 0; i < scripts.length; ++i) {
scripts[i].addEventListener('load', onLoad, false);
}
}
getCurrentScript(function(currentScript) {
window.console.log(currentScript.src);
});
Чтобы получить скрипт, загруженный в настоящий момент скриптом, вы можете использовать
var thisScript = document.currentScript;
. Вам нужно сохранить ссылку в начале вашего скрипта, чтобы вы могли позвонить позже
var url = thisScript.src
Я нашел следующий код наиболее согласованным, показательным и простым.
var scripts = document.getElementsByTagName('script');
var thisScript = null;
var i = scripts.length;
while (i--) {
if (scripts[i].src && (scripts[i].src.indexOf('yourscript.js') !== -1)) {
thisScript = scripts[i];
break;
}
}
console.log(thisScript);
У меня есть это, которое работает в FF3, IE6 & amp; 7. Методы в загружаемых сценариях по запросу недоступны до тех пор, пока загрузка страницы не будет завершена, но это все еще очень полезно.
//handle on-demand loading of javascripts
makescript = function(url){
var v = document.createElement('script');
v.src=url;
v.type='text/javascript';
//insertAfter. Get last <script> tag in DOM
d=document.getElementsByTagName('script')[(document.getElementsByTagName('script').length-1)];
d.parentNode.insertBefore( v, d.nextSibling );
}
id
является недопустимым в элементеscript
. Какие проблемы могут возникнуть при таком подходе? – n.r. 19 January 2018 в 18:14