아래와 같은 태그에서 버튼을 누르면 '등록'이란 문자열을 '변경'이란 문자열로 바꾸는 작업을 하던 중이었다.

<span id="p"><em class="ClassName"></em> 등록</span>

잘보면 CSS 스타일을 먹인 <em></em> 태그 다음에 공백문자가 하나 있고 그 다음에 '등록'이란 문자열이 있다.

jquery를 이용하여 $('#p').text().repalce('등록', '변경'); 으로 바꾸면 나머지 브라우저에선 잘되는데, 

IE8 이하에선 앞부분의 공백문자가 사라져서 디자인이 틀어지는 현상이 일어났다.


혹시 jquery의 버그인가 싶어서 text() 함수에서 문자열을 추출하는 부분을 살펴봤다.

소스는 아래와 같다. (jquery-1.11.1 기준)

getText = Sizzle.getText = function( elem ) {
	var node,
		ret = "",
		i = 0,
		nodeType = elem.nodeType;

	if ( !nodeType ) {
		// If no nodeType, this is expected to be an array
		while ( (node = elem[i++]) ) {
			// Do not traverse comment nodes
			ret += getText( node );
		}
	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
		// Use textContent for elements
		// innerText usage removed for consistency of new lines (jQuery #11153)
		if ( typeof elem.textContent === "string" ) {
			return elem.textContent;
		} else {
			// Traverse its children
			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
				ret += getText( elem );
			}
		}
	} else if ( nodeType === 3 || nodeType === 4 ) {
		return elem.nodeValue;
	}
	// Do not include comment or processing instruction nodes

	return ret;
};


Chrome이나 IE9 이상에서는 elem.textContent 를 가져와서 반환하는데,

IE8 이하에서는 textContent가 없어서 가장 마지막 else if 부분으로 들어가 nodeValue를 반환한다.

하지만 IE8 이하에서의 nodeValue는 ltrim()을 당해 앞부분의 공백문자가 다 사라진다.

(실제 브라우저의 소스코드를 본 건 아니다;;)


여하튼 이게 원인이었던 것이다.

참고로 다른 브라우저에서는 nodeValue를 가져와도 앞부분의 공백문자는 그대로다.


해결책은 아래 2개 정도.

1. 공백문자 대신 &nbsp;를 이용하면 nodeValue를 가져와도 공백이 보존된다.

2. 이것도 저것도 못 믿겠다면 치환할 때 그냥 공백까지 포함해서 해버리는 방법도 있다.







Posted by bloodguy
,