이러쿵저러쿵


JQuery를 통해 Javascript 코드 상에 HTML 객체(Object)를 제어하는 경우가 많이 있습니다.

이 때에 객체의 특정 class 값을 이용하여 다수의 객체에 동시 접근하여 제어를 하거나 한 번에 동일한 CSS를 적용하는 등 다양한 용도로 사용할 수 있습니다.

 

class 속성은 다양한 용도로 사용되는데요. 이러한 속성값이 특정 객체에 포함되어 있는지 여부를 확인하는 방법은 어떤 방법이 있을까요?

JQuery를 통해서 특정 객체(Object)가 특정 클래스 속성 값을 가지고 있는지 알아내는 다양한 방법에 대해서 알아보겠습니다.

 

 

<div id="div_test" class="milk apple house">

...

</div> 

 

 

 

위의 div HTML 객체는 3가지의 class 속성 값을 가지고 있습니다. 그럼 위의 객체가 apple 속성을 가지고 있는지 확인하는 방법에는 어떤 것들이 있을까요?

 

 

1. hasClass 함수 사용

 

if($("#div_test").hasClass("apple") === true) {

// 속성값이 존재함.

}

 

ID가 div_test 인 객체가 class apple 을 가지고 있는지 체크합니다.

hassClass 는 해당 객체가 파라메터로 들어온 속성 값을 가지고 있는 경우 true를 반환합니다.

이 함수는 JQuery 1.2 버전에서 추가되었습니다.

 

 

 

2. is 함수 사용

 

if($("#div_test").is(".apple") === true) {

// 속성값이 존재함.

}

 

is 함수를 통해 특정 class를 포함하고 있는지 체크합니다.

is 함수에는 class 외에 id, name 등도 사용 가능하므로 반드시 클래스 이름 앞에 . 을 찍어서 클래스 속성임을 명시해 주어야 합니다.

 

 

3. length 속성 체크

 

if($("#div_test.apple").length) {

// 속성값이 존재함.

}


 

apple 클래스 속성 자체가 존재한다면 length 길이가 1이 됩니다. 존재하지 않는다면 length 길이는 0이 됩니다.

이 length 값이 있는지 여부를 체크하여 class 속성이 존재하는지 확인할 수 있습니다.

 

 

위에서 처럼

hasClass 와 is 함수 그리고 length 속성을 통해 객체가 특정 class 를 포함하고 있는지 여부를 체크할 수 있습니다.

 

그럼 위의 방법 들 중에서 어떤 것을 사용하는 것이 좋을까요?

 

사실 용법만 조금 다를 뿐이지, 차이점은 거의 없습니다. 취향 따라 쓰면 되겠습니다.^^

 

라고 하면 좋겠지만, 그래도 좀 더 나은 것을 사용하고 싶다. 하신다면..

코드를 작성하는데에 있어서 어떤 것을 중시하는지에 따라 다르겠지만.. (가독성, 성능(속도), 서비스 부하 등등)

 

 

속도를 중시한다고 한다면!! 어떤 것을 사용하는 것이 더 좋을까요?

 

jsMacth(http://jindo.dev.naver.com/jsMatch/index.html) 라는 Javascript 코드 성능 비교 사이트에서 앞의 1번과 2번 두 코드의 성능을 비교해 보았습니다.

 

결과는 다음과 같았습니다.

 

 

 

 

 

결과 좀 더 자세히 보러가기 : http://jindo.dev.naver.com/jsMatch/index.html?d=183

 

크롬 43버전, ie(인터넷 익스플로러) 8,9,10,11, 사파리, 파이어폭스, 총 7개의 브라우저로 테스트 해보았습니다.

위에 보면 mozilla11 이라고 되어 있는데 저건 인터넷익스플로러11 입니다. jsMatch 를 업데이트 해주지 않아서 그런지 ie11 을 mozilla11 로 인식하네요. ㅡ.ㅡ;

 

IE에서는 두 구문이 아주 큰 차이를 보이지는 않지만, 크롬이나, 사파리, 파폭에서는 어느정도 성능 차이가 있는 것으로 보입니다. IE도 차이가 크지만 않을 뿐, hasClass 가 조금더 성능이 좋네요. (속도 측정은 컴퓨터 환경 등에 영향을 받기도 하기 때문에 테스트할 때마다 항상 동일한 결과를 주지는 않지만, 대체적으로 비슷한 수치를 보입니다.)

 

테스트는 0.1초 동안 1번 코드가 실행된 횟수만큼 2번 코드를 실행하여 걸린 상대적인 시간을 표시합니다.

 

아마 클래스 존재 여부 만을 체크하기 위한 함수와 모든 객체 타입 및 속성에 대응하는 약간은 범용적인 함수에는 어느정도 차이가 있는 것으로 보입니다.

 

 

별도로 포스팅에 작성하지는 않았지만, 1번과 3번의 코드 또한 성능 비교를 해 보았을 때에도, 1번의 성능이 더 좋게 나왔습니다.

 

그러니 객체의 특정 클래스 존재 여부를 확인할 수 있는 위의 3가지 방법 중에서 성능을 고려하신다면 1번의 방법을 사용하시는 것을 추천드립니다. 그런데 아마도 성능 이런 것을 떠나서라도 보통 1번을 많이 사용하고 있는 것으로 알고 있습니다. 함수 명도 직관적이지 않습니까?^^

 

 

실제 위의 각각의 코드를 한 번 실행 하는 정도는 그 실행 소요 시간이 수만 수십만 분의 1 정도의 차이만 날 정도로 그 차이가 미미합니다.

 

하지만 대규모 포털 사이트를 개발 및 운용하거나 방문자가 많은 커뮤니티를 운용하는 경우라면 이러한 작은 성능 개선도 무시못할 수준이 될 겁니다.

 

위의 1번 코드와 2번 코드를 3,500번 정도 수행한 시간을 비교하였을 때에는 약 0.015 초 정도 차이가 있었습니다. 15/1000 분의 성능 효과가 있었던 것이지요. 하루 동안에 위의 코드가 실행되는 페이지가 약 350,000번 정도 읽혀졌다면 약 1.5초의 성능 효과가 있는 것입니다. 그리고 저 코드 하나만 있는 것도 아닐 것이고, 유사한 코드가 상당히 많을 수 있기 때문에 is 나 length 대신 hasClass를 사용하는 것의 성능 개선은 무시하지 못할 것입니다.^^

 

 

 

 

 

 

저작자 표시 비영리 변경 금지
신고


Comment +6

  • 질문이 있습니다. ㅠ 특정 문구열 포함 여부를 확인하기 위해서는 어떻게 하면 좋을까요? ㅠ

    if (!($('span.bread bread-page').filter(":contains('Site/Social/Tech/sdfsdf')") > 0)) {
    $('.menubarrr').show();

    }

    특정 카테고리에서 .menubarrr 를 나타나게 하려고하는데 ㅠ 잘하기가 힘듭니다.

    • 안녕하세요. COCO Media 님^^

      특정 문구열 포함 여부를 확인하려면 보통 indexOf를 많이 사용합니다. 간단하죠.

      strData 문자열 내에 site라는 문자열이 포함되어 있는지 체크하는 코드는 아래와 같습니다. site 문자열이 포함되어 있다면 문자열의 시작 위치(index)를 반환합니다 문자열이 없다면 -1을 반환합니다.

      if(strData.indexOf("site") >= 0) {
      // Do Something
      }

      질문주신 내용중에 filter 관련 코드가 있는데요.
      $().filter(":contains()) ... JQuery 문법은 특정 텍스트를 포함하고 있는 요소에 대해 반환하고, 해당 요소들에 대해 처리를 하는 문법입니다. 특정 요소들에 대해 일괄적으로 CSS속성 값을 주거나 할때 사용합니다. 결과로 $() 요소 내의 contains() 내의 텍스트를 포함하고 있는 오브젝트들을 반환하기 때문에 실제 반환되는 오브젝트가 있는지 체크하는 방식으로 해야 합니다. (length 값 체크)
      예시
      if($('span').filter(":contains('Site/Social/Tech/sdfsdf')").length > 0) {
      // Show Menubar
      }

      그리고 코드 상에서 Site/Social/Tech/sdfsdf 라는 문자열을 contains 내에 두셨는데, 정말 해당 문자열 전체가 포함되어 있는 경우를 의미하신 것인지, 아니면 Site, Social, Tech 또는 sdfsdf 문자열 들중에 하나만 포함하면 메뉴바를 보여주시려고 하신 것인지 정확한 의도를 확인하지 못하였습니다. 만약 4개의 각각의 문자열 중 하나라도 포함된 경우 처리하시려고 하신 것이라면 위의 코드는 동작하지 않습니다. 그러한 경우, 각 문자열들을 배열로 만들어 루프를 돌며 체크하시거나, 특정 패턴이 있다면 정규표현식을 사용해서 처리해야 합니다.

      제가 질문 의도를 제대로 파악했는지, 답변이 제대로 되었는지 잘 모르겠네요.^^ 다른 궁금한 것이 있다면 질문 주세요!

      좋은 밤 되세요~

  • 정말 친절한 답변감사합니다. ㅠ_ㅠ 며칠째 고민을하는 거였는데 너무쉽게 해결을 해주셨습니다.
    구글을 검색해봐도 하나도 나오지 않았는데 정말 감사합니다.ㅠㅠ

    여러 카테고리중에 'Site/Social/Tech' 카테고리과 'Html&Css 편집' 카테고리에서만 나타나게 하려고했는데

    if($('span').filter(":contains('Tech')").length > 0) {
    // Show Menubar
    }
    if($('span').filter(":contains('Html')").length > 0) {
    // Show Menubar
    }
    이런식으로 적어서 나타나게 하는데 성공했습니다^^ 다만 ㅠ 이렇게 2개를 적는게 맞는지 잘모르겠습니다. ㅠㅎㅎ


    혼자서 독학으로 여기저기보면서 웹언어를 배우다보니 html과 css는 어느정도 알겠는데..정확한 용어는 잘모르고ㅠ 요며칠 이문제로 계속 검색해서 보고있는데 ㅠ JS나 jQuery쪽은 막막하더라구요. 그래서 html/css/JS 생활코딩 기초강좌를ㅠ 들어볼까하고 있었습니다 ㅎㅎ;; 시간 날 때마나 틈틈히 배워야겠습니다. 다시 한 번더 정말 감사하고 자주블로그 방문해서+_+ 많이 배우도록할게요. 좋은 밤 되세요

    • 안녕하세요. COCO Media 님.^^

      요즘 너무 정신없이 바빠서 ㅠ.ㅠ 답변을 너무 늦게 달아드렸던 것 같아요. 그래도 문제가 해결되었다니, 다행입니다.

      전체적인 코드를 본 것은 아니라서 정확하지 않을 수도 있지만,
      'Site/Social/Tech' 와 'Html&Css 편집' 카테고리에 만 나오게 하실 거라면 이렇게 조건문 if 하나로 쓰셔도 무방합니다.

      if($('span').filter(":contains('Site/Social/Tech')").length > 0 || $('span').filter(":contains('Html&Css 편집')").length > 0) {
      // Show Menubar
      }

      COCO Media님이 코드에 'Tech' 와 'Html' 텍스트만 비교하셨는데, 차 후에 Tech 또는 Html 텍스트가 포함된 다른 메뉴 (예 - Html 강좌)가 새로 추가된다면 해당 카테고리에도 메뉴바가 나타나게 됩니다.^^

      지금 상태로도 큰 문제는 없다고 하시니, 그냥 사용하셔도 무방하지만, 정확하게 위의 2개 카테고리만 적용시키실 것이라면 텍스트를 정확하게 비교하시는 것이 좋을 수 있습니다.^^

      그래도 혼자 독학으로 코드 짜시고, 블로그 꾸미시는게 대단한 것 같습니다.^^
      또 놀러오세요~

    • 우와. 제가 원하는 코드였습니다.ㅠ 다중if문으로 검색해보니 elseif만 나오길래.. 음.. 먼가 두개쓰지않고 하나로.. 깔끔하게 정리 될 것 같았는데... || 이게 or의 의미였네요! +_+ 정말 감사합니다..!!

    • 에공 너무 늦게 댓글을 확인했네요.^^

      네^^ 도움이 된 것 같아 저도 기분이 좋네요^^

      좋은 주말 되세요! 가끔 놀러오세요~ ㅎㅎㅎ

티스토리 툴바