현재 실행중인 스크립트를로드 한 스크립트 태그를 어떻게 참조합니까?
현재 실행중인 자바 스크립트를로드 한 스크립트 요소를 어떻게 참조 할 수 있습니까?
상황은 다음과 같습니다. HEAD 태그 아래에 페이지에 "마스터"스크립트가 많이로드되어 있습니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>
"scripts.js"에는 다른 스크립트를 요청시로드 할 수있는 스크립트가 있습니다. HEAD 요소가 렌더링을 완료하지 않았기 때문에 HEAD 태그를 참조하지 않고 새 스크립트를 추가해야하기 때문에 일반적인 방법은 제대로 작동하지 않습니다.
document.getElementsByTagName('head')[0].appendChild(v);
내가하고 싶은 것은 현재 스크립트를로드 한 스크립트 요소를 참조하여 동적으로로드 된 새로운 스크립트 태그를 DOM에 추가 할 수 있습니다.
<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>
현재 스크립트 요소를 얻는 방법 :
1. 사용 document.currentScript
document.currentScript
<script>
스크립트가 현재 처리되고 있는 요소를 반환합니다 .
<script>
var me = document.currentScript;
</script>
혜택
- 간단하고 명시 적입니다. 신뢰할 수 있습니다.
- 스크립트 태그를 수정할 필요가 없습니다
- 비동기 스크립트 (
defer
&async
) 와 함께 작동 - 스크립트를 동적으로 삽입 한 상태에서 작동
문제
- 이전 브라우저 및 IE에서는 작동하지 않습니다.
- 모듈과 작동하지 않습니다
<script type="module">
2. 아이디로 스크립트를 선택
스크립트에 id 속성을 부여하면를 사용하여 id별로 쉽게 스크립트를 선택할 수 있습니다 document.getElementById()
.
<script id="myscript">
var me = document.getElementById('myscript');
</script>
혜택
- 간단하고 명시 적입니다. 신뢰할 수 있습니다.
- 거의 보편적으로 지원
- 비동기 스크립트 (
defer
&async
) 와 함께 작동 - 스크립트를 동적으로 삽입 한 상태에서 작동
문제
- 스크립트 태그에 맞춤 속성을 추가해야합니다.
id
일부 브라우저에서는 속성이 일부 브라우저에서 이상한 동작을 일으킬 수 있습니다.
3. data-*
속성을 사용하여 스크립트를 선택하십시오
스크립트에 data-*
속성을 부여하면 내부에서 쉽게 선택할 수 있습니다.
<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>
이전 옵션에 비해 이점이 거의 없습니다.
혜택
- 간단하고 명시 적입니다.
- 비동기 스크립트 (
defer
&async
) 와 함께 작동 - 스크립트를 동적으로 삽입 한 상태에서 작동
문제
- 스크립트 태그에 맞춤 속성을 추가해야합니다.
querySelector()
모든 브라우저에서 호환되지 않는 HTML5id
속성을 사용하는 것보다 덜 널리 지원- 주위에 얻을 것이다
<script>
으로id
가장자리의 경우. - 다른 요소가 페이지에서 동일한 데이터 속성 및 값을 갖는 경우 혼동 될 수 있습니다.
4. src로 스크립트를 선택하십시오
데이터 속성을 사용하는 대신 선택기를 사용하여 소스별로 스크립트를 선택할 수 있습니다.
<script src="//example.com/embed.js"></script>
embed.js에서 :
var me = document.querySelector('script[src="//example.com/embed.js"]');
혜택
- 신뢰성
- 비동기 스크립트 (
defer
&async
) 와 함께 작동 - 스크립트를 동적으로 삽입 한 상태에서 작동
- 맞춤 속성이나 ID가 필요하지 않습니다
문제
- 않습니다 하지 로컬 스크립트에 대한 작업
- 개발 및 생산과 같은 다른 환경에서 문제를 일으킬 것
- 정적이고 깨지기 쉬운. 스크립트 파일의 위치를 변경하려면 스크립트를 수정해야합니다
id
속성을 사용하는 것보다 덜 널리 지원- 동일한 스크립트를 두 번로드하면 문제가 발생합니다
5. 모든 스크립트를 반복하여 원하는 스크립트를 찾으십시오.
또한 모든 스크립트 요소를 반복하고 각각 개별적으로 검사하여 원하는 요소를 선택할 수 있습니다.
<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
if( isMe(scripts[i])){
me = scripts[i];
}
}
</script>
이를 통해 querySelector()
속성을 제대로 지원하지 않는 이전 브라우저에서 이전 기술을 모두 사용할 수 있습니다 . 예를 들면 다음과 같습니다.
function isMe(scriptElem){
return scriptElem.getAttribute('src') === "//example.com/embed.js";
}
이것은 어떤 접근 방식의 이점과 문제를 물려 받지만 의존하지는 않지만 querySelector()
이전 브라우저에서 작동합니다.
6. 마지막으로 실행 된 스크립트를 얻습니다
스크립트는 순차적으로 실행되므로 마지막 스크립트 요소는 현재 현재 실행중인 스크립트 인 경우가 많습니다.
<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>
혜택
- 단순한.
- 거의 보편적으로 지원
- 맞춤 속성이나 ID가 필요하지 않습니다
문제
- 않습니다 하지 비동기 스크립트 작업 (
defer
&async
) - 않습니다 하지 동적으로 삽입 된 스크립트 작업
스크립트는 순차적으로 실행되므로 현재 실행중인 스크립트 태그는 그 때까지 페이지에서 항상 마지막 스크립트 태그입니다. 따라서 스크립트 태그를 얻으려면 다음을 수행하십시오.
var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
아마도 가장 쉬운 방법은 스크립 태그에 id
속성 을 부여하는 것입니다.
스크립트는 "지연"또는 "비동기"속성이없는 경우에만 순차적으로 실행됩니다. 스크립트 태그의 가능한 ID / SRC / TITLE 속성 중 하나를 아는 경우에도 작동 할 수 있습니다. 따라서 Greg와 Justin의 제안은 모두 맞습니다.
document.currentScript
WHATWG 목록에 대한 제안이 이미 있습니다 .
편집 : Firefox> 4는 이미이 매우 유용한 속성을 구현하지만 IE11에서는 사용할 수 없으며 마지막으로 확인했으며 Chrome 29 및 Safari 8에서만 사용할 수 있습니다.
편집 : 아무도 "document.scripts"컬렉션을 언급하지 않았지만 다음은 현재 실행중인 스크립트를 얻는 데 좋은 크로스 브라우저 대안 일 수 있다고 생각합니다.
var me = document.scripts[document.scripts.length -1];
다음은 폴리 필이있는 document.CurrentScript
경우 활용 하고 ID로 스크립트를 찾는 것입니다.
<script id="uniqueScriptId">
(function () {
var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');
// your code referencing thisScript here
());
</script>
모든 스크립트 태그의 맨 위에 이것을 포함하면 어떤 스크립트 태그가 실행되고 있는지 지속적으로 알 수 있으며 비동기 콜백의 맥락에서 스크립트 태그를 참조 할 수 있다고 생각합니다.
테스트를 거치지 않았으므로 다른 사람에게 피드백을 남겨주세요.
페이지로드 및 스크립트 태그가 자바 스크립트 (예 : 아약스)로 추가 될 때 작동해야합니다.
<script id="currentScript">
var $this = document.getElementById("currentScript");
$this.setAttribute("id","");
//...
</script>
현재 실행중인 스크립트 블록에 대한 참조를 얻으려면 다음 간단한 단계를 수행하십시오.
- 스크립트 블록 내에 임의의 고유 한 문자열을 넣습니다 (각 스크립트 블록마다 고유해야 함)
- document.getElementsByTagName ( 'script')의 결과를 반복하여 각 내용에서 고유 한 문자열을 확인합니다 (innerText / textContent 속성에서 가져옴).
예 (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
비동기 및 지연된 스크립트를 처리하는 방법은 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
이 알고리즘을 고려하십시오. 스크립트가로드되면 (여러 개의 동일한 스크립트가있는 경우) document.scripts를 살펴보고 올바른 "src"속성을 가진 첫 번째 스크립트를 찾아서 저장 한 후 데이터 속성 또는 고유 한 className으로 '방문'으로 표시하십시오.
다음 스크립트가로드되면 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 알고리즘과 유사합니다.
스크립트의 파일 이름을 가정하면 찾을 수 있습니다. 지금까지 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');
FF3, IE6 & 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 );
}
다음 코드가 가장 일관되고 성능이 뛰어나고 간단한 것으로 나타났습니다.
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);
'Programing' 카테고리의 다른 글
PEM 인코딩 인증서에서 SSL 인증서 만료 날짜를 결정하는 방법은 무엇입니까? (0) | 2020.03.28 |
---|---|
Java 문자열에서 선행 및 후행 공백 제거 (0) | 2020.03.28 |
파이썬에서 여러 공백을 단일 공백으로 대체 (0) | 2020.03.28 |
fs.readFile에서 데이터 가져 오기 (0) | 2020.03.28 |
scp 또는 sftp는 단일 명령으로 여러 파일을 복사합니다 (0) | 2020.03.27 |