Ajax 프로그래밍을 할 때 xmlhttp로 얻은 페이지 콘텐츠를 innerHTML을 통해 컨테이너(예: p, span 또는 td 등)에 할당해야 하는 경우가 많습니다. innerHTML에 할당하십시오. 페이지 내용에 스크립트가 포함되어 있으면 외부 스크립트이든 내부 스크립트이든 (1)이 실행되지 않을 수 있습니다. 때로는 이 문제가 사소하여 무시할 수도 있지만 때로는 이 문제가 매우 심각하여 프로그램이 예상한 결과를 얻지 못할 가능성이 높습니다. 그래서 우리는 이 문제를 해결해야 합니다.
MSDN을 읽어보면 innerHTML에 삽입된 모든 스크립트를 실행할 수 없는 것을 알 수 있습니다. 이 스크립트의 스크립트 태그에 defer 속성이 포함되어 있으면 IE는 이러한 스크립트를 올바르게 실행합니다. 그러나 불행하게도 Moziila/Firefox 및 Opera는 스크립트 태그에 defer 속성이 설정되어 있는지 여부에 관계없이 IE처럼 innerHTML에 삽입된 스크립트를 실행하지 않습니다.
그러나 스크립트 실행 여부에 관계없이 우리가 확신할 수 있는 한 가지는 이러한 스크립트가 실제로 innerHTML에 삽입되었다는 것입니다. 믿을 수 없다면 경고하고 살펴보세요. 그러나 실제로 주의를 기울이면 예외가 있음을 발견할 수도 있습니다. 즉, 스크립트가 innerHTML 콘텐츠의 시작 부분에 있으면 IE 브라우저는 이 스크립트를 무시하지만 Moziila/Firefox 및 Opera는 무시하지 않습니다.
자, 문제 분석이 거의 완료되었습니다. 해결 방법을 살펴보겠습니다.
해결 방법은 실제로 매우 간단합니다. 즉, innerHTML에 삽입된 모든 스크립트를 꺼내어 하나씩 실행하는 것입니다. 하지만 먼저 위의 두 가지 문제를 해결해야 합니다.
먼저 첫 번째 질문인 IE의 innerHTML에서 defer 속성을 사용하여 스크립트를 반복적으로 실행하지 않는 방법을 살펴보겠습니다. 이것은 쉽습니다. 먼저 브라우저가 IE인지 확인한 다음 실행할 스크립트에 defer 속성이 있는지 확인하면 됩니다. IE 브라우저를 판단할 때 오페라의 브라우저 인식에 속지 않도록 주의해야 합니다. 아래 코드에서 이것이 어떻게 수행되는지 살펴보겠습니다.
다음으로 IE에서 innerHTML 시작 부분의 스크립트를 무시하는 문제를 살펴보겠습니다. 이 문제도 해결하기 쉽습니다. innerHTML에 삽입하려는 콘텐츠의 시작 부분에 스크립트가 아닌 콘텐츠를 추가하기만 하면 작업이 완료됩니다. 그러나 빈 내용이나 공백, 캐리지 리턴, 줄 바꿈 등이 포함된 태그를 추가하지 마십시오. 작동하지 않으며 시작 부분의 스크립트는 계속 무시됩니다. 를 추가하려고 시도하지 마십시오. 이렇게 하면 시작 스크립트가 무시되는 것을 방지할 수 있지만 원본 콘텐츠 표시에는 여전히 영향을 미칩니다. 비록 명확하지 않다고 생각할 수도 있지만 까다로운 사용자에게는 허용되지 않을 수 있습니다. 따라서 추가 콘텐츠가 오프닝 스크립트가 무시되는 것을 방지하고 부작용을 일으키지 않도록 다음 콘텐츠를 추가합니다.
코드 복사 코드는 다음과 같습니다.
/* innerhtml.js
* 저작권 Ma Bingyao
* 버전: 1.9
* 최종 수정: 2006-06-04
* 이 라이브러리는 무료입니다. 재배포하거나 수정할 수 있습니다.
* http://www.php.cn/
*/
var global_html_pool = [];
var global_script_pool = [];
var global_script_src_pool = [];
var global_lock_pool = [];
var innerhtml_lock = null;
var document_buffer = "";
함수 set_innerHTML(obj_id, html, time) {
if (innerhtml_lock == null) {
innerhtml_lock = obj_id;
}
else if (typeof(time) == "정의되지 않음") {
global_lock_pool[obj_id "_html"] = html;
window.setTimeout("set_innerHTML('" obj_id "', global_lock_pool['" obj_id "_html']);", 10);
반품;
}
else if (innerhtml_lock != obj_id) {
global_lock_pool[obj_id "_html"] = html;
window.setTimeout("set_innerHTML('" obj_id "', global_lock_pool['" obj_id "_html'], " 시간 ");", 10);
반품;
}
function get_script_id() {
return "script_" (new Date()).getTime().toString(36)
Math.floor(Math.random() * 100000000).toString(36);
}
document_buffer = "";
document.write = 함수(str) {
document_buffer = str;
}
document.writeln = 함수(str) {
document_buffer = str "n";
}
global_html_pool = [];
var 스크립트 = [];
html = html.split(//i);
for (var i = 0; i < html.length; i ) {
global_html_pool[i] = html[i].replace(/ 스크립트[i] = {텍스트: '', src: '' };
scripts[i].text = html[i].substr(global_html_pool[i].length);
scripts[i].src = scripts[i].text.substr(0, scripts[i].text.indexOf('>') 1);
scripts[i].src = scripts[i].src.match(/srcs*=s*("([^"]*)"|'([^']*)'|([^s ]*)[s>])/i);
if (scripts[i].src) {
if (scripts[i].src[2]) {
scripts[i].src = scripts[i].src[2];
}
그렇지 않으면 (scripts[i].src[3]) {
스크립트[i].src = 스크립트[i].src[3];
}
else if (scripts[i].src[4]) {
scripts[i].src = scripts[i].src[4];
}
그렇지 않으면 {
스크립트[i].src = "";
}
scripts[i].text = "";
}
else {
scripts[i].src = "";
scripts[i].text = scripts[i].text.substr(scripts[i].text.indexOf('>') 1);
scripts[i].text = scripts[i].text.replace(/^s*