Zeptoソースコードを読む:属性操作

DOM操作に関連する内部メソッド

setAttributeメソッド

function setAttribute(node, name, value) {
  if (value === null) {
    node.removeAttribute(name);
  } else {
    node.setAttribute(name, value);
  }
}

この関数は属性の設定と削除を担います。値がnullの場合にはremoveAttributeを呼び出し、それ以外はsetAttributeを使用します。

deserializeValueメソッド

function deserializeValue(value) {
  if (!value) return value;
  
  try {
    if (value === "true") return true;
    if (value === "false") return false;
    if (value === "null") return null;
    
    // 数値変換チェック
    if (!isNaN(value) && value.trim() === String(Number(value))) {
      return Number(value);
    }
    
    // JSON解析
    if (/^[\[\{]/.test(value)) {
      return JSON.parse(value);
    }
    
    return value;
  } catch (e) {
    return value;
  }
}

文字列を適切なデータ型に変換する機能を提供します。JSON形式の文字列はパースし、真偽値や数値も適切に変換します。

DOM操作メソッドの実装

.html()メソッド

html: function(htmlContent) {
  if (arguments.length === 0) {
    return this.length > 0 ? this[0].innerHTML : null;
  }
  
  return this.each(function(index) {
    const originalHtml = this.innerHTML;
    $(this).empty().append(processContent(this, htmlContent, index, originalHtml));
  });
}

要素のHTMLコンテンツを取得・設定するメソッドです。引数の有無で取得と設定を分岐します。

.text()メソッド

text: function(textContent) {
  if (arguments.length === 0) {
    return this.length > 0 
      ? this.map(el => el.textContent).join('') 
      : null;
  }
  
  return this.each(function(index) {
    const processed = processContent(this, textContent, index, this.textContent);
    this.textContent = processed === null ? '' : String(processed);
  });
}

textContentプロパティを操作するメソッドで、HTMLエスケープされたテキスト処理を行います。

.attr()メソッド

attr: function(name, value) {
  if (typeof name !== 'string' || arguments.length > 1) {
    return this.each(function(index) {
      if (this.nodeType !== 1) return;
      
      if (typeof name === 'object') {
        Object.entries(name).forEach(([key, val]) => {
          setAttribute(this, key, val);
        });
      } else {
        setAttribute(this, name, processContent(this, value, index, this.getAttribute(name)));
      }
    });
  }
  
  return this.length > 0 && this[0].nodeType === 1 
    ? this[0].getAttribute(name) 
    : undefined;
}

属性の取得・設定を行うメソッドで、オブジェクトによる一括設定もサポートしています。

.data()メソッド

data: function(name, value) {
  const attrName = 'data-' + name.replace(/[A-Z]/g, '-$&').toLowerCase();
  const result = arguments.length === 1 
    ? this.attr(attrName) 
    : this.attr(attrName, value);
  
  return result !== null ? deserializeValue(result) : undefined;
}

data属性の操作を行うメソッドで、キャメルケースをハイフン形式に変換して扱います。

位置情報操作メソッド

.offset()メソッド

offset: function(coords) {
  if (coords) {
    return this.each(function(index) {
      const $el = $(this);
      const current = $el.offset();
      const parent = $el.offsetParent();
      const parentOffset = parent.is('html,body') ? {top:0,left:0} : parent.offset();
      
      const props = {
        top: coords.top - parentOffset.top,
        left: coords.left - parentOffset.left
      };
      
      if ($el.css('position') === 'static') {
        props.position = 'relative';
      }
      
      $el.css(props);
    });
  }
  
  if (!this.length || !$.contains(document.documentElement, this[0])) {
    return {top:0, left:0};
  }
  
  const rect = this[0].getBoundingClientRect();
  return {
    top: rect.top + window.pageYOffset,
    left: rect.left + window.pageXOffset,
    width: Math.round(rect.width),
    height: Math.round(rect.height)
  };
}

要素のドキュメントに対する絶対座標を取得・設定するメソッドです。

スクロール操作メソッド

.scrollTop()メソッド

scrollTop: function(value) {
  if (!this.length) return;
  
  const hasScroll = 'scrollTop' in this[0];
  if (value === undefined) {
    return hasScroll ? this[0].scrollTop : window.pageYOffset;
  }
  
  return this.each(hasScroll 
    ? function() { this.scrollTop = value } 
    : function() { this.scrollTo(this.scrollX, value) }
  );
}

要素の垂直方向のスクロール位置を取得・設定するメソッドです。

タグ: zepto DOM操作 javascript ソースコード解析

8月15日 17:42 投稿