상세 컨텐츠

본문 제목

[JavaScript] 자바스크립트를 동적으로 로딩하기, 자바스크립트로 html에 코드 넣기 관련

WEB/JavaScript

by AlrepondTech 2018. 4. 13. 16:13

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

 

 

출처: https://www.hooni.net/xe/study/2173

 

 

 

 

Dynamic Script Loading

 
동적으로 자바스크립트를 로딩하는 방법 중 하나는 script 태그를 자바스크립트 코드에서 직접 생성하는 것인데요. 다음과 같이 script 태그를 생성하고 src에 로딩할 주소를 넣음으로서 로딩하게 됩니다. 
1
2
3
4
5
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'helper.js';
head.appendChild(script)
위의 코드를 실행함으로서 스크립트 파일을 로딩을 할 수는 있지만, 스크립트가 로딩이 완료되어서 사용할 수 있는 지 여부를 알 수가 없습니다. 이 때 사용할 수 있는 방법은 두 가지가 있습니다. 
하나는, script 태그의 onload 속성을 사용하는 것과 
또 다른 하나는, 로딩하는 스크립트 파일안에 자신이 로딩되었음을 알려주는 코드를 넣는 방법입니다. 
1에서의 문제점은 IE에서는 script 태그에서의 onload를 지원하지 않는다는 점인데요. MSDN에는 attributes에 포함되어 있기는 합니다만 호출되지는 않습니다. 
 
대신에 IE에서 지원하는 onreadystatechange(비표준)를사용하면 script태그에서 로딩이 완료되었는지 여부를 알 수 가 있습니다. 
1
2
3
4
5
6
7
8
9
10
11
12
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
 
script.onreadystatechange= function () {
   if (this.readyState == 'complete'
         || this.readyState == 'loaded') helper();
}
script.onload= helper;
 
script.src= 'helper.js';
head.appendChild(script)
※ IE에서 onreadystatechange를 사용하여 로딩을 체크하는 상태 값으로 'loaded' 또는'complete'가 호출되기 때문에 두 값중 하나를 체크해서 실행하도록 합니다. 
※※ 두 번 호출될 수도 있기 때문에 해당하는 부분에 대해서는 중복로딩이 되지 않도록 처리를 해야합니다.
 
2의 문제점은 동적으로 로딩하려는 코드의 뒤에 로딩되었음을 알려주는 동작이 추가되어야 하는 문제점이 있습니다. script 태그를 사용하지 않고 다른 방법으로도 로딩은 가능합니다.
 
가장 대표적인 방법으로 XMLHTTPRequest를 사용하는 방법인데요. 사용방법은 다 아실테니 생략하도록 하겠습니다. ^^;;; 파일을 요청한 후, 요청한 파일을 response로 받은 다음 이를 eval()를 사용하여서 로딩하게 되는데요. 파일을 로딩하는게 아니라 파일을 텍스트로 로딩한 후, 이를 실행하기 때문에 
일반적인 자바스크립트 파일이 브라우저에서 캐시가 되지만 텍스트에 대해서는 캐시할 수 없습니다.
에러가 발생하여도 몇 번째 줄에서 발생하였는 지에 대한 정확한 정보를 얻기 힘듭니다. 
이 외에도 iframe을 사용하여 로딩을하거나 document.write()를 쓸 수도 있겠죠.
 
 
Degrading Script Tags
Steve Souders의 Coupling asynchronous scripts에서는 조금 다른 방식을 취합니다. 먼저, 이 방식을 들여다보기 전에, 위대하신 레식 사마의 Degrading Script Tags에 대해서 살펴봐야 하는데요. 
 
아래와 같이 외부 파일 형태로 존재하는 자바스크립트 파일과 이를 사용하는 코드를 
1
2
3
4
5
<script src="some-lib.js"></script>
<script>
  var foo = use_some_lib();
  foo.do.stuff();
</script>
다음과 같이 하나의 script 태그로 묶습니다. 
1
2
3
4
<script src="some-lib.js">
  var foo = use_some_lib();
  foo.do.stuff();
</script>
그리고, some-lib.js의 파일 안에 some-lib.js를 로딩하는 script 태그 안의 자바스크립트 코드를 실행하는 코드를 추가합니다. 
1
2
var scripts = document.getElementsByTagName("script");
eval( scripts[ scripts.length - 1 ].innerHTML );
이렇게 묶게 되면 some-lib.js에 정의되어 있는 코드와 이를 사용하는 코드를 하나로 묶을 수 있기 때문에 some-lib.js를 로딩하는데 실패하게 되는 경우, 사용하는 코드도 함께 실행하지 않게 할 수 있는 장점(Degrading)이 있습니다. 
 
Degrading Script Tags는 script 태그의 다음 특성을 사용합니다. 
script 태그에 src 속성이 포함되어 있는 경우, script 태그 사이에 정의되어 있는 자바스크립트 코드는 실행되지 않습니다. 
그러나, script 태그도 HTMLElement이기 때문에 innerHTML로 script 태그안에 정의되어 있는 코드에 접근이 가능합니다. 
 
 
Coupling asynchronous scripts
Steve Souders는 Script 태그를 사용하여 동적으로 로딩하는 방식에 Degrading Script Tags를 함께 사용하여, 관련된 코드들을 하나로 묶어버립니다.  
1
2
3
4
5
6
var script = document.createElement('script');
script.src = "sorttable-async.js";
 
script.text = "sorttable.init()";
 
document.getElementsByTagName('head')[0].appendChild(script);
 
sorttable-async.js에 정의되어 있는 코드를 호출하는 코드를 script태그의 text에 넣어서 커플링을 최소화 시킨 후, sorttable-asnyc.js의 뒤에 script 코드를 실행하는 코드를 추가하여 외부 파일의 코드가 로딩된 후, 바로 실행되게 합니다. 
1
2
3
4
5
6
7
8
9
10
var scripts = document.getElementsByTagName("script");
var cntr = scripts.length;
while ( cntr ) {
    var curScript = scripts[cntr-1];
    if ( -1 != curScript.src.indexOf('sorttable-async.js') ) {
        eval( curScript.innerHTML );
        break;
    }
    cntr--;
}
Steve Souders는 위의 코드처럼 초기에 로딩될 필요가 없는 자바스크립트 코드의 로딩을 동적으로 로딩되게 한 후, 페이지가 전체 로딩된 다음에 실행될 코드들을 window의 onload() 시 호출되도록 조정하여 Stuart Langridge의 sorttable script의 로딩 속도를 487ms에서 417ms까지 단축시켰습니다. 
 
[출처]
Jan Wolter - JavaScript Madness: Dynamic Script Loading
John Resig - Degrading Script Tags
Steve Souders - Coupling asynchronous scripts
※ Steve Souders가 Coupling asynchronous scripts 다음으로 쓴 Loading Scripts Without Blocking 글도 함께 보시면 도움이 많이 될 것 같습니다.

 

 

 

반응형

 

728x90

 

 

 

=================================

=================================

=================================

 

 

출처: https://code.i-harness.com/ko/q/d2b9

 

 

 

문제를 설명하는 간단한 테스트 페이지를 만들었습니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html>     <head>         <meta http-equiv="Content-type" content="text/html; charset=utf-8" />         <title>Document Write Testcase</title>     </head>     <body>         <div id="container">         </div>         <div id="container2">         </div>          <script>             // This doesn't work!             var container = document.getElementById('container');             container.innerHTML = "<script type='text/javascript'>alert('foo');document.write('bar');<\/script>";              // This does!             var container2 = document.getElementById('container2');             var script = document.createElement("script");             script.type = 'text/javascript';             script.innerHTML = "alert('bar');document.write('foo');";             container.appendChild(script);         </script>     </body> </html>

이 페이지는 'bar'에 경고하고 'foo'를 인쇄하고 'foo'에 경고하고 'bar'로 인쇄 할 것을 기대했습니다. 그러나 불행히도 script 태그는 더 큰 HTML 페이지의 일부이므로 위의 예처럼 태그를 붙이지 않고 추가 할 수는 없습니다. 글쎄, 할 수 있지만, 그 script 태그에 대한 innerHTML 콘텐츠를 검색하고 자리 표시 자에 의해 문자열에 그들을 교체하고 그들을 사용하여 DOM을 삽입합니다. 그게 사소한 소리는 아니에요.

 

 

=================================

=================================

=================================

 

 

 

출처: https://developer.mozilla.org/ko/docs/Web/API/Document/createElement

 

 

지정된 태그이름을 가지는 엘리먼트를 생성합니다.

문법

엘리먼트 = document.createElement(태그이름);
  • 엘리먼트 생성된 엘리먼트 객체입니다.
  • 태그이름 생성할 엘리먼트의 종류를 지정하는 문자열입니다. 생성된 엘리먼트의 nodeName 속성은 태그이름에 지정된 값으로 초기화됩니다.

예제

이 예제는 새로운 <div> 엘리먼트를 생성한 후, id가 "org_div1" 인 엘리먼트 앞에 추가합니다:

<html> <head> <title>||엘리먼트 사용하기||</title> </head>  <script type="text/javascript"> var my_div = null; var newDiv = null;  function addElement() {   // 새로운 div 엘리먼트를 만들고   // 내용을 작성합니다.   newDiv = document.createElement("div");   newDiv.innerHTML = "<h1>안녕! 반가워!</h1>";    // 생성된 엘리먼트를 추가합니다.   my_div = document.getElementById("org_div1");   document.body.insertBefore(newDiv, my_div); }  </script>  <body onload="addElement()"> <div id='org_div1'> 위의 문장은 동적으로 만들어 진 것입니다.</div> </body> </html>

참고 사항

기본값이 있는 잘 알려진 특성(attributes)들은 자동으로 생성되어 엘러먼트에 특성노드로 추가됩니다.

qualified 이름과 네임스페이스 URI를 갖는 엘리먼트를 만들 경우에는 createElementNS 메서드를 사용합니다.

Gecko 엔진의 createElement 구현은 XUL과 XHTML 문서에 대한 DOM 규약을 따르지 않습니다: localName과 namespaceURI는 null로 설정되지 않습니다. 자세한 사항은 bug 280692를 참고하세요.

 

=================================

=================================

=================================

 

 

출처: https://stackoverflow.com/questions/584751/inserting-html-into-a-div

 

var div = document.createElement("div");  div.innerHTML =     '<div class="slideshow-container">\n' +     '<div class="mySlides fade">\n' +     '<div class="numbertext">1 / 3</div>\n' +     '<img src="image1.jpg" style="width:100%">\n' +     '<div class="text">Caption Text</div>\n' +     '</div>\n' +      '<div class="mySlides fade">\n' +     '<div class="numbertext">2 / 3</div>\n' +     '<img src="image2.jpg" style="width:100%">\n' +     '<div class="text">Caption Two</div>\n' +     '</div>\n' +      '<div class="mySlides fade">\n' +     '<div class="numbertext">3 / 3</div>\n' +     '<img src="image3.jpg" style="width:100%">\n' +     '<div class="text">Caption Three</div>\n' +     '</div>\n' +      '<a class="prev" onclick="plusSlides(-1)">&#10094;</a>\n' +     '<a class="next" onclick="plusSlides(1)">&#10095;</a>\n' +     '</div>\n' +     '<br>\n' +      '<div style="text-align:center">\n' +     '<span class="dot" onclick="currentSlide(1)"></span> \n' +     '<span class="dot" onclick="currentSlide(2)"></span> \n' +     '<span class="dot" onclick="currentSlide(3)"></span> \n' +     '</div>\n';  document.body.appendChild(div);

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

 

반응형


관련글 더보기

댓글 영역