아래 코드가 왜 script 요소를 DOM에 추가하지 않는지 아십니까?
var code = "<script></script>";
$("#someElement").append(code);
아래 코드가 왜 script 요소를 DOM에 추가하지 않는지 아십니까?
var code = "<script></script>";
$("#someElement").append(code);
답변:
일부 브라우저는 직접 수행 할 때 일부 변경 사항을 존중하지 않는 문제를 보았습니다 (스크립트 태그를 사용하는 것처럼 텍스트에서 HTML을 만드는 것을 의미합니다). 내장 명령으로 수행 할 때 상황이 좋아집니다. 이 시도:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
보낸 사람 : jQuery 용 JSON
$("#someElement")[0].appendChild( script );
좋은 소식은 :
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()
를 사용 하여 스크립트를 추가 하지는 않을 것 입니다.
$.getScript
jQuery에 내장되어 있습니다.
jQuery 함수를 사용하여 JavaScript 파일을 동적으로로드 할 수 있습니다getScript
$ .getScript ( 'http://www.whatever.com/shareprice/shareprice.js', function () { Display.sharePrice (); });
이제 외부 스크립트가 호출되고로드 할 수 없으면 정상적으로 저하됩니다.
eval()
.
"작동하지 않는다"는 것은 무엇을 의미합니까?
jQuery는 SCRIPT 요소를 만들려고 시도하고 전역 컨텍스트 내에서 요소의 내용을 자동으로 실행합니다. 이것이 효과가 없다고 말하고 있습니까? -
$('#someElement').append('<script>alert("WORKING");</script>');
편집 : 명령을 실행 한 후 DOM에 SCRIPT 요소가 표시되지 않으면 (예 : Firebug) jQuery가 말했듯이 코드를 실행 한 다음 SCRIPT 요소를 삭제하기 때문에 SCRIPT 요소가 있다고 생각합니다. 항상 본문에 추가되지만 ... 어쨌든 배치는이 상황에서 코드 실행과 전혀 관련이 없습니다.
도움이 될 수 있습니다.
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
<script>
...
...jQuery("<script></script>")...
...
</script>
</script>
문자열 리터럴 종료 전체 스크립트 내에서 그 피하기 위해 "</scr" + "ipt>"
대신 사용할 수 있습니다.
"\x3cscript\x3e\x3c/script\x3e"
. XHTML에서는 주석 처리 된 CDATA 블록 만 입력하면됩니다.
</
허용되지 않는 것입니다. 참조 stackoverflow.com/questions/236073/...
이 페이지에서 언급 한 것처럼 스크립트 파일에 sourceURL을 추가하면 도움이됩니다. https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
스크립트가 실행 중이므로 사용할 수 없습니다 document.write
. 경고를 사용하여 테스트하고 사용을 피하십시오 document.write
. js 파일의 명령문은 document.write
실행되지 않으며 나머지 함수는 실행됩니다.
이것이 최선의 해결책이라고 생각합니다. 이런 식으로 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); })();
스크립트 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
스크립트가로드 될 때 약속을 해결하여 장기 실행 스크립트의 경쟁 조건을 방지 할 수 있습니다.
본문에 스크립트 추가 :
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
스크립트 태그를 포함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