IE の getAttribute / setAttribute ― 2005年10月29日 04時29分
DOM の getAttribute / setAttribute メソッドは DOM Level 1 から定義されているメソッドで、MSDN Library によれば IE はバージョン 4 からサポートしています。しかし、IE での element.getAttribute(name)
/ element.setAttribute(name, value)
というのは、基本的には JavaScript における element[name]
/ element[name] = value
のシンタックスシュガーでしかありません。ですから、element.setAttribute("innerHTML", "foo")
とすると、element の属性には何の変化もないが element の内容が書き換えられるという事態になります。
この (手抜き) 実装が原因で、getAttribute
/ setAttribute
で class 、style 、イベント属性などを操作できないというバグが IE にはあります。具体的には無理やり getAttribute / setAttribute メソッドを使おうとするなら以下のようにしなくてはいけません。
// NG
element.getAttribute("class");
element.setAttribute("style", "background-color: #fff; color: #000;");
element.setAttribute("onclick", "clickHandler(event);");
// OK
element.getAttribute("className");
element.style.cssText = "background-color: #fff; color: #000;";
element.setAttribute("onclick", new Function("clickHandler(event);"));
また、デフォルトで getAttribute
は大文字小文字を区別せずプロパティ名を検索しますが、setAttribute
は大文字小文字を区別します。この動作は IE 独自の引数 iFlags を設定することで変更可能です。(0: 大文字小文字を区別しない、1: 大文字小文字を区別する)
input.setAttribute("maxLength", 10);
input.setAttribute("maxlength", 20);
alert(input.getAttribute("MAXLENGTH")); // 10
input.setAttribute("maxlength", 30, 0);
alert(input.getAttribute("MaxLength")); // 30
alert(input.getAttribute("maxlength", 1)); // 20
ちなみに、このことを利用すればほぼ確実に IE かどうかを判別できると思われます。document.all
を実装するブラウザはいくつもありますが、こんな奇妙な動作を実装するブラウザはほかにはないでしょう。(あったら教えてください。)
var isIE = (document.documentElement.getAttribute("style") ==
document.documentElement.style);
ただし、手元に環境がないため、Mac IE 5 でも同じ動作をするのかは不明です。もしどなたか試してくださった際にはぜひ報告していただければ幸いです。
なお、これはあくまでも HTML (MSHTML) に関しての話であり、XML (MSXML) に関しては IE もちゃんと仕様どおりの動作をします。
参考
コメント
_ オムスビ ― 2005年11月06日 02時44分
_ nanto_vi ― 2005年11月06日 12時52分
Mac IEでも同じ実装なのですね。
判別の手間が省けると思いつつもちょっと残念です。
_ nao ― 2006年02月26日 00時57分
_ nao ― 2006年02月26日 01時05分
助かりました。
前の投稿、記事が消えてしまいましたが、こんどはちゃんとかきこめるだろうか。
_ hal* ― 2006年09月15日 16時23分
_ brazil ― 2006年11月07日 23時22分
checked -> defaultChecked
usemap -> useMap
for -> htmlFor
readonly -> readOnly
colspan -> colSpan
bgcolor -> bgColor
_ nanto_vi ― 2006年11月09日 20時29分
defaultChecked はちょっと特殊 (動的に生成した input 要素を文書ツリーに挿入する前に設定した checked 属性は反映されず、defaultChecked だと反映される) ですがあとは DOM HTML と同じ変換ですね。
実際に試したわけではありませんが DOM HTML 仕様から抜き出す限りでは以下も当てはまりそうです。
http-equiv -> httpEquiv
tabindex -> tabIndex
accesskey -> accessKey
accept-charset -> acceptCharset
datetime -> dateTime
ismap -> isMap
longdesc -> longDesc
codebase -> codeBase
codetype -> codeType
valuetype -> valueType
nohref -> noHref
cellpadding -> cellPadding
cellspacing -> cellSpacing
char -> ch
charoff -> chOff
rowspan -> rowSpan
_ F.D ― 2007年04月13日 17時39分
}
IEの場合はdocument.allがTrueになりました。
_ NMT ― 2007年09月21日 16時42分
ありがとうございます。
_ PIN ― 2007年10月13日 22時16分
今作成しているものにこのsetAttributeの動作が必要なのですが、
onClickを入れようとして属性値にfunction名("値")を入れているのですが、FireFoxで実行した時に値が変数だとそのまま変数名が入ってしまいます。
FireFoxの場合変数の中身を代入することはできないのでしょうか?
説明が下手で申し訳ございませんが、ご教授願えたらと思います。
_ nanto_vi ― 2007年10月14日 23時24分
var a = 42;
element.setAttribute("onclick", "alert('a');");
}
としたら、42 と表示してほしいのに a と表示されてしまったということでしょうか?
もしそうなら、以下のようにクロージャを使うことで解決できます (ブラウザによってはクロージャの使用がメモリリークの原因となることもありますが)。
function f() {
var a = 42;
element.addEventListener("click", function () { alert(a); }, false);
}
_ otn ― 2007年12月11日 20時16分
element.setAttribute("onclick", "alert('"+a+"');");
でいいんじゃないですか?
aの値がsetAttribute時点とclick時点で異なるならダメですが。
_ nanto_vi ― 2007年12月12日 01時19分
_ nanto_vi ― 2009年08月27日 23時47分
大変申し訳ありません。
_ Ghost X ― 2011年03月06日 21時44分
getAttribute:function(element,name){
var browser=getBrowserName();
if(browser=='InternetExplorer'){
switch(name){
case 'class':
name='className';
break;
case 'checked':
name='defaultChecked';
break;
case 'usemap':
name='useMap';
break;
case 'for':
name='htmlFor';
break;
case 'readonly'
name='readOnly';
break;
case 'colspan':
name='colSpan';
break;
case 'bgcolor':
name='bgColor';
break;
case 'http-equiv':
name='httpEquiv';
break;
case 'tabindex':
name='tabIndex';
break;
case 'accesskey':
name='accessKey';
break;
case 'accept-charset':
name='acceptCharset';
break;
case 'datetime':
name='dateTime';
break;
case 'ismap':
name='isMap';
break;
case 'longdesc':
name='longDesc';
break;
case 'codebase':
name='codeBase';
break;
case 'codetype':
name='codeType';
break;
case 'valuetype':
name='valueType';
break;
case 'nohref':
name='noHref';
break;
case 'cellpadding':
name='cellPadding';
break;
case 'cellspacing':
name='cellSpacing';
break;
case 'char':
name='ch';
break;
case 'charoff':
name='chOff';
break;
case 'rowspan':
name='rowSpan';
break;
}
}
return element.getAttribute(name);
}
};
_ Ghost X ― 2011年03月06日 21時48分
if(/*@cc_on!@*/false){
return true;
}
return false;
}
皆さんの意見を参考に、
CSS.getAttribute(element,name,value);
を作ってみました。
ただ、あまりにも長いというか、処理が多くなってしまいます;
もっと、軽く書ける方法をご存知の方は書いてください><;
_ Ghost X ― 2011年03月06日 21時51分
正しくは、
function getBrowserName(){
if(/*@cc_on!@*/false){
return 'InternetExplorer';
}
return null;
}
です。
_ Ghost X ― 2011年03月07日 03時09分
CSS.getAttribute関数のswitch文内に、以下の記述を追加して下さい^^;
case 'style':
return element.style.cssText+';';
break;
連投すみませんm(_ _)m
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※投稿には管理者が設定した質問に答える必要があります。
トラックバック
このエントリのトラックバックURL: http://nanto.asablo.jp/blog/2005/10/29/123294/tb
_ BUZZ LIVEYEAR - 2005年12月28日 09時44分
_ Blog::Trapple::Net - 2006年04月21日 17時23分
_ Junnama Online - 2006年06月18日 14時18分
_ A Better Project@はてなダイアリー - 2006年10月24日 10時03分
_ 神保町のウェブ制作者のつぶやき - 2006年10月24日 23時02分
_ ひきこもり生活記 - 2007年04月04日 21時11分
_ cefa::blog - 2007年07月05日 15時11分
_ KK企画研究所 - 2008年03月05日 13時34分
今回は、InternetExplorer(以下IE)でsetAttribute()メソッドを使ったスクリプトを書いていてハマッテしまったので、その解決策を忘れないうちに記します。
= IEと非IE系ブラウザの差異 =
現在あるDOMに対して、動的に属性などを設定する場合、モダンブラウザ繁栄の時代でもあるので、やはり DOM.setAttribute()メソッドを使いたくなります。
そこで、id="text...
_ 覚え書きみたいなもの - 2008年09月01日 14時59分
JavaScriptにて、elementオブジェクトから、
setAttributeメソッドにて class 、style 、onclick等のイベント属性の設定を行うことができない。
(getでの取得もできない。)
それぞれ、
【クラス】
キー指定を"class"で....
_ progress - 2009年06月05日 19時14分
#というか、何でIEってこんな...
Mac IE 5.2.3で「p.style == p.getAttribute("style")」を試したら、「true」になりました。
Safari 2.0.2の場合は、「false」になりました。
どちらもMac OS X 10.4.3上で確認。