Rev. 2.73

IE에서는 페이지의 위치가 변할때 마다 클릭음이 발생한다. 이것은 사용자에게 무언가 일어나고 있다는 것을 알리기 때문에 중요한 요인으로 작용하는 특성을 가진다. 하지만 규모가 큰 웹 애플리케이션에서는 이 클릭음이 진짜로 성가시게 될 수도 있다. 예를 들면 아이프레임을 이용한 자동 순환 광고가 그러하다. 아무런 액션을 취하지 않아도 클릭 노이즈가 지속적으로 발생한다면 방문객은 얼마 버티지 못하고 떠나 버릴지도 모른다. 실제로 매우 불쾌하기도하고 거슬리기도 한다. 그래서 Julien Lecomte씨는 아이프레임에서 src위치를 변경할 때 소리를 지울 방법을 모색해냈다.

function setIFrameSrc(iframe, src) {
    var el;
    iframe = YAHOO.util.Dom.get(iframe);
    if (YAHOO.env.ua.ie) {
        // Create a new hidden iframe.
        el = iframe.cloneNode(true);
        el.style.position = "absolute";
        el.style.visibility = "hidden";
        // keep the original iframe id unique!
        el.id = "";
        // Listen for the onload event.
        YAHOO.util.Event.addListener(el, "load", function () {
            // First, remove the event listener or the old iframe
            // we intend to discard will not be freed...
            YAHOO.util.Event.removeListener(this, "load", arguments.callee);
            // Show the iframe.
            this.style.position = "";
            this.style.visibility = "";
            // Replace the old iframe with the new one.
            iframe.parentNode.replaceChild(this, iframe);
            // Reset the iframe id.
            this.id = iframe.id;
        });
        // Set its src first...
        el.src = src;
        // ...and then append it to the body of the document.
        document.body.appendChild(el);
    } else {
        iframe.src = src;
    }
}

YUI로 작성된 이 코드의 작동원리는 간단하다. 새로운 숨겨진 아이프레임을 생성하고 src를 할당한다. 로드가 완료되면 기존 아이프레임을 새로 생성한 아이프레임으로 대체하여 노이즈를 제거하는 트릭이다. 예제를 통해 실험해 보자.

Comments

logo.png

Scripteka.comPrototype을 확장하는 플러그들의 저장소(repository)이다. Prototype의 커뮤니티를 형성하고 플러그인들의 집합장소로 사용되기 위한 목적을 띠고있다. 실제로 플러그인 개발자에게 Trac 소스 리파지토리를 제공하여 버전 관리를 할 수 있게 한 점도 주목 할 만하다. 산뜻한 디자인과 멋진 UI, 그리고 Ajax로 무장한 Scripteka는 플러그인들을 쉽고 빠르게 조회할 수 있으며, 별점추천을 할 수 있고, 인기별, 시간별 정렬을 지원하여 Prototype기반 플러그인들을 쉽고 빠르게 찾고 다운로드 할 수 있다.

Comments

실제로 우리가 Prototype에 대하여 얼마나 잘 알고 있는지 확인하는 시간을 가져봅시다. Juiry Zaytsev씨는 어떤 넌센스한 사람들은 document.getElementById와 Ajax.Request 메서드를 함께 사용하는 것도 목격했다고 하면서 안타까움을 토로하고 Prototype 1.6의 옳은 사용법과 바르지 못한 사용법을 비교하는 포스트(How well do you know prototype)를 작성했습니다.

How well do you know prototype

//바르지 못한 방법:
document.getElementById("foo ")
//적당한 방법: 놀랍게도 어떤 사람들은 이것에 대해 잘 모른다.
$("foo ")

//바르지 못한 방법:
var woot = document.getElementById("bar").value
var woot = $("bar").value
//적당한 방법: 폼 값의 편리하고 빠른 호출
var woot = $F("bar")

//바르지 못한 방법:
$('footer').style.height = '100px';
$('footer').style.background = '#ffc';	
//적당한 방법: 모든 브라우저가 W3C의 권고를 따르고 있지 않다.
$('footer').setStyle({
	height: '100px',
	background: '#ffc'
})

//바르지 못한 방법:
$('coolestWidgetEver').innerHTML = 'some nifty content'
//적당한 방법:
$('coolestWidgetEver').update('some nifty content')
// 아래와 같은 문법 구사가 가능해 지므로
$('coolestWidgetEver').update('some nifty content').addClassName('highlight').next().hide()

//바르지 못한 방법:
new Ajax.Request('ninja.php?weapon1=foo&weapon2=bar')
//적당한 방법: 보기 좋으며 보다 나은 파라메터 구조 사용 
new Ajax.Request('ninja.php', {
	parameters: {
		weapon1: 'foo',
		weapon2: 'bar'
	}
})

//바르지 못한 방법:
new Ajax.Request('blah.php', {
	method: 'POST',
	asynchronous: true,
	contentType: 'application/x-www-form-urlencoded',
	encoding: 'UTF-8',
})
//적당한 방법: 기본옵션은 생략하라!
new Ajax.Request('blah.php')

//바르지 못한 방법:
Event.observe('myContainer', 'click', doSomeMagic)
//적당한 방법: 논쟁의 여지가 있지만 객체지향적이다!
$('myContainer').observe('click', doSomeMagic)

//바르지 못한 방법:
$$('div.hidden').each(function(el){
	el.show();
})
//적당한 방법: 슬프게도 이 사용법을 아는 사람들이 많지 않다는 사실.
$$('div.hidden').invoke('show')

//바르지 못한 방법:
$$('div.collapsed').each(function(el){
	el.observe('click', expand);
})
//적당한 방법: invoke를 이용한 이벤트 핸들링, 졸라 쉽다!
$$('div.collapsed').invoke('observe', 'click', expand)

//바르지 못한 방법:
$$('input.date').invoke('observe', 'focus', onFocus);
$$('input.date').invoke('observe', 'blur', onBlur);
//적당한 방법: $$는 오버해드가 크기 때문에 invoke를 사용하면 $$를 여러번 사용할 필요도 없다.
$$('input.date').invoke('observe', 'focus', onFocus).invoke('observe', 'blur', onBlur)

//바르지 못한 방법:
$('productTable').innerHTML = 
	$('productTable').innerHTML + 
	'<tr><td>' + productId + ' '
	+ productName + '</td></tr><tr><td>' 
	+ productId + ' ' + productPrice + 
	'</td></tr>'
//적당한 방법: Template 클래스는 정말 쓸만한 DOM 솔루션이다. 하지만 잘 사용되고 있지 않는 것 같다.
var rowTemplate = new Template('<tr><td>#{id} #{name}</td></tr><tr><td>#{id} #{price}</td></tr>');
$('productTable').insert(
	rowTemplate.evaluate({
		id: productId,
		name: productName,
		price: productPrice
	}))
)

사실 저 또한 지금까지 몸에 배인 코드를 습관처럼 즐겨쓰기 때문에 새로운 방법에 익숙해지길 꺼려할 때가 있습니다. 하지만 invoke메서드나 Template메서드는 활용 가치가 매우 높다는 사실을 일깨워 주네요. 부록으로 How well do you know prototype Part 2도 참고하세요.

Comments