<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.