我最近开始使用custom elements。
如您所知,HTMLElement
在文档中包含标记和JavaScript object
。因此,使用我的自定义元素,我尝试将JavaScript对象properties
与元素attributes
相关联。
因此,如果其中任何一个更新,另一个也会更新。但这并没有发生,我发誓我已经尝试了一切,也许是一些愚蠢的我不知道但是对我来说,这段代码的表现是一种奇怪的错误。
在阅读下面的代码说明并看到演示后,您应该能够理解我的问题:
attributes
正确更新,但不是properties
?我已经设置了一个JSFiddle来说明我的问题,我将在本文中讨论代码应该如何工作。
<e-button color="red" width="250px">RED BUTTON</e-button>
嗯,它很少比这更简单。我创建了一个名为“电子按钮”的自定义对象,其中包含color=red
和width=250px
。
var eButtonProto = Object.create(HTMLElement.prototype);
eButtonProto.createdCallback = function() {
this.__htmlToJsProp(); //Gets all the HTML attributes and makes them accessible via JS.
this.__processAttr(); //Makes decision upon predefined attributes.
}
eButtonProto.__htmlToJsProp = function() {
var attr = this.attributes;
for (var i = 0; i < attr.length; i++) {
var current = attr[i];
var name = current.name;
var value = current.value;
this[name] = value;
Object.defineProperty(this, name, {
get: function() {
return this.getAttribute(name);
},
set: function(val) {
this.setAttribute(name, val);
}
});
}
}
eButtonProto.attributeChangedCallback = function(name, oldVal, val) {
this[name] = val;
this.__processAttr();
}
eButtonProto.__processAttr = function() {
var color = this.color || this.defaults.color;
this.style.backgroundColor = color;
}
eButtonProto.defaults = {
color: "whitesmoke"
}
var eButton = document.registerElement("e-button", {
prototype: eButtonProto
});
window.onload = function() {
redButton = document.querySelector("e-button[color=red]");
console.log("button ATTRIBUTES", redButton.getAttribute("color"), redButton.getAttribute("width"));
console.log("button PROPERTIES", redButton.color, redButton.width);
} < /script>
这里真正重要的代码片段是这些,它们必须使我的想法有效,首先是__htmlToJsProp()
函数:
eButtonProto.__htmlToJsProp = function() {
var attr = this.attributes; //Gets the element's attributes.
for (var i = 0; i < attr.length; i++) {
var current = attr[i]; //Element attribute name,value pair.
var name = current.name; //Attribute name.
var value = current.value; //Attribute value.
Object.defineProperty(this, name, { //Defines the element property from the attribute name, for simplicity I will be using the color attribute as my example.
get: function() {
return this.getAttribute(name); //When accessing element.color you should get element.getAttribute("color")
},
set: function(val) {
this.setAttribute(name, val); //When setting element.color = "red" you should also be doing element.setAttribute("color","red");
}
});
this[name] = value; //Sets element.color = "red"
}
}
然后是attributeChangedCallback
函数:
eButtonProto.attributeChangedCallback = function(name, oldVal, val) {
this[name] = val; //This would be the other way around, if the attribute is updated via setAttribute, or the browser console, the property is updated (works).
this.__processAttr(); //You can ignore this
}
您在测试后看到很多我发现如果您将自己放在for循环中并输出属性值,它会为您提供element.color = "red"
和element.width = "250px"
; < / p>
但是如果你在for循环之外测试它,它会为属性提供element.color = "250px"
和element.width = "250px"
,但属性会正确更新,即element.getAttribute("color") = "red"
和element.getAttribute("width") = "250px"
。
如果你做到这一点,那么,非常感谢,希望你能找到解决这个问题的方法,我真的似乎无法解决这个问题,快乐的编码:)
答案 0 :(得分:1)