jQuery attributes.js 2回(最終回)

attributes.jsのメモを公開します! 参加者@ryuoneさんの記事も合わせてごらんください。 →4月9日(土)のjQuery attributes.js 読書会に・・・

今回は266行目からjQueryのバージョンは1.5.1です。

jQuery.extend({
	attrFn: {
		val: true,
		css: true,
		html: true,
		text: true,
		data: true,
		width: true,
		height: true,
		offset: true
	},

	attr: function( elem, name, value, pass ) {
		// don't get/set attributes on text, comment and attribute nodes
		// テキスト、コメント、タグの属性は取得登録ができない。
		// elemがないか、elemのnodeTypeが3(テキスト)か、8(コメント)か、2(タグの属性)であれば何もしない。
		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
			return undefined;
		}

		// 第4引数passがあり第2引数nameがval,css,html,text,data,width,height,offsetであれば
		// inの返り値はBoolean
		if ( pass && name in jQuery.attrFn ) {
			// $(elem).val(value) or
			// $(elem).css(value) or
			// $(elem).text(value) or
			// $(elem).data(value) or
			// $(elem).width(value) or
			// $(elem).height(value) or
			// $(elem).offset(value)
			return jQuery(elem)[name](value);
		}

		// elem.nodeTypeが1(要素)以外であればtrue、そうではなくて、
		// jQuery.isXMLDoc( elem )がfalseであればtrue
		// isXMLDoc()の中身はSizzle.isXML 参照はsizzle-jquery.jsで渡している
		// notxmlはelemがxmlで無い場合trueにしたいので
		// notxml = !jQuery.isXMLDoc( elem ) とする。やっぱりこんがらがる。俺だけ? 
		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			// 第3引数があればtrueなければfalse
			set = value !== undefined;

		// Try to normalize/fix the name
		// jQuery.propsは12行目で定義
		// --------------------------------
		// jQuery.props = {
		// 	"for": "htmlFor",
		// 	"class": "className",
		// 	readonly: "readOnly",
		// 	maxlength: "maxLength",
		// 	cellspacing: "cellSpacing",
		// 	rowspan: "rowSpan",
		// 	colspan: "colSpan",
		// 	tabindex: "tabIndex",
		// 	usemap: "useMap",
		// 	frameborder: "frameBorder"
		// };
		// --------------------------------
		// notxmlがtrueでjQuery.propsがnameのキーを持っていれば name = jQuery.props[name]
		// そうでなければ name = name;
		name = notxml && jQuery.props[ name ] || name;

		// Only do all the following if this is a node (faster for style)

		// elemが要素ノードの場合の処理ここから
		if ( elem.nodeType === 1 ){
			// These attributes require special treatment
			// rspecialは6行目で定義
			// nameがhrefがsrcかstyleであればtrueを返す
			var special = rspecialurl.test( name );

			// Safari mis-reports the default selected property of an option
			// Accessing the parent's selectedIndex property fixes it
			// jQuery.support.optSelectedはsupport.jsで定義
			// nameが"selected"でありjQuery.support.optSelectedがfalseであれば
			if ( name === "selected" && !jQuery.support.optSelected ) {
				var parent = elem.parentNode;
				if ( parent ) {
					// selectedIndexは選択してるindexを返す ←まんまやね!
					// safari用の修正
					parent.selectedIndex;

					// Make sure that it also works with optgroups, see #5701
					if ( parent.parentNode ) {
						// 上と同じく
						parent.parentNode.selectedIndex;
					}
				}
			}

			// If applicable, access the attribute via the DOM 0 way
			// 'in' checks fail in Blackberry 4.7 #6931
			// name in elem || elem[ name ] !== undefinedとしてるのはブラックベリー4.7対策
			
			// elemがnameを持っており、elemがxmlではなく、nameが"href","src","style"でなければ 
			if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
				
				// elemの中にnameがあった場合の処理
				// 第3引数があれば、値をセットする
				if ( set ) {
					// We can't allow the type property to be changed (since it causes problems in IE)
					// nameがtypeであり、elemのノード名がbuttonかinputであり、親ノードがある場合
					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
						// エラーを返す
						jQuery.error( "type property can't be changed" );
					}

					// valueは第3引数
					if ( value === null ) {
						// elemが要素ノードであればnameの属性を削除
						if ( elem.nodeType === 1 ) {
							elem.removeAttribute( name );
						}

					} else {
						// セット
						elem[ name ] = value;
					}
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				// getAttributeNone DOM level2
				// jQuery.nodeNameはcore.jsで定義
				// 第一引数の要素のノード名が第2引数とマッチしているか調べる。返り値はBoolean
				// elemのノード名がformでありelemがname属性を持っている場合
				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
					// name属性の値を返す
					return elem.getAttributeNode( name ).nodeValue;
				}

				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
				// nameがtabIndexだった場合。あんまり使わないけどね。tabIndex
				if ( name === "tabIndex" ) {
					var attributeNode = elem.getAttributeNode( "tabIndex" );

					return attributeNode && attributeNode.specified ?
						attributeNode.value :
						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
							0 :
							undefined;
				}
				
				// elemのname属性を返す
				return elem[ name ];
			}

			// nameがstyleだった場合の処理
			if ( !jQuery.support.style && notxml && name === "style" ) {
			   //
				if ( set ) {
					// からの文字列を結合してvalueを文字列に変換
					elem.style.cssText = "" + value;
				}

				return elem.style.cssText;
			}

			// 上記条件に引っかからなかった場合の処理
			if ( set ) {
				// convert the value to a string (all browsers do this but IE) see #1070
				// IE は0を渡すと削除する
				elem.setAttribute( name, "" + value );
			}

			// Ensure that missing attributes return undefined
			// Blackberry 4.7 returns "" from getAttribute #6938
			// 要素を調べる場合
			if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
				return undefined;
			}

			// hrefNormalized で IE判定
			var attr = !jQuery.support.hrefNormalized && notxml && special ?
					// Some attributes require a special call on IE
					// elem.getAttribute( name, 2 )はIE用の対策
					// IEは相対パスなどの場合、勝手にhttp://と付加した値を返したりする。
					elem.getAttribute( name, 2 ) :
					elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}
		// elemが要素ノードの場合の処理ここまで		
		// Handle everything which isn't a DOM element node
		// DOMノード以外場合の処理
		if ( set ) {
			elem[ name ] = value;
		}
		return elem[ name ];
	}
});

})( jQuery );

毎度困惑するのですが、jsの場合

var v1 = "hoge1", v2 = "hoge2";
var v3 = v1 && v2; // v3 -> hoge2

一見trueが返ってきそうですが、返ってくるのは最後に評価した値です。

var v1 = "hoge1", v2 = "hoge2";
var v3 = v1 || v2; // v3 -> hoge1

となるので、当然といえば当然ですね ><

  • 2011/05/03
  • jsdokusho

コメントを書く

お名前[必須]

メールアドレス[必須]メールアドレスは公開されません。

コメント

トラックバック/ピンバック

トラックバック URL