jQuery

05_1. jQuery 빠르게, 간단하게, 더욱 재미있게

개발여우 2011. 1. 21. 13:58
5장은 챕터가 많기 때문에 반으로 나누어 요약 정리한다.

5.2 $(this)에 무슨 문제가 있을까?
# 1번코드
========================================
$(document).ready( function() {
  $('.clicky').click( function() {
    $(this).addClass('clicked');
      setTimeout( function(){
        $(this).removeClass('clicked');
      }, 1000 );
    });
});
========================================
:: setTimeout을 이용하여 1초간 대기하다 clicked란 클래스를 제거하려는 목적 하지만 동작 하지 않는다.
:: setTimemout의 $(this)가 동작하지 않는듯 하다.

# 2번코드
========================================
$(document).ready( function() {
  $('.clicky').click( function() {
    var element = this;
    $(element).addClass('clicked');
      setTimeout( function(){
        $(element).removeClass('clicked');
      }, 1000 );
    });
});
========================================
:: element변수에 this를 저장하여 각기 호출한다.

# 3번코드
========================================
$(document).ready( function() {
  $('.clicky').click( function() {
    var $element = $(this);
    $element.addClass('clicked');
      setTimeout( function(){
        $element.removeClass('clicked');
      }, 1000 );
    });
});
========================================
:: 2번코드는 $()를 두번 호출하기 그보다 $()을 한번 호출하고 이를 jQuery개체 ($element)에 저장한다.
:: 이리하면 한번 호출로도 위아래에서 두번 사용가능하다.
:: $()는 jQuery()의 축약형일 뿐이다.

# 4번코드
========================================
<a href="#" id="test" onclick = "clicked(this);">Test</a>
function clicked( it) {
  alert( it.id);                     //true;
  alert( this.id );                 //undefined
  alert( this === window );   //true (what?)
}
========================================
:: 이 예제는 this는 이벤트를 가진 요소를 가리킨다. 함수내부에서는 window개체이며 
:: 기본적인 의미가 this=window이다.

5.3 장황한 중복 제거하기
# 1번코드
=================================================
$(document).ready( function() {
  var $country = $('#country');
  function setVisibility(){
    var value = $country.val();
    $('#state').toggle( value == 'US' );
    $('#province').toggle( value =='CA');
  }
  setVisibility();
  $country.bind( 'change keyup', setVisibility );
});
=================================================
:: 책에 있는 예제를 .bind를 이용하고 함수를 이용해서 정리한 방법 (표준적인 해결방식)

# 2번코드
=================================================
$(document).ready( function() {
  $('#country')
  .bind ( 'change keyup', function(){
    var value = $(this).val();
    $('#state').toggle( value == 'US');
    $('#province').toggle( value =='CA');
  })
  .trigger('change');
});
=================================================
::시작시와 이벤트 발생시 모두에 대해 공용 함수를 사용한다.
::함수에 이름 부여하여 시작 시에 직접적으로 호출하도록 하기보다는 change이벤트에 대한
::이벤트 처리기로 함수를 설정하여 trigger() 메서드를 사용하여 이벤트를 발생시키는 방식을 사용
::(함수를 간접적으로 호출한다.)

5.4 jQuery 체인 가독성 높이기
1) $('#box').addClass('contentbox').children(':header').addClass('contenttitle')
2)         $('#box')
.addClass('contentbox')
.children(':header')
.addClass('contenttitle')
:: 1)보다는 2)방식으로 쓰는게 가독성에서 좋다.

5.5 다른 라이브러리에서 코드 빌려쓰기 (ext Core Library)
<div>
  <div id="one" class="hilite">One</div>
  <div id="two">Two</div>
  <div id="three">Three</div>
  <div id="four">Four</div>
</div>

$('#three').radioClass('hilite');

//간단한 플러그인
jQuery.fn.radioClass = function( cls ) {
  return this
    .siblings()
    .removeClass(cls)
    .end().addClass(cls);
};

:: radioClass는 #one의 형제들을 선택 cls란 class를 모두 삭제하고 end()으로 이전의 상태로 셀렉트한뒤
:: 다시 cls를 적용한다 따라서 #on에 있던 클래스를 지우고 다시 전체에 클래스를 넣어주는 셈이 된다.

:: jQuery.fn은 jQuery.prototype과 동일한 개체를 참조한다. 그냥 동일하다 봐도 무방하다.
:: jQuery() 나 $()를 사용하여 개체를 만든다면 실제로는 new jQuery()를 호출하는 것이나 마찬가지이다.

:: jQuery.fn을 만든이유 protytype의 별명으로 호환성을 위해 사용한다.

5.6 사용자 정의 반복기 작성하기
# 코드
=================================================
// 배열(일반적으로는 jQuery 배열, 하지만 일반 배열이 될 수도 있다)을 반복하면서
// 각 요소에 대해 콜백 함수를 호출한다. 단, 각각의 콜백 사이에 시간 지연을 두도록 한다.
// 콜백은 일반적인 jQuery.each() 콜백과 동일한 매개변수를 갖는다.
jQuery.slowEach = function ( array, interval, callback ) {
  if( ! array.length ) return;
  var i=0;
  next();
  funcntion next(){
    if(callback.call ( array[i], i, array[i] ) !== false)
      if( ++i<array.length)
        setTimeout( next, interval);
    }
  return array;
  };

  // "/turn array:e개체)를 반복하면서 각 요소에 대해 콜백 함수를 호출한다.
  // 단 각각의 콜백 사이에는 지연 시간을 두도록 한다.
  // 콜백은 일반적인 jQuery(rray;ext, 와 동일한 매개변수를 갖는다.
  jQuery.fn.slowEach = function ( interval, callback){
    return jQuery.slowEach( this, interval, callback );
  };

  //0.5초마다 요소를 보이게 한다.
  $('.reveal').slowEach( 500, function(){
    $(this).show();
  });
=================================================

5.7 어트리뷰트 토글하기
 체크박스 그룹에서 모든 체크 표시를 토글하기 위한 방법
 jQuery.fn.toggleCheck = function ( check ){
   return this.toggleAttr( 'checked', true, false, check );
};
$('.toggleme').toggleCheck( true );  //동작 허용
$('.toggleme').toggleCheck( false );  //동작 금지

::이부분은 좀 이해가 되지 않으므로 담에 다시한번 살펴볼것

5.8 병목현상 파악하기
프로파일러사용 
::일단 패스

5.9 jQuery 개체 캐시하기
$('.clientX').html(event.clientX );
$('.clientY').html(event.clientY );
등을
var $clientX = $('.clientX') 등으로 캐시한뒤 사용하면 반복사용시 속도 향상의 효과가 있다.

한마디로 개체들을 변수에 저장한다는이야기

5.10 보다 빠른 셀렉터 작성하기
<div class="foo"></div>
<div id="bar"></div>
$('.foo')  // 느림
$('#bar') // 빠름
클래스보다 아이디값으로 겁색하는것이 훨씬 빠르다.

:: id로 검색할때는 브라우저에서 포인터처럼 한번에 접근이 가능하다고 하다
:: 하지만 class같은 경우는 리스트처럼 되어있고 이를 순차적 검색과정을 거치기 때문에
:: 느릴 수 밖에 없다고 한다 id class를 혼용해서 사용할경우 class만 사용하는것 보다는 속도가 향상된다

5.11 빠르게 테이블 로딩하기
최적화 방법
1. 여러개의 <tr>요소 대신 단일 <table> 또는 <tbody>를 삽입한다.
2. DOM 조작 대신 .innerHTML이나 .html()을 사용한다.
3. 문자열 결합대신 a[++i]배열과. join()을 사용한다.
4. $.each대신 순수 for 루프를 사용한다.
5. 이름 조회를 줄인다.
# JSON data
=================================================
[
  "names" : [
  {
    "first" : "Azzie",
    "last" : "Zalenski",
    "street" : "9554 Niemann Crest",
    "city" : "Quinteros Divide",
    "state": "VA",
    "zip": "48786"
  },
  //1000개의 이름 반복
 ]
}

# 코드1 - 느리지만 깔끔
=================================================
<html>
<head>
  <title>5.11</title>
  <script src="script/jquery-1.4.2.min.js" type="tetxt/javascript"></script>
  <script type="text/javascript">
  // & < > 기호를 변경하여 텍스트의 깔끔한 버전을 반환한다.
  function esc( text ) {
    return text
      .replace( '&', '&amp;' )
      .replace( '<', '&lt;' )
      .replace( '>', '&gt;' )
  }
  $(document).ready( function() {
    function filTable ( names ) {
      $.each( names, function() {
        $('<tr>')
          .append( $('<td>').addClass('name').html(
            esc(this.first) + ' ' _ esc(this.last)
          ))
          .append( $('<td>').addClass('address').html
            esc(this.street) + '<br/>' + 
            esc(this.street) + ', ' + 
            esc(this.street) + ' ' + esc(this.zip)
          ))
          .appendTo('#nameTable');
        });
    }
    $.getJSON( 'names=1000.json', function( json ) {
      fillTable( json.names );
    });
  });
  </script>
</head>
<body>
 <table id="nameTable">
 </table>
</body>
</html>

# 코드2
=================================================
<html>
<head>
  <title>5.11</title>
  <script src="script/jquery-1.4.2.min.js" type="tetxt/javascript"></script>
  <script type="text/javascript">
  // & < > 기호를 변경하여 텍스트의 깔끔한 버전을 반환한다.
  function esc( text ) {
    return text
      .replace( '&', '&amp;' )
      .replace( '<', '&lt;' )
      .replace( '>', '&gt;' )
  }
  $(document).ready( function() {
    function filTable( names ) {
      //지역 함수를 사용하여 이름 조회를 줄인다.
     var e = esc;
    var html = []; h=-1;
    html[++h] = '<table id = "nameTable">';
    html[++h] = '<tbody>';
    for( var name, i = -1; name = names[++i];) {
      html[++h] = '<tr><td class="name">';
      html[++h] = e(name.first);
      html[++h] = ' ';
      html[++h] = e(name.last);
      html[++h] = '</td><td class="address">';
      html[++h] = e(name.street);
      html[++h] = '<br />';
      html[++h] = e(name.city);
      html[++h] = ', ';
      html[++h] = e(name.state);
      html[++h] = ' ';
      html[++h] = e(name.zip);
      html[++h] = '</td>,/tr>';
    }
    html[++h] = '</tbody>';
    html[++h] = '</table>';
    $('#container')[0].innerHTML = html.join('');
  }
  $.getJSON( 'names-1000.json', function( json ) {
    fillTable ( json.names );
  });
});
</script>
</head>
   <body>
    <div id="container"></div>
  </body>
</html>