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

时间:2012-08-02 20:42:06

标签: javascript dom prototype

  

可能重复:
  In Javascript, can you extend the 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这样做,但我想做我的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中进行测试。

4 个答案:

答案 0 :(得分: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来修复此问题。您正在创建一个全局变量{{1}}(因为对全局对象的属性赋值变为全局变量),然后返回全局变量。

答案 1 :(得分: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();

答案 2 :(得分:0)

$id('myId').dosomething()

$ id('myId')是一个元素。

你在'Element'中没有一个名为doS​​omething的函数,你有$ id,这是一个函数。实际上当你向函数添加一个函数时会发生什么?是否可能?

答案 3 :(得分:0)

首先,扩展DOM通常(读:总是)是一个糟糕的选择。如果要编写快速的跨浏览器代码,则不应扩展DOM或其​​他本机对象(Object,String ...)。扩展本机对象也可能导致与库等的兼容性问题。如果您想了解有关该主题的更多信息,我建议您查看这篇优秀的博客文章: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;
}