5

重複の可能性:
Javascript で DOM を拡張できますか?

Element にメソッドとプロパティを追加しようとしています。グローバルクラスとしてリストされていません。次のように String を拡張できます。

String.prototype.dosomething = function { ... };

私はこのように試みます(それはより大きく、これが基本です):

function $id(str){
    this.element = document.getElementById(str); 
    return element;
}
var myElem = $id('myId'); // WORKS !!!
$id.prototype.dosomethig = function ( ... }; 
var myValue = $id('myId').dosomething(); // DOESN'T WORK !!!

私は他の方法で試しますが、クラスを拡張しようとすると、常に同じであるという点は機能しません。これを回避する方法はありますか?私はjQueryがこれを行うことを知っていますが、私は自分のonwをやりたいです-できるなら、できます...そうですか?

編集: Safari と Firefox で既に動作しているコードの下...

Element.prototype.pos = function(){
    var curleft = this.offsetLeft;
    var curtop = this.offsetTop;
    var scrleft = this.scrollLeft;
    var scrtop = this.scrollTop;
    var pElement = pElementScr = this.offsetParent
    while(pElement){
        curleft += pElement.offsetLeft;
        curtop += pElement.offsetTop;
        pElement = pElement.offsetParent;
    }
    while(pElementScr){
        scrleft += pElementScr.scrollLeft;
        scrtop += pElementScr.scrollTop;
        pElementScr = pElementScr.offsetParent;
    }
    return {x:this.offsetLeft, y:this.offsetTop};
}

他の多くのdivの内側でもdivの位置を示します。ライブラリの他の多くの問題を解決した後、IE8 でテストしてみます。

4

4 に答える 4

4

Firefox では、chrome および IE8+ 要素が継承されるElement.prototypeため、次のことを行う必要があります。

Element.prototype.doSomething = function() {
    alert("hello");
};

ホスト プロトタイプの拡張は非常に壊れやすく、お勧めしませんが、ただ遊んでいるだけなら問題ないはずです。主な理由は、DOM 仕様がプロトタイプの実装を指定しておらず、インターフェイスだけを指定しているためです。動作する必要があり、プロトタイプelem.appendChild()である必要はありません。


これ:

function $id(str) {
    this.element = document.getElementById(str);
    return element;
}

this関数がオブジェクトコンテキストなしで呼び出されたときにグローバルオブジェクトを参照する望ましくない動作のためにのみ機能しました(this厳密モードでは、に設定することでこれをいくらか修正しますが、単に を見ただけでエラーをスローする必要がありますundefined)。グローバル変数を作成しelement(グローバル オブジェクトへのプロパティの割り当てがグローバル変数になるため)、グローバル変数を返します。

于 2012-08-02T20:45:50.463 に答える
2

DOM オブジェクトを拡張する代わりに、jQuery のようにラップしてみませんか。

var myLib = {
   addWrapper: function ( id ) {
      return new this.WrapperClass( document.getElementById( id ) );
   },
   WrapperClass: function ( element) {
      this.element = element;
   }
};
MyLib.WrapperClass.prototype.someMethod = function() {
   alert( this.element);
}

var wrappedElement = myLib.addWrapper( 'someid' );
wrappedElement.someMethod();
于 2012-08-02T20:56:35.127 に答える
0
$id('myId').dosomething()

$id('myId') は要素です。

'Element' に doSomething という関数はありません。関数である $id にあります。実際、関数に関数を追加するとどうなりますか?

于 2012-08-02T20:52:40.480 に答える
0

まず第一に、DOM の拡張はしばしば (常に) 悪い選択です。高速なクロスブラウザー コードを記述したい場合は、DOM やその他のネイティブ オブジェクト (オブジェクト、文字列など) を拡張しないでください。ネイティブ オブジェクトを拡張すると、ライブラリなどとの互換性の問題も発生する可能性があります。この件について詳しく知りたい場合は、次の優れたブログ投稿をご覧になることをお勧めします: http://perfectionkills.com/whats-wrong-with -extending-the-dom/

古いバージョンの IE (IE6 && 7) のサポートが重要でない場合は、次のようにします。

Element.prototype.doSomething = function () {
    // Your code here
};

あなたの例では、問題は $id が要素を返すことです。あなたの「doSomething」は、それが返す要素ではなく、関数 $id に添付されています。

これを行うとうまくいきます:

function $id(str){
    this.element = document.getElementById(str); 
    return this;
}
于 2012-08-02T20:54:17.410 に答える