・ chrome での動作の相違
・ prototype.js では Element が使えない
以前も似たようなものをUPしたのですが、2年も!放置していたので、今使っているものを紹介。
Javascript:DOMオブジェクトかECMAオブジェクトかを判定する。
こちらで Element を使えば良いというお話しが出ているのですが、実は Element では prototype.js など使わざる得ない場合(他の人が作成したものの改造とか・・・)に期待どおり動きません。
しかも prototype.js の利用率って意外と馬鹿にならない。
■ 確認環境
ie 5.0, 6.0, 7.0, 8.0
ff 1.0, 1.5, 2.0, 3.0
op 7.02, 8.53, 9.01
ns 6.2, 7.1
safari 4.0beta(for win)
sleipnir 2.3
google chrome
各 prototype.js あるなしです。ちなみに ie5.0 は prototype.js 動きません。
最新が無いものも目立ちますが op とかw
ソース
function isElement(e){
var r = null;
if(e && e.nodeType === 1){
try{
r = e.cloneNode(false);
}catch(n){
return false;
}
try{
if(r == e){
return false;
}else{
// CloneNode で別物なら書換え試行
r.nodeType = 9;
}
if(r.nodeType === 1){
// Cr は error にならないが書き換えられない。
return true;
}else{
return false;
}
}catch(n){
// Cr 以外は error になる
return true;
}
}else{
return false;
}
}
var r = null;
if(e && e.nodeType === 1){
try{
r = e.cloneNode(false);
}catch(n){
return false;
}
try{
if(r == e){
return false;
}else{
// CloneNode で別物なら書換え試行
r.nodeType = 9;
}
if(r.nodeType === 1){
// Cr は error にならないが書き換えられない。
return true;
}else{
return false;
}
}catch(n){
// Cr 以外は error になる
return true;
}
}else{
return false;
}
}
hasOwnProperty すら使っていません。
実は、cr ですと hasOwnProperty で nodeType を見ると true になってしまう。
確認例)
var ele = document.createElement('div');
alert(ele.hasOwnProperty('nodeType'));
ff ですと当然 false ですし、ie では [element] に hasOwnProperty はありません。
また、[element].nodeType に値を入れようとすると多くのブラウザでは、例外が発生するのに対し、cr では無言?です。
ただし、書き換えられない。
結局、prototype.js のようなライブラリを使う場合、hasOwnProperty の動作がブラウザ毎に異なることや、Element や Object など簡単に書き換えられるという事を加味すると、動作上許されないようなメソッドやプロパティを利用するしか手が無い訳です。
つまりここで使用しているのは cloneNode と nodeType への書き込み。
cloneNode で自身を返すような、イヤらしい自前のオブジェクトはそのまま false になりますし、ちゃんと別物を返すような場合は、実際 nodeType を書き換えてやっても問題ない訳です。
通常 nodeType 調べれば事足ります。
苦労してアップしつつ骨折りな事追記してますがw
cloneNode や例外を投げるような事をしていますので、当然余分に負荷が掛かります。
ごちゃごちゃと得体の知れない事をしているスクリプトには、無用な誤動作を防止できると思います。ま、それでも nodeType 持っているオブジェクト+protoype.jsってところでしょうけど。
※ これぐらいのものでも正答します。
function mimic(){}
mimic.prototype.nodeType = 1;
mimic.prototype.hasOwnProperty = function (p){
// ちなみにこれは完ぺきではない
return (this[p] && !this.constructor.prototype[p]);
};
mimic.prototype.cloneNode = function (){
return this;
// とか
return {};
}
※ こんなイジワルされると誤答しますw
mimic.prototype.cloneNode = function (){
return document.createElement('div');
}
苦労してアップしつつ骨折りな事追記してますがw
cloneNode や例外を投げるような事をしていますので、当然余分に負荷が掛かります。
ごちゃごちゃと得体の知れない事をしているスクリプトには、無用な誤動作を防止できると思います。ま、それでも nodeType 持っているオブジェクト+protoype.jsってところでしょうけど。
※ これぐらいのものでも正答します。
function mimic(){}
mimic.prototype.nodeType = 1;
mimic.prototype.hasOwnProperty = function (p){
// ちなみにこれは完ぺきではない
return (this[p] && !this.constructor.prototype[p]);
};
mimic.prototype.cloneNode = function (){
return this;
// とか
return {};
}
※ こんなイジワルされると誤答しますw
mimic.prototype.cloneNode = function (){
return document.createElement('div');
}



この記事へのコメント