2011/09/29 16:47

[jQuery Cookbook - 1장 jQuery의 기초]

  jQuery는 HTML문서, 보다 정확하게는 문서객체모델(DOM)과 자바스크립트 사이의 상호작용을 간단하게 해주는 오픈소스자바스크립트 라이브러리이다.

  • jQuery의 철학 : Write less, do more (적게 작성하고, 보다 많이 한다)
  • jQuery 선택자 : #은 id, .은 class
  • jQuery('div').hide() => 모든 div를 숨긴다.
  • jQuery('div').text('new content') => 모든 div의 내부텍스트를 변경한다.
  • jQuery('div').addClass("updatedContent") => 모든 div에 updatedContent클래스를 추가한다.
  • jQuery('div').show() => 모든 div를 나타낸다.
  • jQuery 온라인문서 : http://docs.jquery.com/Main_Page
  • 문서에 jQuery 포함하기 (부가적인 기능향상을 위해 방법1을 사용하자!)

방법1 : <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

방법2 : 다운로드 받아 포함시키기

  • DOM 로드된 후 함수 실행 (로딩속도 향상을 위해 방법3을 사용하자!)

    방법1 : jQuery(document).ready(function() { //실행구문 })

    방법2 : jQuery(function() { //실행구문 })

    방법3 : </body> 앞에 스크립트 추가

  • DOM요소 선택

    jQuery('a') => 모든 a요소 (== document.getElementsByTagName('a'))

    jQuery('a').length => 모든 a요소의 개수

    jQuery('input', $('form')) => 모든 form요소내의 input요소(들)

jQuery('input', document.forms[0]) => 첫번째 form요소내의 input요소(들)

jQuery('input', 'body') => body요소내의 input요소(들)

  • DOM요소 필터링

    jQuery('a').filter('.external') => 모든 a요소 중 클래스명이 external인 a요소(들) (== jQuery('a').filter(function(index) { return $(this).hasClass('external'); }))

    jQuery('p').filter('.middle').end() => 모든 p요소 중 클래스명이 middle인 요소(들)의 필터링 전 요소(들) (== jQuery('p'))

  • 파괴작업 (end()도 파괴작업의 이) : 일치된 jQuery요소집합에 변경을 가하는 모든 종류의 작업
  • DOM요소 검색

    jQuery('p').find('em') => 모든 p요소 하위의 em요소(들) (== jQuery('em', $('p')) ==jQuery('p em'))

    jQuery('p').filter('.middle').find('span').end().end() => 모든 p요소 중 클래스명이 middle인 요소(들)의 하위 span요소(들)의 검색 전, 필터링 전 요소(들)

    (==jQuery('p'))

  • filter는 현재 요소(들)에 대해, find는 하위 요소(들)에 대해 작동
  • DOM 셀렉션 추가

    jQuery('div').find('p').andSelf().css('border', '1px solid #993300'); => div요소(들)과 하위 p요소(들) 모두에 대해 스타일 적용

  • DOM 탐색

    jQuery('li:eq(1)') => 두번째 li 요소

    관련메소드 => next():다음요소, prev():이전요소, parent():상위요소, children():하위요소들, nextAll():다음요소들, prevAll():이전요소들

    jQuery('li:eq(1)').parent().children(':last') => 두번째 li요소의 상위요소의 마지막 하위요소

    기타 탐색관련 메소드 : http://docs.jquery.com/Traversing

  • DOM요소 생성

    jQuery('<p><a>jQuery</a></p>'); => p요소 생성

    jQuery('<p><a>jQuery</a></p>').find('a').attr('href', 'http://www.jquery.com'); => p요소를 생성하고 하위 a요소(들)을 찾아 속성 변경

    jQuery('<p><a>jQuery</a></p>').find('a').attr('href', 'http://www.jquery.com').end().appendTo('body'); 

    => p요소를 생성하고 하위 a요소(들)을 찾아 속성 변경 후 생성된 p 요소를 body요소 하위로 포함시킴

  • DOM요소 제거

    jQuery('a).remove(); => 모든 a요소 제거

    jQuery('a').remove('.remove'); => 클래스명이 remove인 모든 a요소 제거

  • DOM요소 교체

    jQuery('li.remove').replaceWith('<li>removed</li>'); => 클래스명이 remove인 모든 li요소들을 뒤에 나온 li요소로 변경

  • DOM요소 복제

    jQuery('ul').clone().appendTo('body'); => 모든 ul요소들을 복제하여 body의 하위요소로 포함시킴

    jQuery('ul#a li').click(function() { //실행구문 }).parent().clone(true).find('li').appendTo('#b').end().end().remove();

    => 아이디가 a인 ul 하위의 li요소들을 클릭하면 함수를 실행시키고 부모요소인 ul요소를 찾아 복제(true이면 이벤트까지도 복제됨)한 후 복제된 ul의

    하위 li요소들을 찾아 아이디가 b인 요소의 하위요소로 포함시킨 후 기존 ul을 제거

  • 속성 제어

    jQuery('a').attr('href', 'http://www.jquery.com').attr('href'); => 모든 a요소의 href속성의 값을 설정하고 가져옴

    jQuery('a').attr({'href':'http://www.jquery.com', 'title':'jquery.com'}) => 모든 a요소의 href속성값과 title속성값을 설정

    jQuery('a').removeAttr('title') => 모든 a요소의 title속성 제거

  • class 조작

    addClass() : 클래스 추가  hasClass() : 클래스 값 확인  removeClass() : 클래스 제거  toggleClass() : 클래스 없으면 추가, 있으면 제거

  • HTML 컨텐츠 / 텍스트 조작

    jQuery('p').html('<strong>Hello World</strong>'); => 모든 p요소에 html컨텐츠 삽입

    jQuery('p').html(); => 모든 p요소의 html 가져옴

    jQuery('p').text('Hello World'); => 모든 p요소에 text 삽입 (text메소드는 html을 escape한다)

    jQuery('p').text(); => 모든 p요소의 text 가져옴

  • 전역적인 충돌 없이 $ 사용

    (function($) {

    })(jQuery);

 

  실습파일 :  Chapter1.html

 

 

[JQuery Cookbook - 2장 jQuery로 요소 선택하기]

 

  •  jQuery함수내에서 CSS셀렉터 사용
    jQuery('#content p a'); => id가 content인 요소의 하위 모든 p요소의 하위 모든 a요소들
    jQuery('#content p a').addClass('selected'); => 선택된 요소들에 selected 클래스 적용
  • 직속 자손 결합자 (>) : 계층적 관계
    jQuery('#nav li > a'); => id가 nav인 요소의 하위 모든 li요소의 직속 자손인 a요소들

    jQuery('> p', '#content'); => id가 content인 요소의 직속 자손인 p요소들 => jQuery('#content > p')와 같다

    jQuery('#content').children(); => id가 content인 요소의 모든 직속 자손들 => jQuery('#content').find('> *');과 같다

    jQuery('#content').children('p'); => id가 content인 요소의 모든 직속 p요소들

  • 인접 형제 결합자 (+) : 같은 레벨벨
    jQuery('h1 + h2'); => h1요소에 인접한 h2요소들 => jQuery('h1').next('h2');와 같다
    jQuery('h1').siblings('h2, h3, p'); => h1요소에 인접한 h2나 h3나 p 요소들
    jQuery('li.selected').nextAll('li'); => selected클래스를 가진 모든 li요소들 다음에 나오는 모든 li요소들
  • 일반 형제 결합자 (~)

    jQuery('li.selected ~ li'); => selected클래스를 가진 모든 li요소들 다음에 나오는 모든 li요소들

  • 필터

    • :first 첫번째 선택요소
    • :last 마지막 선택요소
    • :even 짝수번째 요소들
    • :odd 홀수번째 요소들
    • :eq(n) 인덱스가 n인 요소
    • :lt(n) 인덱스가 n보다 작은 요소들
    • :gt(n) 인덱스가 n보다 큰 요소들

      jQuery(':even'); => 문서내의 모든 짝수번째 요소들
      jQuery('ul li').filter(':first'); => ul요소다음에 나오는 첫번째 li요소들

  • 현재 에니메이션 중인 요소 선택
    jQuery('div:animated'); => 에니메이션 중인 div요소들

    jQuery('div:not(div:animated)').animate({height:100}); => 에니메이션 중이 아닌 div요소들의 높이를 100까지 에니메이션

  • 텍스트나 요소를 포함하는 요소 선택

    jQuery('span:contains("bob")'); => bob라는 문자열을 포함하는 span요소들

    jQuery('div:has(p a)'); => p요소 하위에 a요소를 가진 div요소들

    jQuery('p').filter(function() { return /(^|\s)(apple|orange|lemon)(\s|$)/.test(jQuery(this).text()); });

      => apple이나 orange나 lemon이라는 텍스트를 가진 p요소들

  • 일치되지 않는 요소 선택

    jQuery('div:not(#content)'); => id가 content가 아닌 모든 div요소들

    jQuery('a:not(div.important a, a.nav)'); => important클래스를 가진 div요소의 하위 a요소가 아니고 nav클래스를 가진 a요소가 아닌 a요소들

    jQuery('a').click( function() { jQuery('a').not(this).addClass('not-clicked'); } ); => a요소를 클릭하면 모든 다른 a요소들에 not-clicked클래스 추가

    $('#nav a').not('a.active'); => id가 nav인 요소의 하위 a요소들 중 active클래스를 가지지 않은 a요소들

  • 가시성 기반 요소 선택

    jQuery('div:hidden'); => 눈에 보이지 않는 div요소들

  • 속성 기반 요소 선택

    jQuery('a[href="http://google.com"]');=>href속성의 값이 http://google.com인 a요소들

    jQuery('*[title][href]'); => title과 href 속성을 모두 가지는 요소들

    jQuery('div[id^="content-sec-"]'); => id속성의 값이 content-sec-으로 시작하는 div요소들

  • 속성 셀렉터

    • [attr] 특정 속성을 가지고 있는 요소
    • [attr=val] 속성이 특정값을 가지는 요소
    • [attr!=val] 속성이 특정값을 가지지 않는 요소
    • [attr^=val] 속성이 특정값으로 시작하는 요소
    • [attr$=val] 속성이 특정값으로 끝나는 요소
    • [attr~=val] 공백과 함께 특정값을 포함하는 요소 (car는 car와 일치하지만 cart와는 불일치)
  • 폼요소 셀렉터

    • :text <input type="text" />
    • :password <input type="password" />
    • :radio <input type="radio" />
    • :checkbox <input type="checkbox" />
    • :submit <input type="submit" />
    • :image <input type="image" />
    • :reset <input type="reset" />
    • :button <input type="button" />
    • :file <input type="file" />
    • :hidden <input type="hidden" />

jQuery(':text'); => type속성의 값이 text인 모든 input요소들

jQuery(':input:not(:hidden)'); => 눈에 보여지는 모든 input요소들

jQuery(':text, :textarea'); => type속성의 값이 text이거나 textarea인 모든 input요소들

  • 특성을 갖는 요소 선택

    jQuery('*').filter(function() { return !!jQuery(this).css('backgroundImage') });

    => 배경이미지를 갖는 모든 요소들

    => !!는 타입을 불린으로 변경하기 위함

    => jQuery함수의 인자인 this는 모든요소들(*) 중 filter에 인자로 전달되는 시점에 함수에 인자로 전달된 요소를 가리키는데 

        요소를 jQuery함수의 인자로 넘겨 jQuery메소드를 사용할 수 있도록 함

    jQuery('div').filter(function() { var width = jQuery(this).width(); return width>100&&width<200; });

    => 넓이가 100보다 크고 200보다 작은 모든 div요소들

  • 컨텍스트 매개변수

    • 컨텍스트란 jQuery가 셀렉터 식에 의해 매치되는 요소를 찾을 장소
    • jQuery에 의해 사용되는 기본 컨텍스트는 DOM계층에서 최상위 항목인 document임. 즉, jQuery('p')는 jQuery('p', 'document')와 같다

jQuery('p', '#content'); => id가 content인 요소의 하위 p요소들 (이때 #content가 p의 컨텍스트) => jQuery('#content p');와 같다

jQuery('form').bind('submit', function() { var allInputs = jQuery('input', this); });

=> form요소들 중 submit이벤트가 일어나면 allinputs변수에 이벤트가 일어난 form의 모든 input요소들을 저장

 

실습파일 :  Chapter2.html

출처는 : http://mjmsoft.springnote.com/pages/6798267?print=1

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'Program > jQuery' 카테고리의 다른 글

jQuery Cookbook  (0) 2011/09/29
jQuery CSS 셀렉터 팁  (0) 2011/07/07
Posted by 마니씨
2011/08/22 10:41

ReflectMethod.java

package reflect;

public class ReflectMethod {
 
   //field
   public String field;
 
   //constructor
   public ReflectMethod() {}

   public ReflectMethod(String field) {

      this.field = field;
   }
 
   //method
   public String getField() {
      System.out.println("call field : " + this.field);
      return this.field;
   }
   public void methodA() {
      System.out.println("call method A");
   }
   public void methodB(String str) {
      System.out.println("call method B : " + str);
   }
   public String methodC() {
      System.out.println("call method C");
      return "method C";
   }
}


ReflectMain.java

package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectMain {
   public static void main(String[] arguments) throws
                                         ClassNotFoundException,

                                         InstantiationException,
                                         IllegalAccessException,
                                         SecurityException,
                                         NoSuchMethodException,
                                         IllegalArgumentException,
                                         InvocationTargetException,
                                         NoSuchFieldException {
 
  /*
   * 원시형 클래스 타입
   * char : Character.TYPE
   * byte : Byte.TYPE
   * short : Short.TYPE
   * int : Integer.TYPE
   * long : Long.TYPE
   * float : Float.TYPE
   * double : Double.TYPE
   */

 
      //클래스 가져오기
      Class getClass1 = Class.forName("reflect.ReflectMethod");
      Class getClass2 = ReflectMethod.class;
      Class getClass3 = new ReflectMethod().getClass();
 
      //클래스 객체를 이용한 객체 생성

      //생성자에 인자가 없는 경우

      Object object1 = getClass1.newInstance();
      //생성자에 인자가 있을 경우
      Class[] constructorParamClass = new Class[] {String.class};
      Object[] constructorParamObject = new Object[] {"Reflect Test!!!"};
      Constructor constructor = getClass1.getConstructor(constructorParamClass);
      Object object2 = constructor.newInstance(constructorParamObject);

      //필드 값 가져오기
      Field field = getClass1.getField("field");
      Object fieldObject = field.get(object2);
 
      System.out.println(fieldObject);
 
      //메소드 호출
 
      //메소드에 인자가 없는 경우
      Method method1 = getClass1.getMethod("methodA");
      method1.invoke(object1);
      //메소드에 인자가 있을 경우
      Class[] methodParamClass = new Class[] {String.class};
      Object[] methodParamObject = new Object[] {"1 parameter"};
      Method method2 = getClass1.getMethod("methodB", methodParamClass);
      method2.invoke(object1, methodParamObject);
      //메소드에 리턴값이 있을 경우
      Method method3 = getClass1.getMethod("methodC");
      Object returnObject = method3.invoke(object1);
 
      System.out.println("methodC return value : " + returnObject);
   }
}

콘솔출력결과
Reflect Test!!!

call method A
call method B : 1 parameter
call method C
methodC return value : method C

출처: http://mysnyc.tistory.com/42
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'Program > JAVA' 카테고리의 다른 글

자바(Java) Reflect 예제  (0) 2011/08/22
java smtp Mail 발송  (0) 2010/04/19
CronTrigger 의 표현식(Quartz)  (0) 2010/04/19
Quartz 스케줄러  (0) 2010/04/19
GRIDBAGLAYOUT 사용하기  (0) 2010/03/03
좋은 Swing 자료  (0) 2010/03/03
Posted by 마니씨
2011/07/07 15:43

jQuery 에서는 CSS 셀렉터 와 엘리먼트를 선택해 처리하는 방법을 사용합니다.

그러나 이런 CSS 셀렉터 사용법을 좀더 잘 사용하면 처리속도의 향상을 가져옵니다.


여기에서 jQuery의 내부 처리와 같은 코드를 보고, jQuery를 빠르게 사용하기 위한 TIP 5 를 소개하고자 합니다.

1. 여러번 같은 실렉터를 실행하지 않는다.

2. 클래스만으로 지정하는 것을 금지한다.

3. #id 의 사용을 적극 권장한다.

4. 도중까지 결과를 재이용 한다.

5. 자식 셀렉터(>)를 잘 사용하면 처리가 빨라진다.

 

1. 여러번 같은 실렉터를 실행하지 않는다.

ㅁ 개선전

 // 예제1 
 $("div.foo").addClass("bar"); 
 $("div.foo").css("background","#ffffff");
 $("div.foo").click(function(){ alert('foo'); } );

 

ㅁ 문제점

jQuery는 CSS 셀렉터를 쓸 때마다 DOM에서 셀럭터와 일치하는 엘리먼트를 찾습니다.

$("div.foo") 실행하면 뒤에서 jQuery는 아래과 같은 작업을 처리합니다.

 // 셀렉터로 선택한 결과를 저장하는 배열

 var ret = [];

 // div 태그 목록을 열거
 var elems = document.getElementsByTagName("div");

 // 각각 클래스명이 foo 의 것을 ret 에 추가
 for(var i = 0; i < elems.length; i++){
    var classes = elems[i].className.split(" ");
    if(classes.indexOf("foo") != -1){
        ret.push(elems[i]);
    }
 }


  HTML 안에 포함됨 div 태그를 열거하고, 각 클래스명을 조사해 가는 것입니다.
 (Array.indexOf (은)는 비표준입니다만, 간단하게 쓰기 위해서 사용하고 있습니다)

  즉, 모두의 코드와 같이 $("div.foo") (을)를 3회 써 버리면 위에서처럼 처리가 3회 실행되어 버립니다. 비효율적이지요.

ㅁ 개선방법1: 캐쉬
  셀렉터의 실행 결과를 변수에 캐쉬해 둡니다. 2회 분의 $("div.foo") 실행시간을 단축시킬 수 있습니다.
 // 코드 1-1
 var foos = $("div.foo");
 foos.addClass("bar");
 foos.css("background", "#ffffff");
 foos.click(function(){alert('foo');});

ㅁ 개선방법2: 메소드 체인
  메소드 체인을 사용하면, jQuery 같아지고 처리 효율도 오릅니다.
 // 코드 1-2
 $("div.foo")
    .addClass("bar")
    .css("background", "#ffffff")
    .click(function(){alert('foo');});

$("div.foo")실렉터의 실행 결과가 다음의 메소드에 차례로 인계됩니다. 임시 변수를 필요로 하지 않는 것도 장점입니다.


2. 클래스만을 지정하는 것은 금지

ㅁ 개선전
 // 예제 2
 $(".foo").css("display", "none");

ㅁ 문제점
  클래스명 만을 지정하면, jQuery는 모든 HTML 노드를 열거하고, 각 클래스명을 확인합니다.

$(".foo") 의 배후는 다음과 같은 처리가 실행됩니다.
 // 셀렉터로 선택한 결과를 저장할 배열
 var ret = [];

 // 모든 태그를 열거한다
 var elems = document.getElementsByTagName("*");

 // 각 클래스명이 foo 의 것을 ret 에 넣는다
 for(var i = 0; i < elems.length; i++){
     var classes = elems[i].className.split(" ");
     if(classes.indexOf("foo") != -1){
        ret.push(elems[i]);
     }
 }

  모든 태그를 열거하여 루프를 돌리기 때문에 비효율적입니다.
  조금, 이야기가 빗나가지만 Firefox3 나 Opera9.5, Safari3 에는 getElementsByClassName() 메소드가 기본으로 포함되어 있습니다. 그 때문에 이러한브라우저는 빠른 $(".foo") 를 실행할 수 있는 능력을 가지고 있습니다. 그러나, jQuery 1.2.6 의 시점에서는 기본 getElementsByClassName()을 사용하고 있지 않습니다.

  jQuery 의 차기 CSS 셀렉터인 Sizzle는 getElementsByClassName()가 정의되는 경우에 사용하도록 구현되어있는 것 같습니다.

ㅁ 개선방법: 태그를 명시 한다
  태그를 명시합니다.
 $("div.foo").css("display", "none");

  모든 노드로부터가 아닌,  지정된 태그중에서 클래스명으로 검색이 좁히게 되어, 루프의 회수가 큰폭으로 줄어듭니다.


3. #id 를 적극적으로 사용한다

ㅁ개선전
 <body>
   <script src="jquery.js"></script>
   <script>
     $(function(){
       $(".main").css("color", "red");  //문제 부분
     });
   </script>
   <div class="main">
   < ... >
   </div>
 </body>

ㅁ 문제점
  반복적으로 언급해온 대로 jQuery는 클래스 이름으로 검색하는 것은 비효율적이다.

  HTML 설계의 이야기가 되어 버립니다만, HTML 중 1번만 등장하지 않는 클래스명은 id 화 하는게 좋습니다. 그 편이 JavaScript 에서 취급하기에도 형편상 좋습니다.

ㅁ 개선방법
  main 을 클래스가 아닌 id 로 변경합니다.
 <body>
   <script src="jquery.js"></script>
   <script>
     $(function(){
       $("#main").css("color", "red"); // 해결부분
     });
   </script>
   <div id="main">
     < ... >
   </div>
 </body>
  jQuery는 셀렉터에 id 가 지정되어 있을 경우에는 재귀적으로 탐색하지 않고 getElementById() 를 이용합니다. 따라서 모든 노드를 열거하는데 비해 비교적 빠른 처리를 할 수 있습니다.

4. 도중까지의 결과를 재이용한다

ㅁ 개선전
 <body>
  <script src="jquery.js"></script>
  <script>
    $(function(){
      $("#main div.entry").css( ... );
      $("#main div.entry div.body")  // 문제부분
          .css( ... );
    });
  </script>
  <div id="main">
    <div class="entry">
      <div class="header"> ... </div>
      <div class="body"> ... </div>
    </div>
    <div class="entry">
      <div class="header"> ... </div>
      <div class="body"> ... </div>
    </div>
  </div>
 </body>

ㅁ 문제점
아래를 읽어 보면 이 경우에 대해 알수 있습니다.
  $("#main div.entry")              // (1)
  $("#main div.entry div.body")     // (2)

 (2) 의 셀렉터에서는,
   1. #main 을 탐색
   2. 그 자손으로부터 div.entry 를 열거
   3. 그 자손으로부터 div.body 를 열거
 
  는 작업을 실행합니다. 이 중 1~2는 (1)(과)과 완전히 같은 처리입니다. (1)에서 구한 결과를 다시 사용하면 처리속도가 향상할 것입니다.

ㅁ 개선방법 : 캐쉬 전략
  var entries = $("#main div.entry").css( ... );
  $("div.body", entries).css( ... );

  $() 함수의 제2 인수에는 CSS 셀렉터를 찾는 기점을 지정할 수 있습니다. (1)의 결과에 포함된 엘리먼트의 자식에서 div.body 를 찾아 줍니다.

find() 메소드를 사용해도 괜찮을 것입니다.
  var entries = $("#main div.entry").css( ... );
  entries.find("div.body").css( ... );

어라?  여기까지 오면  메소드 체인이 생길 것 같네요.
 $("#main div.entry").css( ... )
     .find("div.body").css( ... );


ㅁ 응용 사례
  div.head 도 찾고 싶은 경우에는 어떻게 하면 좋을 까요?

  네, 이렇게 하면 좋겠네요.
 var entries = $("#main div.entry").css( ... );
 entries.find("div.body").css( ... );
 entries.find("div.head").css( ... );

  이 녀석도 메소드 체인 해보죠. end()를 사용하면, find()로 찾기 이전 상태에 되돌릴 수 있습니다.
 $("#main div.entry")
     .css( ... );
     .find("div.body") // #main div.entry div.body 가 된다
         .css( ... )
     .end()            // #main div.entry로 돌아온다
     .find("div.head") // #main div.entry div.head 가 된다
         .css( ... )
     .end();
 
   여기까지 오면 곡예수준입니다만.....윈래 코드보다 더 빠르다는것은 틀림없습니다.


5. 자식 셀렉터(>)를 사용하면 빨라질수 있다.

ㅁ 개선전

 <body>
   <script src="jquery.js"></script>
   <script>
     $(function(){
        $("#main div.entry").css( ... ); // ← 코코
     });
   </script>
   <div id="main">
     <div class="entry">
       <div class="header"> ... </div>
       <div class="body"> ... </div>
     </div>
     <div class="entry">
       <div class="header"> ... </div>
       <div class="body"> ... </div>
     </div>
   </div>
 </body>

ㅁ 문제점
 ' #main div.entry '는 #main 의 후에 자손 실렉터(스페이스)가 있습니다. 즉, #main 노드아래의 모든 div 노드로부터 entry 클래스를 찾아냅니다.

$("#main div.entry") 의 배후에서는 다음과 같은 처리가 실행되고 있습니다.
 // 셀렉터로 선택한 결과를 저장하는 배열
 var ret = [];
 
 // #main을 찾는다
 var main = document.getElementsById("main");

 // #main의 아래에서 전체 div 를 열거한다
 var elems = main.getElementsByTagName("div");

 // 각 클래스명이 foo 의 것을 ret 에 넣는다
 for(var i = 0; i < elems.length; i++){
     var classes = elems[i].className.split(" ");
     if(classes.indexOf("foo") != -1){
         ret.push(elems[i]);
     }
 }

  elems 에는 div#main 의 아래의 모든 div 태그가 저장됩니다. 이 모두에 대한 클래스명을 확인하는 것이, 경우에 따라서는 늦어져 버립니다.

  만약,div.entry 가  div#main 아래에만 존재한다면, "자손 실렉터"는 아니고 "자식 셀렉터"를 사용하면 효율적으로 동작할지도 모릅니다.

ㅁ개선방법
  자식 셀렉터(>)를 사용합니다.
    $("#main > div.entry").css( ... );

jQuery 그럼 자식 셀렉터가 나오면, 모든 자손이 아니고, 자식중에서 매치하는 것을 조사합니다. 손자와 그 자식에 대해서는 조사하지 않기 때문에, 고속화가 기대됩니다.

$("#main > div.entry") 의 배후에서는 다음과 같은 처리가 실행됩니다.
 // 셀렉터로 선택한 결과를 저장하는 배열
 var ret = [];

 // #main 를 찾는다
 var main = document.getElementsById("main");

 // #main 자식 노드중에서
 // 태그 이름이 DIV이고, 클래스명이 entry 의 것을 ret에 넣는다
 var child = main.firstChild;
 while(child){
     var classes = elems[i].className.split(" ");
     if (child.tagName == "DIV"
     && classes.indexOf("entry") != -1){
         ret.push(child);
     }

     child = child.nextSibling;
 }
꼭 자식 셀렉터를 사용하면 반드시 빨리된다 싶지 않지만 자식의 수에 비해 자손이 많은 경우, 자식셀럭터 쪽이 빨라집니다.

ㅁ 실제 코드 시험
  실제로 브라우저로 실행했을 때에 CSS 실렉터에 의해서 처리 속도가 얼마나 개선하는지를 확인해 봅시다.

시험은 블로그의 HTML 에서 실행해 보았습니다. HTML 구조는 다음과 같습니다.
 <div id="days">
    <div class="day">
        <h2>2008년12월11일</h2>
        <div class="body">
            <div class="section">
                <h3>타이틀</h3>
                <p>본문</p>
            </div>
        </div>
    </div>
    <div class="day"> ... </div>
    <div class="day"> ... </div>
 </div>

이러한 HTML 에 대해서,jQuery (을)를 실행해 보았습니다.
 CSS 셀렉터
 FireFox 2
 IE7  Opera9  Safari(win)
 .body  22.18ms  19.85.ms 5.32ms
2.49ms
 div.body  2.34.ms  2.82.ms 1.24ms
 0.49ms
 #days >div.day>div.body  2.66.mx  1.72ms 1.25ms
 0.44ms
    * 모든 브라우저로,.body 에 비해 div.body (분)편이5~10배속구 되어 있다.
    * #days > div.day > div.body 는 아이 셀렉터를 2회 사용하고 있는데,
      div.body 와 같을 정도의 속도로 실행 되어 있다.


마지막에

  jQuery 는 라이브러리인 이상, DOM 을 직접 접근하는데 비해 늦어지는 것은 피할 수 없습니다.
  아무래도 처리 속도가 신경이 쓰이는 경우는, jQuery 의 코드를 DOM 를 직접 컨트롤하는 코드로 변환하면 좋을 것입니다. 경험적으로 Firefox 나 IE 그리고 처리 속도가10배정도가 됩니다.
  다만, 개발 효율설 측면에서는 처음에 jQuery 를 사용해 쓰기 시작하는 것을추천합니다.
jQuery 의 코드를 DOM 직접 변환하는 것은 간단합니다만, DOM 직접으로 개발을 진행시키는 것은 귀찮지요. 
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'Program > jQuery' 카테고리의 다른 글

jQuery Cookbook  (0) 2011/09/29
jQuery CSS 셀렉터 팁  (0) 2011/07/07
Posted by 마니씨
2011/06/30 11:48

개발하기 귀찮을땐.... 이용을 ㅋㅋㅋ

http://www.yjkim.net/mimetool

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 마니씨
2010/10/15 15:47


MS-SQL 트랜잭션 백업 작업을 걸었는데...

BACKUP LOG is terminating abnormally

라면서.... 에러가 난다 ㅠ

트랜잭션 로그백업은 전체 백업을 받은 시점부터의 트랜잭션을 백업하는 개념이라서.....
전체백업본이 있어야만 한다는 ㅠ
전체 백업후에 실행해보자 잘되는것이 눈에 보인다 ㅠㅠ

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 마니씨