IE8 에서 :checked 가 css 에서 활용 안되기 때문에 발생하는 이슈

해당 포스트는 사실 제작년에 알았던 이슈이고..
작년에 팀분들과 이야기 하다가 정리했던 이슈인데 작성만 해놨다가 이제야 올리게 된다. ( 반성..)

그래도 나름 신기했던 동작이였고, 나중에 누군가에게는 도움이 될것 같아서 정리해둔다.

보통 HTML5 에서는 checked, selected, disabled, readonly 등의 attribute 를 사용할때 아래와 같이 쓰게 된다.

 <input type="checkbox" checked> <!-- 이렇게 쓰는걸 선호함 -->
 <input type="checkbox" checked="checked">

위에서 checked attribute 만 선언 하는것은

아래의 코드는 기본적으로 HTML5 에서 동일하게 취급되기 때문이다.

 <input type="checkbox" checked>
 <input type="checkbox" checked="">
 <input type="checkbox" checked="checked">

이 이유는 checked attribute 는 boolean attribute 이기 때문이기도 한데 추가하자면 XHTML에서는 checked=”checked” 가 유효하지만 HTML5에서는 같은 결과를 내기 때문에 checked 하나만 쓰게 된다.
프로젝트를 할때 checked=”checked” 로 퍼블리싱 되어 오는 경우도 있지만. 같은 팀에서 협업할때 checked 형태를 더 선호하고 convention도 이렇게 되어있어서 나는 개인적으로 checked 하나만 사용하는것을 좋아한다.

그렇다면 input 이 checked 되었을 경우에 css 적으로 효과를 준다면 어떤 선택자를 쓰게될까?
해당 선택자는 다음과 같다.

input:checekd{

}

여기 까지 보자면 뭐가 문제가 있나? 생각 되지만.  문제는 IE8 같은 오래된 브라우저에서 발생한다.

바로 :checked 선택자가 동작하지 않는다. 그렇다면 이 경우 fallback 을 하기 위해서  [checked] 선택자를 사용하는 방법이 있다.

input[checked]{
// 
}

이렇게 되면 IE8 이하의 브라우저에서도 해당 이슈를 해결 할 수 있다.

다만 이런 방법이 또다른 오류를 발생하게 하는데 주로 jQuery로 이 checked 속성을 이용해서 작업할때 발생하게 된다.

예를들어 아래의 코드가 문제가 된다는 것이다.

//[checked] 선택자 안먹음. 
//:checked는동작
var isChecked; 
// isChecked 는 true 또는 false
// 주로 요소들끼리 이벤트가 연결되어있는 경우 사용  
if ( isChecked ){
  $( "input" ).prop( "checked", true ); // checked 적용 
} else {
  $( "input" ).prop( "checked", false ); // checked 해제 
};

 

보통 jQuery로 DOM 조작을 하는경우 2가지 method 를 많이 쓰게 되는데 이 2개의 메소드는$().prop()$().attr() 이다. ( + $().removeAttr() 도 )

prop과 attr 가 혼용되기도 하고 실제로 많은 개발자들이 헷갈려 하기도 한다.

부연 설명을 하자면.  jQuery 1.6 이하의 버전에서는 attr 로 이 prop의 역할도 일부 수행하고 있었기 때문에 주로 개발자들이 헷갈려했고 이 이슈는 1.6 이후의 버전부터 해당 역할이 분리되었으며 jQuery 공식 사이트에서도 해당 이슈에 대해 설명하고 있다. http://api.jquery.com/prop/

그렇기 때문에 대부분 jQuery를 자주 쓰는 개발자 또는 prop과 attr 의 차이를 잘 아는 사람일수록 attr 보다 input 의 checked property를 제어할때는 prop을 사용한다.  다시 말하면 checked 와 같은  property를 조작 하려면 prop 메소드를 쓰는게 맞다. ( js 로 dom의 checked 효과를 제어 하려면. )

 

다만 위의 [checked]와 같이 IE8 대응 코드가 들어가게 된다면 prop 메소드는 제대로 된 checked 효과를 주지 못한다.

그렇기 때문에 이 경우에는 attr() 메소드를 사용해야 하고 attr( “checked”, “checked” ) 메소드를 사용했기 때문에 해당 효과를 제거 하고 싶다면 removeAttr( “checked” )를 사용해야 한다.

즉 위 코드는 아래와 같이 수정되어야 한다.

//[checked] 선택자 안먹음. 
//:checked는동작
var isChecked; 
// isChecked 는 true 또는 false
// 주로 요소들끼리 이벤트가 연결되어있는 경우 사용  
if ( isChecked ){
  $( "input" ).attr( "checked", "checked" ); // checked 적용 
} else {
  $( "input" ).removeAttr( "checked" ); // checked 해제 
};

정리하자면 2가지가 핵심이다.

1. input 의 propery를 컨트롤 하려면 prop() 메소드가 맞다. (jQuery 기준)
2. 단 해당 input 요소가 checked 되었을때 특정 효과를 주는 스타일링이 있다면 (css) 
그리고 해당 서비스가 IE8 이라면!  호환성을 위해 [checked]선택자와 removeAttr() , attr() 을 사용하자 

물론  IE8 때문에 매번 prop대신 attr을 사용하기 싫다면 prop으로 기본 처리를 하고 IE 8이하인 경우에만 removeAttr(), attr() 로 fallback 하게 짜도 된다.

( 선택자는 [checked] ,:checked 둘다 사용해서 css 를 사용해야 한다. IE8 이하만 따로 CSS 를 만들어 관리하는 방법도 있다. )

 

1 댓글

sida 에 응답 남기기 응답 취소

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.

다음의 HTML 태그와 속성을 사용할 수 있습니다: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>