일반적이고 대부분의 브라우저 스니핑 기법은 각 브라우저에서 지원하는 DOM의 차이점을 이용하여 활용하고 있습니다.  

그리고 최근 Ajaxian.com 을 통해 소개된 기사에서는 JavaScript 만을 이용한 스니핑 방법을 소개하고 있습니다.


꾀 오래전에 Opera의 Array의 Slice 메소드가 IE, FF, Safari와 다르게 동작하여 피드백을 해놨는데 답변이 없더니 패치는 된것 같습니다.

이렇듯 현대 주(major) 브라우저의 자바스크립트는 ECMA Script 262-2 Spec을 따르고 있는데요.  이 JavaScript 역시 브라우저마다 작은 차이점들을 가지고 있습니다.  

//Firefox detector 2/3 by DoctorDan
FF=/a/[-1]=='a'

//Firefox 3 by me:-
FF3=(function x(){})[-5]=='x'

//Firefox 2 by me:-
FF2=(function x(){})[-6]=='x'

//IE detector I posted previously
IE='\v'=='v'

//Safari detector by me
Saf=/a/.__proto__=='//'

//Chrome by me
Chr=/source/.test((/a/.toString+''))

//Opera by me
Op=/^function \(/.test([].sort)

소개된 코드들은 상당한 테스트와 분석에서 나온 결과물이 아닐까 생각이 듭니다.

더보기




신고
Posted by Rhio.kim
1. 엘리먼트element

<tagName id="element" ... properties = "value">   </tagName>

어떤 면에서 보면 단지 HTML 태그에 불과합니다.

하지만 좀더 XML 관점에서 바라본다면 위의 단위를 "엘리먼트element"라 부릅니다.
하나의 엘리먼트는 DOM spec의 IDL(Interface Definition Language) 에 정의된 attributes를 취하게 됩니다.


2. 인터페이스interface

  우리는 DOM의 내부(core) 구현은 알 필요가 없이 다양한 언어(java, javascript, ect)로 오브젝트와 인터페이스를 통해 document object 에 접근을 하게 됩니다.  여기서 인터페이스라는 간단히 말해

    개발자 언어(java, javascript)와 Document Objec와의 의사소통을 담당하는 중간 매개체
    <#참고 : 위키백과 - 인터페이스>   <#참고 : Web Kit DOM>

입니다.

이 인터페이스는 FireFox에서 아래와 같은 수행을 했을 때 쉽게 볼 수 있습니다. 또한 Web Kit DOM 사이트에서도 찾아 볼 수 있습니다.

var el = document.createElement('img');
//[object HTMLImageElement]
var el = document.createElement('input');
//[object HTMLInputElement]
var el = document.createElement('div');
//[object HTMLDivElement]
...
...
위 예제처럼 알 수 있듯이 [type interface]를 취하는 것을 알 수 있습니다.  단편적인 createElement 메서드의 수행 결과이나 모든 javascript 에서 object 화 하여 취하게 되는 모든 document object 에는 고유의 interface를 제공받게 됩니다.


3.자바스크립트javascript  엘리먼트element 인터페이스interface의 관계

여기서 javascript를 이용하였을 때의 interface에 대한 관계를 설명하고자 합니다.

var el = document.getElementById('element');

  우리는 HTML Document에서 엘리먼트의 고유한 id 프로퍼티가 'element' 인 엘리먼트 오브젝트를 넘겨줍니다.  간단하게 본 el에는 object type의 엘리먼트를 취한다고 봅니다.  또한 el을 통해서 위에 명시했던 엘리먼트의 속성을 접근하거나 이벤트 핸들링을 하거나 style을 변경하거나 할 수 있다 라고 봅니다.

  이러한 하나의 엘리먼트에 어떤 프로퍼티의 속성에 값을 지정하거나 삭제를 하거나 하는 다양한 처리를 통하여 엘리먼트에 원하는 결과로 설정합니다.

  여기서 el을 얻기 위해서 사용하는 document는 자바스크립트 엔진 런타임 시에 도입되는 window의 하위 오브젝트로 window.document 입니다.   이는 또한 DOM(Document Object Model)에 접근하기 위한 가장 상위 인터페이스(DOM 관점에서 볼때) 혹은 오브젝트(자바스크립트 관점에서 볼때)입니다.


좀더 자세한 예제를 통해서 DOM HTML Spec에서의 interface에 접근해 보도록 하겠습니다.

우리는 HTML document에 표현되지 않고 랜더링 되지 않는 엘리먼트 오브젝트를 생성할 수 있습니다.

var el = document.createElement('img');
var el = document.createElement('div');
var el = document.createElement('input');

이렇게 createElement 메서드를 통해서 image 엘리먼트를 생성하였습니다.

이때도 알 수 있지만 el에는 image object가 담겨져 있고 이것은 image가 갖는 attribute를 제공받습니다.
createElement 수행 시 생성된 엘리먼트에는  아래의 interface를 제공 받습니다.

interface Element,
interface HTMLElement:Element,
interface HTMLImageElement:HTMLElement
interface HTMLDivElement:HTMLElement     
interface HTMLInputElement:HTMLElement     

간단한 예제 코드로 interface HTMLImageElement가 취하게 되는 attributes를 보겠습니다.
var el = document.createElement('img');
var DOM_ATTRIBUTE = [];
for(property in el) DOM_ATTRIBUTE.push(property);

more..


위에서 보셨던 많은 attributes는 interface HTMLImageElement 에 의해서만 제공받은 attributes는 아닙니다. 상속 계층에 있는 모든 interface에서 제공되는 attributes를 제공받습니다.
<#참조 : Web Kit - interface HTMLImageElement> <#참조 : Web Kit - HTMLImageElement IDL>

아래의 다이어그램과 같이 javascript에서는 window.document에 의해서 얻어진 Document Object는 DOM interface의 계층에 따라 상위 인터페이스를 제공받습니다.  달리 말하면 상위 interface에 의해서 HTMLImageElement 을 제공받게 됩니다.
사용자 삽입 이미지


4. 요약
javascript 는 window.document 즉 interface document 에 의해서 document object 에 접근합니다.
window.document는 javascript runtime 시 도입되는 interface 역활을 합니다.

javascript에서 접근하는 모든 document object는 자신만의 interface를 제공받으며 또한 상속 계층에 있는 상위 interface 또한 제공받게 됩니다. 이를 통해 개발자 언어를 통하여 document object를 제어, 획득 할 수 있게 됩니다.

신고
Posted by Rhio.kim
사용자 삽입 이미지





  다양한 프레임웍(DOMAssistant 2.6, jQuery 1.2.3, Prototype 1.6.0.2, Mootools 1.2b2, ExtJS Core 2.0.1, YUI 2.4.1)들에 대한 셀렉터(Selector) 속도 및 유효성 테스트입니다.

  정확한 테스트와 상호 테스트간의 충돌을 방지하기 위해서 각각의 프레임웍 테스트를 각각의 아이프레임내에서 수행되도록 처리했네요. 최대한 정확한 테스트가 되기위해서 여러모로 신경을 썼다는 군요.

사용자 삽입 이미지

제 PC 에서 수행한 결과입니다.
DOMAssistant 2.6         1087ms
jQuery 1.2.3                  1454ms
Prototype 1.6.0.2      2324ms
Mootools 1.2b2             1578ms
ExtJS Core 2.0.1      617ms
YUI 2.4.1                      1789ms

테스트 결과가 생각과 많이 다르네요..
Prototype.js가 속도면이나 유효성면에서 제일 떨어지네요.  실망스럽네요. 하지만 다른 부분은 탄탄하게 구성되어있으니 element 찾을때 Selector를 이용해 접근하는 $$ 함수의 사용을 자재해야겠군요.

  반면 ExtJS는 그리드 기반의 Framework인데 Selector 부분을 신경을 많이 썼나보군요.
하기야 대부분 css 컨트롤을 통해서 그리드 구성을 할터이니 이부분도 상당히 신경을 썼겠죠..
내부 로직은 잘 모르겠지만 ExtJS가 Selector에서는 다른 Framewokr에 비해서 탁월한 성능을 보이는게 사실이네요.

테스트 사이트 : http://www.domassistant.com/slickspeed/
신고
Posted by Rhio.kim
getElementsByClassNamenative 가 되었다.
여담 : 저는 이런 Webkit, Mozilla 의 새로운 이슈되는 기사를 볼때마다 MS와 비교가 됩니다.
         발빠른 HTML 5 스펙, ECMA Script 4의 적용, Gears 등등 새로운 웹 기반의 패러다임을 만들기 위해서
         불철주야 새로운 이슈를 내놓는데 도대체가 MS는 IE 차기 버젼의 이름은 IE8 이다 라는
         이슈를 봤는데 그게 뭐 어쨋따는 건지... 이그.. 윈도우만 아니였으면 벌써 IE는 쇠퇴해 갔을텐데...

사용자 삽입 이미지

위 그래프는 getElementsByClassName 를 10,000번 수행한 결과 입니다.
상당히 아니 너무나 대조적입니다.  이게 왠말인가.. native 의 수행속도가 이렇게 확연히 차이가 나는 이유는
무엇일까요?

그 속내가 더욱 궁금합니다. 저런 수행 능력이라면 대부분의 것들을 native로 등록해서 쓸 수 있도록 하면 더욱 좋을텐데 말이죠.

이 메서드는 HTML 5 스펙이 추가되었습니다.
또한 파이어폭스와 오페라의 최신의 새버젼에서 지원합니다.


Javascript native method 의 명확한 이점!!


1. 추가적인 javascript 라이브러리 파일을 필요로 하지 않는 다는 것!!
2. 명확한 명세와 일관된 속성을 제공한다는 것
3. 눈부신 속도


밴치마킹 테스트 페이지 : http://webkit.org/blog-files/gebcnspeedtest.html(사파리)
출처 : http://webkit.org/blog/153/webkit-gets-native-getelementsbyclassname/
신고
Posted by Rhio.kim
사용자 삽입 이미지
몇일전 1.6.0 정식버젼으로 릴리즈 된 Prototype.js 의 변화 중 Event 오브젝트의 사용자 이벤트부분이 있습니다.
OOP 개발을 하다보면 이벤트 밖의 처리와 이벤트 안의 처리 좀 더 자세히 말하자면

리스너와 핸들러 핸들러 Scope 안과 밖에서 일어나는 모든 일들을 처리하자면 어려운 점들이 간혹 생깁니다.
예를 들어 Scope 안의 this와 밖의 this 분명 차이가 있죠...

아 이건 사용자 이벤트와는 무관하니 넘아갑니다.


이벤트 리스너 등록(Observing events)

<img src="./test_off.gif" onmouseOver="this.src='./test_on.gif'" onmouseOut="this.src='./test_of.gif'" />

<input type="button" onclick="javascript:buttonClick(event);" id="button" value="Ok"/>
<script type="text/javascript">
    function buttonClick(event){
        alert(event);
    }
</script>

우리는 iniline 스크립트로 대부분 이런식의 이벤트를 줍니다. 하지만 web2.0방식의 oop 개발에 있어서는
그 다지 추천할만한 방법은 아니라고 보여집니다.

Prototype.js 에서 지원하는 이벤트 Observing

<div id="test"></div>
<script type="text/javascript">
    Element.observe('test', 'mouseover', bgChange);  <-- target Element id 를 통한 mouseover 리스너 설정

    $('test').observe('mouseover', bgChange);  <-- target Element 에 mouseover 리스너 설정

    function bgChange(event){
        var targetElement = Event.element(event);  <-- 1.6.0 에서는 var targetElement = event.target;
    }
</script>

이 벤트 리스너와 핸들러에 대한 구분과 실제 DOM 레벨 addEventListener, dipatchEventListener 등을 알아야합니다. 프레임웍의 편리한 점도 있지만 원천적으로 알아야할 부분을 모르고 사용한다면 코더에 불과해집니다.



사용자 이벤트(custom events)

대부분에 잘 알려진 Javascript 프레임웍에서는 이미 사용자 이벤트가 있습니다. 그리고 Prototype에 적용되기 전에 매우 긴 방법을 사용했습니다. Prototype.js 의 사용자 이벤트는 다른 프레임웍과 틀립니다.
사용자 이벤트를 사용하기 위해서 namespace에 event name을 등록해야 된다는 것인데요.

  'namespace:eventname' 이 처럼 하면 됩니다.

사용자 이벤트 부분을 담당해서 개발했던 Sam은 사용자 이벤트를 이렇게 사용해야 된다는 것에 이처럼 말했습니다.
  
  " 작지만 중요한 변화는 사용자 이벤트를 만들어졌다.[7835] : 모든 사용자 이벤트 명은 namespace에 등록되어야 합니다.  이것은 Prototype.js 만의 솔루션이고 "mousewheel" 과 "DOMMouseScroll" 처럼 비표준 네이티브 DOM 이벤트이기 때문에 사용자 이벤트 네임의 충돌문제를 해결하기 위함입니다. "

$('pandora').observe('PTV:play', function(event) {
   alert(event.memo);
  });
이 예제는 'PTV' namespace에 있는 'play' 이벤트를 실행하는 방법입니다.


Prototype Custom Event 중 한가지

Prototype 1.6.0 정식 버젼에서는  'dom:loaded' 이벤트를 가지고 있습니다.
window 오브젝트에 의해서 이 이벤트는 실행되는데요. 이 이벤트는 DOM tree 즉 document가 모두 load 되고 나면 실행되게 됩니다. document가 모두 load되었다는 것은 쉽게는 html 문서가 다운로드 됨을 의미합니다.

그안에 내포된 image 리소스까지 모두 다운로드 됨을 의미하는것은 아닙니다.

우리가 브라우저를 통해 원격지의 어떤 URL을 요청하게 되면 그 URL의 HTML 문서 즉 document 객체가 모두 다운로드 다운로드되고 DOM에 의해서 랜더링 과정을 거치면서 거기에 해당되는 js, css, img 들을 요청합니다.
이래서 HTTP Request 가 계속 발생하게 됩니다.

이런 과정이 많을 수록 웹 페이지의 포퍼먼스는 떨어지게 됩니다.
본론으로 들어가서요. document 가 onload가 되면 'dom' namespace의 loaded 사용자 이벤트가 발생하게 되어있습니다.



제가 생각할때 이 사용자 이벤트는 상당히 고급 Web App를 개발하는데 큰 도움이 됩니다.
IE에서는 fireEvent 가 내부적으로 지원을 하고 있습니다. 하지만 FF, Opera, Safari에서는 자체적 지원은 되지 않고 DOM 메서드를 통해서 어렵게(?) 구현을 해야합니다.

간지러운 부분을 Prototype에서 이번에 잘 긁어 주었네요.
신고
Posted by Rhio.kim
원본출처 : http://webkit.org/blog/126/webkit-does-html5-client-side-database-storage
사용자 삽입 이미지

Safari 계열에서도 클라이언트 사이드 데이터 베이스 스토리지를 지원하는군요. HTML5 표준이 나오면.. 기대 됩니다.

클라이언트 사이트 스토리지 개념을 대부분의 브라우저가 도입하고 있는데 IE에서만 소식을 못 접하고 있네요.

사파리에서도 원본출처로 가시면 관련 기사를 볼 수 있습니다.

몇일 전에 파이어 폭스에 대해서도 기재한 적이 있는데요. 파이어 폭스에서는 현재도 sqlite 라이브러리를 이용해서

globalStorage(지속성을 갖는 스토리지) 와 sessionStorage(일회성을 갖는 스토리지) 로 분류하여 지원하고 있습니다.

현재 클래스화하여 사용할 수 있도록 만들 구 있습니다.  조만간 공개 토록하겠습니다.

뭐 거창한것은 아닙니다. 아래 소스와 같이 쿼리문을 날리고 그런 정도의 지원이 아닙니다.

FF의 글로벌 오브젝트로 지원되는 것이구요. 그래도 Ajax개발에 있어서는  절실히 필요한 부분임은

확실합니다. 하루 속히 IE에서도 지원되고 Opera에서도 지원을 했으면 좋겠네요.


var database = openDatabase("Database Name", "Database Version");

database.executeSql("SELECT * FROM test", function(result1) {
  // do something with the results
  database.executeSql("DROP TABLE test", function(result2) {
    // do some more stuff
    alert("My second database query finished executing!");
  });
});


신고
Posted by Rhio.kim