<script> 요소를 추가 할 수 없습니다


276

아래 코드가 왜 script 요소를 DOM에 추가하지 않는지 아십니까?

var code = "<script></script>";
$("#someElement").append(code);

4
"작동하지 않음"을 정의하십시오. 문제는 스크립트가 실제로 돔 트리의 일부가 아니라고 생각합니다.
Joel Coehoorn 2016 년

1
내 생각은 스크립트 노드가 DOM에 추가되고 있지만 브라우저는 스크립트를 실행하지 않는다는 것입니다.
무법자 프로그래머

댄, 이걸 어떻게 실제로 시험 했어?
James

1
@Joel- "작동하지 않음"= 아무런 영향을 미치지 않습니다. 즉, 스크립트 내의 코드가 @Outlaw Programmer가 실행되지 않습니다.-노드가 DOM에 추가되지 않았습니다. @Jimmy 예, 테스트했으며 작동하지 않습니다
Dan Burzo

답변:


259

일부 브라우저는 직접 수행 할 때 일부 변경 사항을 존중하지 않는 문제를 보았습니다 (스크립트 태그를 사용하는 것처럼 텍스트에서 HTML을 만드는 것을 의미합니다). 내장 명령으로 수행 할 때 상황이 좋아집니다. 이 시도:

var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );

보낸 사람 : jQuery 용 JSON


18
<script> 태그는 기존 요소의 innerHTML이 아니라 DOM 자체에 추가해야합니다.
Diodeus-James MacFarlane 2016 년

6
@Diodeus innerHTML은 DOM의 일부이며 브라우저에서 즉시 구문 분석되므로 유효한 경우입니다.
크리스티안 토마


5
요소를 DOM에 실제로 표시하려면 jQuery의 추가를 사용하지 마십시오. 이를 위해 native appendChild를 사용하십시오.
Minqi Pan

8
$("#someElement")[0].appendChild( script );
Minqi Pan

352

좋은 소식은 :

100 % 효과가 있습니다.

스크립트 태그 안에와 같은 것을 추가하십시오 alert('voila!');. 아마도 "DOM에서 왜 보지 못했습니까?" .

Karl Swedberg는 jQuery API 사이트 에서 방문자의 의견을 잘 설명했습니다 . 내가 하지 , 직접 읽을 수있는 그의 모든 단어를 반복 할 여기에 (내가 코멘트를 탐색 할 하드를가 있음) .

모든 jQuery의 삽입 메소드는 내부적으로 domManip 함수를 사용하여 요소를 DOM에 삽입하기 전후에 요소를 정리 / 처리합니다. domManip 함수가 수행하는 작업 중 하나는 삽입 할 스크립트 요소를 가져 와서 나머지 DOM 프래그먼트에 삽입하는 대신 "evalScript 루틴"을 통해 실행하는 것입니다. 스크립트를 개별적으로 삽입하고 평가 한 다음 DOM에서 제거합니다.

jQuery가 수행하는 이유 중 하나는 특정 상황에서 스크립트를 삽입 할 때 Internet Explorer에서 발생할 수있는 "Permission Denied"오류를 방지하기위한 것입니다. 또한 삽입하고 DOM 주위를 이동하는 포함 요소 내에있는 경우 동일한 스크립트를 반복적으로 삽입 / 평가할 수 있습니다 (문제가 발생할 수 있음).

다음은 .append()함수를 사용하여 스크립트를 추가 하여 나쁜 소식이 무엇인지 요약하겠습니다 .


그리고 나쁜 소식은 ..

코드를 디버깅 할 수 없습니다.

난 당신이 추가 할 경우에도, 농담 아니에요 debugger;당신이 중단 점으로 설정할 라인 사이의 키워드, 당신은 소스 코드에 중단 점을 보지 않고 객체의 호출 스택을 그만 둘 수 있습니다 이 있음을 언급 (하지 키워드는 웹킷 브라우저에서만 작동하며 다른 모든 주요 브라우저는이 키워드를 생략 한 것 같습니다 .

코드의 기능을 완전히 이해하면 약간의 단점이 있습니다. 그러나 그렇지 않으면 debugger;코드 (또는 내 코드)에 문제가 있는지 찾기 위해 모든 곳에 키워드 를 추가하게됩니다 . 어쨌든 대안이 있습니다. 자바 스크립트가 HTML DOM을 기본적으로 조작 할 수 있다는 것을 잊지 마십시오.


해결 방법.

jQuery가 아닌 javascript를 사용하여 HTML DOM 조작

디버깅 기능을 잃고 싶지 않다면 자바 스크립트 네이티브 HTML DOM 조작을 사용할 수있는 것보다 낫습니다. 이 예제를 고려하십시오.

var script   = document.createElement("script");
script.type  = "text/javascript";
script.src   = "path/to/your/javascript.js";    // use this for linked script
script.text  = "alert('voila!');"               // use this for inline script
document.body.appendChild(script);

옛날처럼 그렇지 않습니다. 또한 메모리 누수를 방지하기 위해 더 이상 참조되지 않고 참조되지 않는 모든 객체에 대해 DOM 또는 메모리에서 작업을 정리하는 것을 잊지 마십시오. 이 코드를 고려하여 정리할 수 있습니다.

document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.

이 해결 방법의 단점은 실수로 중복 스크립트를 추가 할 수 있다는 것입니다. 여기 .append()에서 객체 검증을 추가하기 전에 추가하고 DOM에서 스크립트를 추가 한 직후 제거하여 기능을 약간 모방 할 수 있습니다 . 이 예제를 고려하십시오.

function AddScript(url, object){
    if (object != null){
        // add script
        var script   = document.createElement("script");
        script.type  = "text/javascript";
        script.src   = "path/to/your/javascript.js";
        document.body.appendChild(script);

        // remove from the dom
        document.body.removeChild(document.body.lastChild);
        return true;
    } else {
        return false;
    };
};

function DeleteObject(UnusedReferencedObjects) {
    delete UnusedReferencedObjects;
}

이런 방식으로 스크립트 중복으로부터 안전하면서 디버깅 기능이있는 스크립트를 추가 할 수 있습니다. 이것은 프로토 타입 일 뿐이므로 원하는대로 확장 할 수 있습니다. 나는이 접근법을 사용하고 있으며 이것에 상당히 만족합니다. 물론 jQuery .append()를 사용 하여 스크립트를 추가 하지는 않을 것 입니다.


2
좋은 설명 감사합니다! 그러나 "UnusedReferencedObjects"입니까?
acme

감사. "UnusedReferencedObjects"의 첫 번째 항목을 참조한다고 가정합니다.이 스크립트는 사용자가로드하는 스크립트에서 생성 한 모든 개체로 간주됩니다. DeleteObject 함수가 무엇을하는지 알면 더 잘 이해한다고 생각합니다. 함수에 전달 된 모든 객체를 삭제합니다. 명확하게하기 위해 코드에 주석을 추가 할 것입니다. :)
Hendra Uzia

슈퍼 포스트! aCrosman의 예는 효과가 없었으며 게시물을 준비한 후 $ ( "# someElement"). append (script); with $ ( "# someElement") [0] .appendChild (스크립트); 그것이 수정 :) 외식을위한 Thnx
Maarten Kieft

7
$.getScriptjQuery에 내장되어 있습니다.
zzzzBov 2019

소스 URL ( blog.getfirebug.com/2009/08/11/… )은 디버깅 문제를 해결하는 데 도움이 될 수 있습니다.
vsevik

23

jQuery 함수를 사용하여 JavaScript 파일을 동적으로로드 할 수 있습니다getScript

$ .getScript ( 'http://www.whatever.com/shareprice/shareprice.js', function () {
  Display.sharePrice ();
});

이제 외부 스크립트가 호출되고로드 할 수 없으면 정상적으로 저하됩니다.


7
이것은 DOM에 아무것도 삽입하지 않습니다. 호출합니다 eval().
nh2

20

"작동하지 않는다"는 것은 무엇을 의미합니까?

jQuery는 SCRIPT 요소를 만들려고 시도하고 전역 컨텍스트 내에서 요소의 내용을 자동으로 실행합니다. 이것이 효과가 없다고 말하고 있습니까? -

$('#someElement').append('<script>alert("WORKING");</script>');

편집 : 명령을 실행 한 후 DOM에 SCRIPT 요소가 표시되지 않으면 (예 : Firebug) jQuery가 말했듯이 코드를 실행 한 다음 SCRIPT 요소를 삭제하기 때문에 SCRIPT 요소가 있다고 생각합니다. 항상 본문에 추가되지만 ... 어쨌든 배치는이 상황에서 코드 실행과 전혀 관련이 없습니다.


17

이것은 작동합니다 :

$('body').append($("<script>alert('Hi!');<\/script>")[0]);

jQuery가 스크립트로 영리한 일을하는 것처럼 보이므로 jQuery 객체 대신 html 요소를 추가해야합니다.


2
이것이 내 경우에 작동하는 유일한 솔루션입니다. 위의 다른 솔루션은 html 파일에 미리 존재하는 자바 스크립트 코드에 달려 있습니다. 코드를 동적으로 추가하기 때문에 이러한 자바 스크립트 코드를 미리 알 수 없습니다! 감사합니다 Darwin !!
tgoneil

14

도움이 될 수 있습니다.

var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);

9
왜이 사람이 부정적인 것을 알지 못했는지 모든 것을 위해 jquery를 계속 사용할만큼 바보가 아닙니다!
SSpoke

OP에서 jQuery를 사용하고 있기 때문에 대부분의 답변은 jQuery를 사용합니다.
sanbor

3

같은 일을하고 싶지만 다른 프레임에 스크립트 태그를 추가하고 싶습니다!

var url = 'library.js'; 
var script = window.parent.frames[1].document.createElement('script' ); 
script.type = 'text/javascript'; 
script.src = url;
$('head',window.parent.frames[1].document).append(script);

3
<script>
    ...
    ...jQuery("<script></script>")...
    ...
</script>

</script>문자열 리터럴 종료 전체 스크립트 내에서 그 피하기 위해 "</scr" + "ipt>"대신 사용할 수 있습니다.


또는 자바 스크립트를 HTML 문서에 직접 포함하지 마십시오. 외부 스크립트 파일에는이 문제가 없습니다.
Ian Clelland

이스케이프 시퀀스 : "\x3cscript\x3e\x3c/script\x3e". XHTML에서는 주석 처리 된 CDATA 블록 만 입력하면됩니다.
Eli Gray

2
오히려 </허용되지 않는 것입니다. 참조 stackoverflow.com/questions/236073/...
검보


1

스크립트가 실행 중이므로 사용할 수 없습니다 document.write. 경고를 사용하여 테스트하고 사용을 피하십시오 document.write. js 파일의 명령문은 document.write실행되지 않으며 나머지 함수는 실행됩니다.


1

이것이 최선의 해결책이라고 생각합니다. 이런 식으로 Google Analytics가 주입됩니다.

var (function(){
    var p="https:" == document.location.protocol ? "https://" : "http://";
        d=document,
        g=d.createElement('script'),
        s=d.getElementsByTagName('script')[0];
        g.type='text/javascript';
        g.src=p+'url-to-your-script.js';
        s.parentNode.insertBefore(g,s); })();

1

스크립트 DOM 요소 를 생성하기 위해 jQuery가 필요하지 않습니다 . 바닐라 ES6로 다음과 같이 수행 할 수 있습니다.

const script = "console.log('Did it work?')"
new Promise((resolve, reject) => {
  (function(i,s,o,g,r,a,m){
      a=s.createElement(o),m=s.getElementsByTagName(o)[0];
      a.innerText=g;
      a.onload=r;m.parentNode.insertBefore(a,m)}
  )(window,document,'script',script, resolve())
}).then(() => console.log('Sure did!'))

에 싸일 필요는 없지만 Promise스크립트가로드 될 때 약속을 해결하여 장기 실행 스크립트의 경쟁 조건을 방지 할 수 있습니다.


0

본문에 스크립트 추가 :

$(document).ready(function() {
    $("<script>", {  src : "bootstrap.min.js",  type : "text/javascript" }).appendTo("body");
});

0

코드를 추가하려는 경우 다른 방법으로 document.createElement메소드를 사용하고 .innerHTML대신 을 사용하는 것입니다 .src.

var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.innerHTML = 'alert("Hey there... you just appended this script to the body");';
$("body").append( script );

0

나는이 시도 하나 와 작품의 벌금을. 그냥 대체 <그와 기호를 \x3C.

// With Variable
var code = "\x3Cscript>SomeCode\x3C/script>";
$("#someElement").append(code);

또는

//Without Variable
$("#someElement").append("\x3Cscript>SomeCode\x3C/script>");

여기 에서 코드를 테스트 할 수 있습니다 .


0

이렇게 시도해 볼 수 있습니다

var code = "<script></" + "script>";
$("#someElement").append(code);

"<script></script>"DOM 레이어가 js와 HTML을 구문 분석 할 수 없기 때문에 문자열이 자바 스크립트 내에서 허용되지 않기 때문에 할 수없는 유일한 이유 입니다.


0

스크립트 태그를 포함npm 하여 HTML 문자열을 가져 와서 스크립트실행하는 동안 컨테이너에 추가 할 수 있는 패키지를 작성했습니다.

예:

import appendHtml from 'appendhtml';

const html = '<p>Hello</p><script src="some_js_file.js"></script>'; 
const container = document.getElementById('some-div');

await appendHtml(html, container);

// appendHtml returns a Promise, some_js_file.js is now loaded and executed (note the await)

여기에서 찾으십시오 : https://www.npmjs.com/package/appendhtml


-1

jQuery로 구문 분석하여 요소를 작성하십시오.

<div id="someElement"></div>
<script>
    var code = "<script>alert(123);<\/script>";
    $("#someElement").append($(code));
</script>

작업 예 : https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz


이것은 여전히 ​​똑같은 문제가 있으며 일부 브라우저는 이것을 존중하지 않습니다.
마틴 마 세라

어떤 브라우저와 어떤 버전의 jQuery를 사용하고 있는지 알려주시겠습니까? 감사!
sanbor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.