2011-01-07 101 views
2

我有一个大项目,我需要截取像element.src,element.href,element.style等东西的分配。我想通过defineSetter来做到这一点,但它的行为非常奇怪(使用Chrome 8.0.552.231)Javascript的奇怪行为__defineSetter__

一个例子:

var attribs = ["href", "src", "background", "action", "onblur", "style", "onchange", "onclick", "ondblclick", "onerror", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onmousedown", "onmousemove", "onmouseover", "onmouseup", "onresize", "onselect", "onunload"]; 
for(a = 0; a < attribs.length; a++) { 
    var attrib_name = attribs[a]; 
    var func = new Function("attrib_value", "this.setAttribute(\"" + attrib_name + "\", attrib_value.toUpperCase());"); 
    HTMLElement.prototype.__defineSetter__(attrib_name, func); 
} 

这段代码应该做的是,只要给attribs常见的元素属性分配,它使用的setAttribute()设置一个大写的版本的属性。

对于一些非常奇怪的原因,setter只能工作约1/3的任务。

例如与

element.src = "test" 

新src为 “TEST”,喜欢它应该是

element.href = "test" 

新href是 “试验”,然而

,没有大写

然后,即使当我尝试element.__lookupSetter__("href"),它返回适当的大写setter

最奇怪的事是不同的变量,Chrome和Firefox

帮助之间

正确拦截!

回答

2

这不是一个好主意。主机对象(如DOM元素)不受适用于本机JavaScript对象的通常规则的约束,并且基本上可以做他们喜欢的事情,所有浏览器都或多或少地利用这个事实。浏览器没有义务为宿主对象提供原型,他们也不一定要允许你重写宿主对象属性的getter和setter,或者尊重任何覆盖默认行为的尝试。

我强烈建议放弃这种方法,并采取不同的方法,例如编写DOM元素的包装对象。

UPDATE:包装方法的实例

您可以创建DOM元素包装对象,并通过这些包装做的所有DOM操作。这是许多图书馆(如YUI)所做的事情。例如:

function ElementWrapper(el) { 
    this.domElement = el; 
} 

ElementWrapper.prototype = { 
    // Wrap the DOM methods you need 
    appendChild: function(child) { 
     this.domElement.appendChild(child); 
    }, 

    // Add custom behaviour, such as converting certain 
    // property values to upper case 
    setProperty: function(name, value) { 
     if (/^(src|href|action)$/i.test(name)) { 
      this.domElement[name] = value.toUpperCase(); 
     } else { 
      this.domElement[name] = value; 
     } 
    } 
}; 

var wrappedEl = new WrappedElement(document.getElementById("foo")); 
wrappedEl.setProperty("href", "http://www.google.com/"); 
+0

你可以推荐一些其他方法,或进一步解释你的意思/如何实现DOM元素的包装对象? – 2011-01-07 23:58:38

2

呼应蒂姆下,加入我自己的两分钱,你将有更好的运气,更跨浏览器,符合标准的方式,如果你等待WebIDL完全定义为ECMAScript的绑定DOM。在这一点上重写应该会给你精确的,明确的行为。但现在你会变得怪异。