mouseenter, mouseleave event

mouseover, mouseout event는 마우스가 객체 위에 놓여졌을 때, 영역을 벗어낫을때 발생하는 event입니다.
허나 이 event들은 객체에서 자식요소로 마우스를 이동해도 event가 발생하는 문제가 있습니다.
아래의 예제처럼요.

event :

이런 문제를 회피하기 위해서 IE에서는 mouseenter, mouseleave 두 event가 존재합니다만, IE에서 밖에 실행이 되질 않아서 스크립트를 작성하는데 문제가 많더군요.
jQuery.js, prototype.js같은 JavaScript Framework을 쓰면 좋겠지만 제 특성상 Framework을 못쓰는 경우가 많아서 ppk(책)에 있는 내용을 참조해서 만들어봤습니다.

event :

Code

[js]
function addEvent(element, type, callback) {
var eventListener = function(element, event) {
element.addEventListener(event, function(e) {
var obj = e.relatedTarget;
while (obj != element) {
if (!obj) return callback.apply(this);
obj = obj.parentNode;
}
return false;
}, false);
};

if (element.addEventListener) {
switch(type) {
case ‘mouseleave’: eventListener(element, ‘mouseout’);
break;
case ‘mouseenter’: eventListener(element, ‘mouseover’);
break;
default : element.addEventListener(type, callback, false);
break;
}
} else if (element.attachEvent) {
element.attachEvent(‘on’ + type, function() {
callback.apply(element);
});
}
}
[/js]

사용 방법

mouseenter

[js]
//일반적인 사용법
object.onmouseenter = function() {
alert(‘mouseenter’);
};
//addEvent를 이용한 방법
addEvent(object, ‘mouseenter’, function() {
alert(‘mouseenter’);
});
[/js]

mouseleave

[js]
//일반적인 사용법
object.onmouseleave = function() {
alert(‘mouseleave’);
};
//addEvent를 이용한 방법
addEvent(object, ‘mouseleave’, function() {
alert(‘mouseleave’);
});
[/js]

실력이 많이 부족하다 보니 좋은방법인지까지는 모르겠습니다.
더 좋은 방법을 아시거나 버그를 발견하신분은 꼭 알려주세요~

IE8 Hack

[css]
/* IE6, IE7, IE8 */
selector { color: blue\9; }

/* IE7, IE8 */
selector { color/*\**/: blue\9; }
[/css]

구글검색을 하다보면 IE8 STANDARDS MODE ONLY로 되어있지만…
막상 IE Tester로 테스트 해보면 IE7에서도 동작 하더군요..-_-
IE Tester가 문제인지 올라온 글들이 문제인지는 확인해 보지 못했지만 IE Tester로 테스트하고 안된다고 하는 사람도 있기에…-_-;
IE7, IE8 두개 다 된다고 생각하는게 좋을듯합니다.

inline-block속성 이용하기

요즘 제가 float속성 대신 많이 사용하고있는 방법은 inline-block입니다.
이미지 겔러리 같은 디자인을 코딩시 float의 단점은 높이가 다를 경우 다음줄의 정렬이 뒤틀어지는 문제가 생기기 때문에 높이를 정해주거나 사이에 clear를 해야 하는 문제가 있었죠..
(저같은 경우는 말이죠.. 좋은 방법을 알고계시다면 알려주세요.)

그래서 사용하는 방법이 inline-block입니다.
inline-block로 정렬시 높이가 일정하지 않아도 정렬이 뒤틀림 없이 나오게 할수가 있습니다.
거기다 세로 정렬까지 되는 아주 멋진 속성인듯 싶습니다.

단점

구버전 브라우저의 빈약한 지원

파이어폭스 2.0 이하의 브라우저에서는 이 속성을 지원하지 않기 때문에 -moz-inline-box속성을 써야만 합니다.
하지만 이것 역시 완벽한 방법은 아닌듯합니다.
[html]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title> Code Example </title>
<style type="text/css">
li {
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
</style>
</head>

<body>
<ul>
<li>
<span>test</span>
<span>test</span>
</li>
</ul>
</body>
</html>
[/html]
위와 같은 코드가 있을시 li의 자식요소인 span까지 -moz-inline-box속성을 먹어서 줄바꿈되는 문제가 있습니다.
CSS tests and experiments를 운영하는 Bruno Fassino님은 li의 자식요소를 한번 더 감싸는 방법으로 회피하고 있더군요.

익스플로러의 경우 inline요소(span, strong..등)에서는 문제가 없지만 block요소(div, li, p…등)에서는 문제가 생깁니다.
이 방법을 회피 하기 위해서는 익스플로러에서는 inline속성으로 만들어주면 됩니다.
[css]
li {
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
/* IE7 */
*+ html li {
display:inline;
}
/* IE6 */
* html li {
display:inline;
}
[/css]

공백문자

inline-block의 경우 inline속성과 같이 줄바꿈없이 내용을 보여주게 되지만 코드의 가독성을 위해서 사용된 줄바꿈, 들여쓰기를 하나의 공백문자로 인식하게 되어서 &nbsp; 한개 만큼의 공백이 생기게 됩니다.

제가 아는 해결방법은 두가지가 있습니다.

첫번째로는 아래와 같이 부모 요소에 font-size, line-height를 0으로 설정하고 inline-block을 준 요소에 font-size와 line-height를 다시 설정해주는 방법이죠.
[css]
ul {
font-size:0;
line-height:0;
}
ul li {
font-size:12px;
line-height:1.2;
display:-moz-inline-box; /* 구 버전의 Moz */
display:inline-block; /* Op, Saf, Moz3.0이상, IE8등 */
}
[/css]

두번째 방법은 html코드의 “>”부분을 줄바꿈해 버리거나 한줄로 붙여 쓰는 방법이죠.
(위에서도 언급했던 Bruno Fassino님의 경우에도 아래와 같은 방법으로 공백문자가 생기는 방법을 회피 했더군요.)
[html]
<ul
><li>content</li
><li>content</li
><li>content</li
></ul>
[/html]
두번째 방법의 경우 개발자와의 대화가 필요합니다.
html를 잘 모르는 개발자일 경우 이런 상황을 인식하지 못하고 할줄로 붙여서 쓴 방법을 무시해 버릴수도 있기 때문이죠.

덧.
위의 글은 접근성에 대한 부분은 무시하고 작성되었습니다.
접근성에 문제가 있다고 딴지를 거신다면 할말이 없습니다.:(

IE를 위한 css모음

IE6 png filter

IE6에서 알파값이 들어간 png를 처리하지 못하기 때문에 filter를 사용해야 합니다.

[css]
/*scale*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’scale’);
}
/*crop*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’crop’);
}
/*image*/
selector {
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’pngImage.png’, sizingMethod=’image’);
}
[/css]

scale, crop, image 속성을 지원합니다.

  • scale 상위의 객체에 꽉 체워 줍니다. 만일 이미지를 싸고 있는 레이어가 있다면 그 레이어에 크기에 맞게 그림이 늘어납니다.
  • crop 이미지의 크기 비율에 맞게 디스플레이 합니다.
  • image 기본 설정값으로 본래의 이미지 크기로 보여줍니다.

Opacity

opacity의 경우 브라우마다 지원하는 방법이 다릅니다.

[css]
/*표준브라우저*/
selector {
opacity:.5;
}
/*IE 5~7*/
selector {
filter:alpha(opacity=50);
}
/*IE 8*/
selector {
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
}
[/css]

expression

IE6에서 max-width같은 지원하지 않는 스타일을 써야할때 많이 사용합니다.

[css]
selector {
max-width:320px;

}
* html selector {
width:expression(this.width > 320 ? "320px" : this.width);
}
[/css]
안에 사용되는 스크립트의 경우 코딩 상황에 따라 달라질수도 있습니다.

child selector

expression을 child selector이용한 사용하기
[css]
.selector { color:blue; }
.selector > .selector { color:red; }
* html .selector .selector { color:expression(/selector/.test(this.parentNode.className) ? ‘red’ : ‘blue’); }
[/css]
class가 아니여도 스크립트만 잘 조합해서 쓰시면 됩니다.

first-child selector

IE6은 :first-child, :last-child 둘 다 지원하지 않고, IE7은 :last-child를 지원하지 않습니다.
(왠만하면 한번만 쓰는게 좋기 때문에 :first-child로 통일하는게 좋을듯합니다.)
[css]
selector { color:blue; }
selector:first-child { color:red; }
* html selector { color:expression((this.previousSibling == null) ? ‘red’ : ‘blue’); }
[/css]
class는 지원하지 않습니다.
태그(li, div…등)에서만 사용 가능합니다.
:last-childthis.previousSiblingthis.nextSibling로 바꾸시면 됩니다.

이중 class

IE6에서 .class.class2같은 이중클래스를 사용할수있게 해줍니다.
[css]
.selector { color:red; }
.selector.selector2 { color:blue; }
.selector2 { color:green; }
* html .selector { color:expression((function(that) { if(/[selector]\s*[selector2]/.test(that.className) === true) return ‘blue’; })(this)); }
[/css]
부모의 클래스를 찾고 싶을때는 that.classNamethat.parentNode.className로 바꿔서 사용 하시면 됩니다.

:before, :after

IE에서 :before, :after를 사용할수 있게 해주는 속성입니다.
[css]
.selector:before {
content:’앞의 내용 추가’;
background-color:blue;
}
.selector:after {
content:’뒤의 내용 추가’;
background-color:red;
}
.selector {
* zoom:expression(
this.runtimeStyle[‘zoom’] = ‘1’,
this.innerHTML = ‘<span style="background-color:blue;">앞의 내용 추가</span> ‘ + this.innerHTML + ‘ <span style="background-color:red;">뒤의 내용 추가</span>’
);
}
[/css]
내용 설명은 생략합니다만, this.runtimeStyle['zoom'] = '1',를 뺀뒤 테스트 해보시는것도 또 하나의 재미라고 생각됩니다.

아래와 같이 selecter tag가 before, after에 사용될 태그와 같을 경우 에러가 납니다.
[css]
span {
* zoom:expression(
this.runtimeStyle[‘zoom’] = ‘1’,
this.innerHTML = ‘<span style="background-color:blue;">앞의 내용 추가</span> ‘ + this.innerHTML + ‘ <span style="background-color:red;">뒤의 내용 추가</span>’
);
}
[/css]
em같은 태그로 회피해서 사용.

소스를 사용함에 있어

몇몇 소스의 경우 인터넷에 돌아다니는 내용이고, 대부분 많이 사용 되는 소스기때문에 문제가 없지만, 몇몇 소스는 제가 만든소스입니다. 저도 실무에서 잘 안쓰는 소스이고, 검증되지 않았습니다.
그런고로 책임은 지지 않습니다.