prototype Element 학습 노트(편 1)

5195 단어 prototypeElement
먼저 Element 가 DOM 확장 에 대한 기술 방향 을 말씀 드 리 겠 습 니 다.저도 하루 동안 코드 를 보고 나 서 야 깨 달 았 습 니 다.prototype 을 사용 하면 우리 가 가장 자주 사용 하 는 것 은$(div 1)와 같은 코드 입 니 다.확 장 된 element 대상 을 얻 은 후에 우 리 는 그것 의 다양한 확장 방법 을 사용 할 수 있 습 니 다.예 를 들 어$(div 1).addClassName(loading).show();그래서 우 리 는 Element 의 확장 을 연구 하 는 것 이 바로 이것 을 입구 로 해 야 한다.function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (Object.isString(element)) element = document.getElementById(element); return Element.extend(element); } 이 함수 가 교묘 하 게 재 귀적 하면 여러 개의 매개 변 수 를 처리 할 수 있 는 상황 은 정말 나 를 찬탄 하 게 한다.코드 의 관건 은 Element.extend(element)입 니 다.extend 전에 element 는 일반적인 DOM 대상 일 뿐 입 니 다.extend 이후 에 확장 되 었 습 니 다.이 를 통 해 비밀 은 extend 에 있 음 을 알 수 있 습 니 다.Element.extend(element)인 이상,우 리 는 당연히 extend 를 단독으로 연구 할 수 없 으 며,Element 가 무엇 인지 먼저 알 아야 한다.function() {    var element = this.Element;    this.Element = function(tagName, attributes) {      attributes = attributes || { };      tagName = tagName.toLowerCase();      var cache = Element.cache;      if (Prototype.Browser.IE && attributes.name) {        tagName = ' <' + tagName + ' name="' + attributes.name + '">';        delete attributes.name;        return Element.writeAttribute(document.createElement(tagName), attributes);      }      if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));      return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);    };    Object.extend(this.Element, element || { }); }).call(window); 이 코드 는 비교적 개성 이 있 습 니 다.기본 구 조 는:(function(){...}).call(window)입 니 다.그래서 이 구 조 를 보면 생략 번호 부분 에 나타 난 this 는 모두 window 를 가리 키 는 것 임 을 알 아야 한다.var element=this.Element;이 줄 은 이해 하기 어렵 지 않 지만,관건 은 this.Element 이 아직 정의 되 지 않 았 다 는 것 이다.다음은 하나의 클래스 를 정의 합 니 다:window.Element 류 는 두 개의 인자 가 있 습 니 다:tagName,attributes.하나의 요 소 를 만 들 고 순수한 지정 탭 에 해당 하 는 DOM 대상 을 캐 시 에 넣 는 역할 을 합 니 다.요 소 를 만 든 후 지정 한 속성 값 을 기록 합 니 다.여기 서 알려 드 리 겠 습 니 다.writeAttribute,readAttribute 라 는 두 함수 기능 은 분명 합 니 다.읽 기,쓰기 속성 이지 만 코드 는 간단 하지 않 습 니 다.그 복잡성 은 주로 서로 다른 브 라 우 저 에서 읽 기,쓰기 속성 방법 이 다 릅 니 다.이것 은 Element 류 의 구조 함수 의 정의 입 니 다.그 다음 Element.cache={};캐 시,어떤 캐 시,설명 하기 쉽 지 않 습 니 다.각종 태그 의 순결 판 DOM 요소 대상 의 캐 시?이 말 은 너무 징그럽다.뒤에 바짝 붙 어 있 는 것 은 Element.Methods={...}입 니 다.여기 서 거의 모든 확장 방법 을 정 의 했 습 니 다.이곳 의 확장 방법 은 모두 하나의 특징 이 있 습 니 다.코드 에는 this 를 사용 하 는 것 이 하나 도 없습니다.모두 엘 리 먼 트 참조 로 솔직하게 전 달 됩 니 다.이것 은 복선 인 데 왜 이렇게 정의 해 야 하 는 지 이유 가 있다.잠시 후에 말씀 드 리 겠 습 니 다.지금 Element 가 대충 말 했 으 니 Element.extend 를 말씀 드 려 야 겠 어 요.Element.extend = (function() {    if (Prototype.BrowserFeatures.SpecificElementExtensions)      return Prototype.K;   var Methods = { }, ByTag = Element.Methods.ByTag;   var extend = Object.extend(function(element) {      if (!element || element._extendedByPrototype ||      element.nodeType != 1 || element == window) return element;     var methods = Object.clone(Methods),      tagName = element.tagName, property, value;     // extend methods for specific tags      if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);     for (property in methods) {        value = methods[property];        if (Object.isFunction(value) && !(property in element))          element[property] = value.methodize();      }     element._extendedByPrototype = Prototype.emptyFunction;      return element;   }, {       refresh: function() {        // extend methods for all tags (Safari doesn't need this)        if (!Prototype.BrowserFeatures.ElementExtensions) {          Object.extend(Methods, Element.Methods);          Object.extend(Methods, Element.Methods.Simulated);        }      }    });   extend.refresh();    return extend; })(); 첫 번 째 줄 의 원 리 는 확실 하지 않 습 니 다.말 하지 않 겠 습 니 다.아래 의 코드 는 복잡 해 보 입 니 다.제 가 그것 의 대략적인 구 조 를 뽑 으 면 var extend=Object.extend(function(element){...},{refresh:function(){...}};extend 에서 첫 번 째 함수 역할 은 XXXX.Methods 에서 방법 을 얻 고 이 element 에 복사 하 는 것 입 니 다.여기 서 주로 이러한 고려 를 바탕 으로 한다.첫째,요소 가 하나의 Form 이 라면 Form.Methods 에서 방법 을 찾 아야 한다.둘째,요소 가 폼 에 입력 할 수 있 는 요소 라면 Form.Element 에서 방법 을 찾 아야 한다.셋째,모든 요 소 는 Element.Methods 에서 통용 되 는 방법(뒤의 refresh 가 고려 한 것)을 얻어 야 한다.즉,여 기 는 여러 가지 상황 을 고려 해 야 한다.원래는 if 문장의 일이 어야 하 는데,여 기 는 Element.Methods.ByTag 를 교묘 하 게 설계 했다.그래서 이 문 제 를 해결 했다.if (Object.isFunction(value) && !(property in element)) element[property] = value.methodize(); Methods 의 구성원 이 함수 나 함수 가 element 에 존재 하지 않 으 면 덮어 쓰 지 않 습 니 다.여기 서 관건 이 되 었 습 니 다.그 value.methodize().이때 앞의 복선 이 효력 이 발생 했 습 니 다.methodize 의 역할 은 현재 호출 자 를 전달 하 는 방법 입 니 다.첫 번 째 매개 변수 로 들 어 옵 니 다.그것 의 사용 방법 은 일반적으로:obj.methodname=functionname.methodize();이렇게 호출 할 때 obj 대상 은 첫 번 째 매개 변수 로 functionsname 함수 에 전 달 됩 니 다.지금까지 이 extend 함수 의 대략적인 사 고 는 분명 해 야 합 니 다.아직 명확 하지 않 은 문제 가 있 습 니 다.요소 의 tagName 에 따라 어떤 Methods 에서 확장 해 야 하 는 지 알 아야 합 니 다.그러면 우 리 는 ByTag 의 상세 한 정 보 를 알 아 보고 찾 아 볼 필요 가 있 습 니 다.Object.extend(Element.Methods.ByTag,{"FORM":Object.clone(Form.Methods). "INPUT": Object.clone(Form.Element.Methods), "SELECT": Object.clone(Form.Element.Methods), "TEXTAREA": Object.clone(Form.Element.Methods) }); ok,하마터면 이렇게 될 뻔 했 어.

좋은 웹페이지 즐겨찾기