2011-01-07 145 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。在這一點上重寫應該會給你精確的,明確的行爲。但現在你會變得怪異。