Javascript 如何将DOM元素扩展为类(没有jQuery)

Javascript 如何将DOM元素扩展为类(没有jQuery),javascript,dom,prototype,Javascript,Dom,Prototype,可能重复: 我正在尝试向元素添加方法和属性。它未列为全局类。我可以像这样扩展字符串: String.prototype.dosomething = function { ... }; 我试着这样做(它更大,这是最基本的): 我尝试了其他方法,但重点总是一样的,当我尝试扩展类时,它不起作用。有没有办法避免这种情况?我知道jQuery可以做到这一点,但我想做我的onwn-如果他们可以,我可以。。。对吧? 编辑: 下面是已经在Safari和Firefox中运行的代码 Element.prototy

可能重复:

我正在尝试向元素添加方法和属性。它未列为全局类。我可以像这样扩展字符串:

String.prototype.dosomething = function { ... };
我试着这样做(它更大,这是最基本的):

我尝试了其他方法,但重点总是一样的,当我尝试扩展类时,它不起作用。有没有办法避免这种情况?我知道jQuery可以做到这一点,但我想做我的onwn-如果他们可以,我可以。。。对吧?

编辑: 下面是已经在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中进行测试。

在firefox中,chrome和IE8+元素继承自
元素。prototype
因此您必须执行以下操作:

Element.prototype.doSomething = function() {
    alert("hello");
};
扩展主机原型是非常脆弱的,不推荐使用,但如果您只是在玩的话应该可以。主要原因是DOM规范没有指定原型实现,只指定接口,
elem.appendChild()
应该可以工作,它不必在某个原型中


这:

只有当函数在没有任何对象上下文的情况下被调用时,
引用全局对象的不希望的行为才起作用(它应该一看到
,就抛出一个错误,尽管严格模式通过将其设置为
未定义
,在某种程度上解决了这个问题)。您正在生成一个全局变量
元素
(因为全局对象的属性指定成为全局变量),然后返回全局变量

$id('myId').dosomething()
$id('myId')是一个元素


在'Element'中没有名为doSomething的函数,而是在$id上,这是一个函数。实际上,当您将一个函数添加到一个函数中时,会发生什么情况呢?

首先,扩展DOM通常是一个错误的选择。如果您想编写快速的跨浏览器代码,就不应该扩展DOM或其他本机对象(对象、字符串…)。扩展本机对象还可能导致与库等的兼容性问题。如果您想了解更多有关本机对象的信息,我建议您阅读以下优秀的博文:

如果支持旧版本的IE(IE6&&7)对您来说并不重要,那么这就是您想要的:

Element.prototype.doSomething = function () {
    // Your code here
};
在您的示例中,问题是$id返回一个元素。“doSomething”附加到函数$id,而不是它返回的元素

这样做有效:

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

与其扩展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();

您应该阅读AFAIK,jQuery不会这样做。它们提供了一个包装器,但避免接触DOM原型。请详细说明,为什么它很脆弱?@srini.venigalla请参阅FelixKling对您的问题的评论同意——这很脆弱,应该avoided@Esailija-好吧,这和多姆有关,我同意,我想你的意思是,一般来说,原型扩展是脆弱的。我正在做一个小的库,我在其中识别浏览器(类型和版本),这样我就可以为每种情况编写代码。Element.prototype适用于我的Safari,这是一个很好的起点!他没有将函数分配给函数,而是将其分配给
$id.prototype。dosomethig
$id.prototype
是一个对象。当然,由于函数是对象,它们可以具有任意属性。@Felix right$id返回一个元素,他在其中添加了一个函数,然后为“myId”创建了一个实例,为什么它没有得到扩展?他返回
元素
,该元素实际上应该抛出一个错误,因为它没有定义。他必须从
$id
返回
这个
。类的创建方式与函数的创建方式相同,这只是“观点”的问题。很好。如果在IE8中工作,这几乎可以解决所有问题。我不打算与旧版本兼容。有趣的是,我的js没有一个类引用列表元素。我从来没有这样做过,我会试试。
function $id(str){
    this.element = document.getElementById(str); 
    return this;
}
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();