私がやろうとしていることをよりよく反映するようにタイトルを更新しました。
つまり、dom要素ごとに異なるコンストラクターがあり、それらすべてが共通のプロトタイプを共有しているわけではないようです。これらのプロトタイプを変更して、すべてのDOM要素に関数プロパティを追加する方法を探していますが、それらを見つける方法がわかりません。
たとえば、次のようなことができます。
function enhanceDom (tagNames, methods) {
var i=-1, tagName;
while (tagName=tagNames[++i]) {
var tag=document.createElement(tagName);
if (!(tag && tag.constructor)) continue;
for (var methodName in methods) {
tag.constructor.prototype[methodName]=methods[methodName];
}
}
}
var thingsToEnhance = ['a','abbr','acronym','address'/* on and on... */];
enhance(thingsToEnhance, {
doStuff : function(){
/* ... */
},
doOtherStuff : function(){
/* ... */
}
/* ... */
});
もちろん、すべてのhtml要素をリストせずにこれを実行したいと思います。誰かがより良い方法を考えることができますか?
(元の質問は次のとおりです)
目標-getElementsByClassName
任意のブラウザの任意のDOMノードで動作するようにします。
それは以前に(ある種の)行われたことがありますが、これが私のショットです。
私が持っている質問は、動的に作成された要素でこれを機能させる良い方法はありますか?HTML DOM要素は、追加できる共通の予測可能なプロトタイプを共有していないgetElementsByClassName
ようです...または、何かが足りないのでしょうか。
これが私がこれまでに得たものです(編集-ディスカッションごとに更新されます)。
(function(){
var fn = 'getElementsByClassName';
// var fn = 'gEBCN'; // test
if (typeof document[fn] != 'undefined') return;
// This is the part I want to get rid of...
// Can I add getByClass to a single prototype
// somewhere below Object and be done with it?
document[fn]=getByClass;
withDescendants(document, function (node) {
node[fn]=getByClass;
});
function withDescendants (node, callback, userdata) {
var nodes = node.getElementsByTagName('*'), i=-1;
while (node=nodes[++i]) {
callback(node, userdata);
}
return userdata;
}
function getByClass (className) {
return withDescendants(this, getMatches, {
query:new RegExp('(^|\\s+)' + className + '($|\\s+)'),
found:[]
}).found;
}
function getMatches (node, data) {
if (node.className && node.className.match(data.query)) {
data.found.push(node);
}
}
}());
スクリプトがロードされる前にロードされたコンテンツではうまく機能しますが、動的に作成された新しい要素はgetElementsByClassName
メソッドを取得しません。何か提案はありますか(setInterval以外にお願いします)?