사이트 내 전체검색
JavaScript Tip
로빈아빠
https://cmd.kr/javascript/782 URL이 복사되었습니다.

본문

페이지 로딩시 java함수 호출하기

보통 페이지를 호출할 때 자바스크립트가 실행되도록 하는 경우 아래와 같이 body에 onLoad라는 이벤트 핸들러를 쓴다.

  1. <body onLoad="해당함수();"> //IE에서만 실행됨. 쓰지 않는 것이 좋다.

그런데 header 페이지를 따로 통일시켜 페이지 디자인과 개발 소스를 나누어 관리하는 경우 body에 onLoad 이벤트 핸들러를 쓰기가 쉽지 않다.

수십, 수백페이지중 특정 페이지에서 호출을 하려고 하는데 header파일을 건드리기는 주저하기 마련이다.

이런 경우 다른 방법으로 onLoad 이벤트 핸들러를 호출할 수 있는 방법이 있다.

  1. <script language="javascript">
  2. window.onload() { 
    1. 해당함수();
  3. }
  4. </script>

 

select 메뉴의 포커스 없애기

원래 html의 속성을 생각하면 onfocus()로 포커스 지정,  onblue()로 포커스 해제가 되어야 한다.

그런데 select 메뉴의 경우 초기화 후 javascript를 통해 생성하는 경우(ajax에서 dom을 뿌려줄 때) 중에 onLoad시 자동 생성되는 경우에 이 포커스가 잘 안먹는다.

이럴때는 꽁수로 아래와 같이 하자. (사실 값은 현재 존재하지 않는 값이면 다 된다. 명료하게 보여주려고 -1을 선택했을 뿐.=ㅅ=

  1. document.frm.selectMenu.selectedIndex = -1

 

크로스 브라우징 관련하여 주의해야하는 부분

IE기준으로 많은 웹페이지들이 개발되고 있지만 본질적으로 웹개발은 웹표준을 준수하여 이를 따르는 여러 브라우저에서 동일하게 출력이 되도록 하는 것이 옳다.

이를 위해서 웹개발시 주의해야하는 부분들에 대해 살펴보자.

  1. IE전용 함수 혹은 각 브라우저용 전용 함수의 사용을 자제한다.

    • 먼저 아래의 소스를 보자. 
      1. <script language="javascript">
        1. function window::onLoad() { 
          1. 함수 구현
        2. }
      2. </script>
    •  위의 경우 IE에서는 페이지 로딩시 onLoad()에 속한 부분이 올바르게 실행되지만 FF(파이어 폭스)와 같은 타 브라우저에서는 실행이 되지 않는다.
      이는 해당 함수가 IE전용 함수이기 때문이다 이러한 함수들은 굳이 onLoad와 같은 IE전용함수로 만들지 않고 구현될 부분을 실행영역 하단에 위치 시키는 것이 좋다.
      1. <div id="insertArea"></div>
      2. <script language="javascript"> 
        1. document.getElementById("insertArea").innerHTML = "구현된 출력부분";
      3. </script>
    • 또 다른 방법으로 window:onLoad()가 아닌 window.onload = function() 을 쓰는 것이다. 

      1. <script language="javascript">
      2. window.onload= function() {

        1. 함수 구현
      3. }
      4. </script>
    •  스크립트 실행 전에 실행영역을 지정해야 오류가 나지 않는다는 것을 명심해야한다. (브라우저에서 출력할 source를 line by로 읽어들여 실행하기 때문이다.)
  2.  W3C의 규약을 지키는 속성들을 사용한다.
    • 각 브라우저마다 특화된 무수히 많은 메소드와 속성이 있겠지만 W3C에서 규약한 메소드와 속성을 따르는 것이 좋다. 이는 브라우저들은 기본적으로 W3C에서 규약한 웹표준을 표현하려고 하기 때문이다.
      이에 대해서 정리한 사이트가 있다. (http://www.w3schools.com/)
      하지만 W3C의 규약을 지킨다 하더라도 각 브라우저마다 이를 실행하는 것은 차이가 존재할 수 있다. 예를 들어 아래와 같은 HTML DOM Style Object를 보자.
      1. <div id="outputArea"></div>
      2. <script language="javascript> 
        1. document.getElementById("outputArea").style.marginLeft = "30";
      3. </script>
    • 위의 경우 IE에서는 제대로 처리가 되지만 FF에서는 올바른 처리가 되지 않는다.
      이는 FF에서는 단위 명시가 불분명한 경우 오류 처리로 무시해버리기 때문이다 따라서 위의 경우는 아래와 같이 단위도 명시해주는 것이 좋다. 
      1. <div id="outputArea"></div>
      2. <script language="javascript"> 
        1. document.getElementById("OutputArea").style.marginLeft = "30px";
      3. </script>
    • [여백]
  3. 전역변수를 사용할 경우 꼭 변수선언을 해준다.
    • IE에서는 전역변수의 경우 var를 지정해주지 않으면 전역변수로 인식을 하지 않는다.
    • FF에서는 전역변수를 지정하지 않더라도 function외부에서 변수가 사용이 되면 전역변수가 된다.
  4. ajax를 사용시 xml에서 정보를 불러들이는 경우 차이가 있다.
    • IE의 경우 불러온 값을 호출을 할때 순차적으로 불러온 노드의 값을 각 item의 text로 불러들여진다. FF의 경우 text 속성이 없으며 불러들여진 nodeList의 값이 IE와 다르다.
    • IE의 경우
      • #루트노드
        노드네임
        ...
        노드네임
    • FF의 경우
      • #루트노드
        노드네임
        #자식노드
        노드네임
        #자식노드
        노드네임
        ...
        #자식노드
        노드네임
    • 위와 같이 순차적으로 불러들여지는 값이 차이가 생긴다. 어쩔수 없이 구분을 지어서 사용해야 하는 실정이다. 
    •  text 속성은 IE전용 속성이며 W3C규약이 아니다. 따라서 사용하지 않는 것이 좋다.  (현 상황에선 별수 없을듯..)
      1. objNodeList.item(i).childNodes.item(0부터 노드의 갯수만큼).text
    • FF의 경우 노드별로 text를 불러들이는 함수가 없고 대신 textContent라는 속성이 존재하여 해당 노드의 값을 저장한다. 따라서 위에서 사용한 부분이 FF에서는 아래와 같이 변형되어진다.
    • textContent 속성은 FF에서만 사용이 가능하나 W3C 규약에 정해져 있다. (그러나 타 브라우저에서 지원하지 않고 있는 실정이다.)
      1. if (objNodeList.item(i).nodeName != "#text") { 
        1. objNodeList.item(i).childNodes.item(1..3..5..7의 노드텍스트 속성이 존재하는 부분).textContent;
      2. }
    •   [여백]
  5. FF의 경우 vbScript를 지원하지 않는다.

 

배열변수 생성과 관련한 성능향상 방법에 대하여

흔히 xml을 호출하여 innerHTML 메소드를 통해 값을 뿌려줄 때, 혹은 기타 구문처리에서 for문을 돌려 해당 xml의 내용을 어떤 변수에 반복 삽입하는 방법을 즐겨쓰게 된다.

그전에 한가지 언급하자면 호출된 값을 뿌려주는 방식은 2가지가 있는데

  1. dom개체를 생성하여 해당 노드에 innerHTML을 통해 값을 입력한다.
  2. 변수에 innerHTML을 통해 입력할 값을 모은다음에 한방에 집어넣는다.

dom을 통해 각 노드들의 object model을 생성하는 것보다 변수을 생성해서 한꺼번에 뿌려주는 것이 확실히 성능에 도움이 된다.

이것은 일반적으로 많이 쓰이는 방법이다.

 

이에 대해서 좀더 성능향상을 할 수 있는 방법에 대해 이야기하도록 하겠다.

이에 대해 명확하게 눈으로 보이는 결과를 확인하기 위한 소스를 짜보도록 하자.

  1. <html>
  2. <head>
  3. <script language="javascript">
  4. var maxLoop = 500;
  5. var testContent = "이것은 테스트입니다.<br>";
  6. function testDOM(){
    1. var myHtml = document.childNodes.item(0);
    2. var myBody = myHtml.childNodes.item(1);
    3. var testArea = myBody.childNodes.item(0);
    4. var startTime = new Date().getTime();
    5. for (var i=0; i<maxLoop; i++) {
      1. testArea.innerHTML+= testContent;
    6. }
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  7. }
  8. function testInnerHTML1(){
    1. var testArea = document.getElementById("testArea")
    2. var roopText;
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
    5. testArea.innerHTML = testArea.innerHTML + testContent;
    6. }
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  9. }
  10. function testInnerHTML2(){
    1. var testArea = document.getElementById("testArea");
    2. var roopText = "";
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
      1. roopText += testContent;
    5. }
    6. testArea.innerHTML = roopText;
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  11. }
  12. function testInnerHTMLByArray() {
    1. var testArea = document.getElementById("testArea");
    2. var roopText = new Array();
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
      1. roopText[roopText.length] = testContent;
    5. }
    6. testArea.innerHTML = roopText.join('');
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  13. }
  14. </script>
  15. </head>
  16. <body>
  17. <div id="testArea"></div>
  18. <div id="runTime"></div>
  19. <a onClick="testInnerHTML1();">testInnerHTML1</a></br>
  20. <a onClick="testInnerHTML2();">testInnerHTML2</a></br>
  21. <a onClick="testInnerHTMLByArray();">testInnerHTMLByArray</a></br>
  22. </body>
  23. </html>

위의 예제를 보면 순서대로

  1. innerHTML에 매번 추가 작업을 실행하는 경우
  2. 변수를 생성하여 값을 저장한후 한번에 innerHTML을 실행한 경우
  3. 배열을 만들어 해당 배열을 join메소드를 통해 저장한 경우

 이다. DOM처리를 테스트 하지 않은 것은 일단 DOM생성을 통한 출력은 상당히 느리다는 전제를 이미 하고 있기 때문이다.

우선 1번과 2번의 결과를 테스트 해보면 아래의 사실을 알 수 있다.

  • innerHTML을 매번 로딩하는 것이 부하가 더 걸린다. 
    • 이것은 innerHTML은 객체를 생성하는 명령이므로 변수에 값을 저장하는 경우에 비해 많은 부하가 걸린다는 사실을 알 수 있다.

2번과 3번의 경우 500번 정도의 Loop 실행으로는 별 차이를 느끼기 힘드므로 5000번으로 늘려 테스트를 해보자.

아마 2배~3배 이상 성능이 향상되는 것을 느낄 수 있을 것이다.

 

이것은 코드의 효율성 때문인데 매번 변수를 불러들어오는 경우 지난번 저장한 값을 다시 불러들여야 한다는 문제점이 발생한다.

즉, 점점 추가되는 값이 누적될수록 코드는 느려지고 성능은 점점 떨어지게 된다.

실제로 저 위의 값을 5만번으로 늘려서 실험해본결과 2번은 69201이란 시간이 걸린 반면 3번의 경우는 단지 2974의 시간이 걸렸다.

즉. 누적을 피할 수 있는 코드가 성능향상에 많은 도움이 되는 코드라는 것이다.

이는 Javscript 뿐만아니라 모든 언어에서 공통적으로 적용되는 사항이다.

 

단일 대입 if 구문 코드 줄이기

아래와 같이 사용하는 경우가 많다.

  1. <script language="javascript"> 
    1. if (a > b) {
      1. c = a;
    2. } else { 
      1. c = b;
    3. }
  2. </script>

 

위와 같이 조건식을 타서 하나의 실행코드가 들어가는 경우는 아래와 같이 '{', '}'의 생략이 가능하다.

  1. <script language="javascript"> 
    1. if (a > b) c = a;
    2. else c = b;
  2. </script>

 

또한 else if 구문이 없이 A가 아니면 B라는 식의 조건문은 아래와 같이 단축이 가능하다.

  1. <script language="javascript"> 
    1. c = a > b ? a : b;
  2. </script>

 

스타일 지정관련 성능향상에 대하여

순수 자바스크립트에서의 스타일 지정은 다음과 같은 형태로 이루어진다.

  1. <script language="javascript">
  2. function setStyle(obj) { 
    1. var selObj = document.getElementById("obj");
    2. obj.style.fontWeight = 700;
    3. obj.style.fontFace = "Arial";
    4. obj.style.fontSize = "20px;"
    5. obj.style.backgroundColor = "#FF0000";
    6. obj.style.color = "#FFFFFF";
    7. obj.noWrap = true;
  3. }
  4. </script>

하지만 이런형태의 개발은 위에서 설명한 배열변수 향상에 관한 내용과 똑같은 이유로 인해 속도저하의 원인이 된다. (반복적인 객체 호출이 실행되고 있으므로.)

따라서 위와 같은 코드는 아래와 같이 변경하는 것이 좋다.

  1. <script language="javascript">
  2. with (obj) {

    1. style.cssText = "font-Weight:700;font-face:Arial;font-size:20px;background-color:red;color:white;";
    2. noWrap = true;
  3. }
  4. </script>

 

뒤로가기 방지

일반적으로 자바스크립트의 이동은 아래와 같이 하게 된다.

  1. <script language="javascript"> 
    1. location.href="이동할 주소";
  2. </script>

그러나 아래와 같이 사용하게 되면 현재 페이지의 URL을 이동하되 history에 남기지 않아 back 할 수 없도록 한다.

  1. <script language="javascript"> 
    1. location.replace("이동할 주소");
  2. </script>

 

이미지 프리로딩

마우스 온 오버 할때 버튼이미지가 교체된다거나 배경 이미지의 변경이 있는 경우 아래와 같은 자바스크립트를 통해 해당 이미지를 바꿔주곤 한다.

  1. <img src="a.gif" onmouseover="this.src='b.gif';">

이런 경우 마우스가 오버하는 순간 이미지를 불러들여오게 되는데 만약 이미지가 배경이미지이거나 혹은 불러들이는 어떤 데이터가 용량이 큰 경우 사용자의 입장에서는 사이트의 반응이 느리다고 느낄 수 있다.

이런 문제를 해결하기 위해서는 미리 해당 데이터를 불러들여오는 방법이 있는데

불러들여오는 방법에는 여러가지가 있을 수 있다.

숨겨진 div그룹안에 해당 image를 호출하거나 아이프레임을 쓴다거나 하는 방법들을 쓸 수 있지만

이런 식으로 이미지를 불러들이는 경우 디스플레이 되지 않는 이미지를 로딩하기 위해 첫 페이지의 진입속도가 더뎌지는 문제가 생기게 된다.

따라서 아래와 같은 방법을 사용하면 좋다.

  1. <script language="javscript">
  2. var preloadImage;
  3. function preload() {
  4. preloadImage  = new Image();

    preloadImage.src="이미지주소";

    }

    window.onload = function() {

    preload();

    }

  5. </script>

설명하자면 미리 로딩할 이미지를 담을 객체를 전역 이미지 객체로 생성한 후 이 객체에 담을 이미지들을 담고 있는 함수를 현 페이지의 로딩이 끝난 상태에서 불러들이는 것이다.

 

insertAdjacentHTML, insertAdjacentText

InnerHTML 이나 InnerText는 해당 element 내에 HTML이나 text를 집어넣지만 위의 두 속성은 추가를 하는 개념이다.

추가를 하는 위치는 해당 element의 바로 앞, 시작된 태그의 바로 안쪽 시작부분, 태그 종로 바로 다음 부분이다.

  1. insertAdjacentHTML("BeforeBegin", "들어갈 내용");

위치에 대한 값은 위에 언급한 3가지가 있으며 해당 값은 아래와 같다.

  • BeforeBegin : 시작 태그 바로 앞
  • AfterBegin : 시작 태그 바로 뒤
  • AfterEnd : 종료 태그 바로 뒤

 

Animation 효과를 줄 때는?

Javascript로 화면에 보이는 객체에 대하여 속성값을 변경하는 것은 알고 있다.

그렇다면 이러한 속성값의 변화를 통해 Animation 효과를 줄 때는 어떻게 해야할까?

이럴때는 setInterval 함수를 사용하면 된다.

이 함수는 주기적으로 다른 함수를 호출하는데 쓰이는데 이 함수를 통해 객체의 속성값이 점차적으로 변하도록 하면 Animation 효과가 나타나게 되는 것이다.

함수의 사용법은 다음과 같다.

  1. <script language="javascript">
  2. var setXposition = 0;
  3. var setYPosition = 0;
  4. function start() { 
    1.  window.setInterval("move()", 50);
  5. }
  6. function move() { 
    1. document.getElementById("moveTarget").left = setXposition + 1;
    2. document.getElementById("moveTarget").left = setXposition + 1;
  7. }
  8. </script>

 

간단한 정규식 모음

자주 쓰이는 정규식 패턴이다.

  1. var regNum =/^[0-9]/; 
  2. var regPhone =/^[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}/;
  3. var regMail =/^[_a-zA-Z0-9-]+@[._a-zA-Z0-9-]+.[a-zA-Z]/;
  4. var regDomain =/^[.a-zA-Z0-9-]+.[a-zA-Z]/;
  5. var regAlpha =/^[a-zA-Z]/;
  6. var regHost =/^[a-zA-Z-]/;
  7. var regHangul =/[가-

댓글목록

등록된 댓글이 없습니다.

831 (2/17P)

Search

Copyright © Cmd 명령어 18.118.162.8