当我们使用Web组件技术创建自定义元素时,有时自定义元素的实现涉及使用主文档中结果元素上存在的属性。如下例所示:
主要文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="import" href="web-components/my-portrait.html">
</head>
<body>
<my-portrait src="images/pic1.jpg" />
</body>
</html>
&#13;
我-portrait.html:
<template id="my-portrait">
<img src="" alt="portait">
</template>
<script>
(function() {
var importDoc = document.currentScript.ownerDocument;
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var t = importDoc.querySelector("#my-portrait");
var clone = document.importNode(t.content, true);
var img = clone.querySelector("img");
img.src = this.getAttribute("src");
this.createShadowRoot().appendChild(clone);
}
}
});
document.registerElement("my-portrait", {prototype: proto});
})();
</script>
&#13;
在createdCallback中,我们使用this.getAttribute(&#34; src&#34;)来获取在portrait元素上定义的src属性。
但是,这种获取属性的方法只能在元素通过元素标记声明实例化时使用。但是如果元素是使用JavaScript创建的: document.createElement(&#34; my-portrait&#34;)?当执行此语句时,已经调用createdCallback并且 this.getAttribute(&#34; src&#34;)将返回null,因为元素在创建时没有立即生成src属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="import" href="web-components/my-portrait.html">
</head>
<body>
<!--<my-portrait src="images/pic1.jpg" />-->
<script>
var myPortrait = document.createElement("my-portrait");
myPortrait.src = "images/pic2.jpg"; // too late
document.getElementsByTagName("body")[0].appendChild(myPortrait);
</script>
</body>
</html>
&#13;
那么当我们使用JavaScript实例化自定义元素时,如何将属性传递给createdCallback?如果有一个beforeAttach回调,我们可以在那里设置属性,但是没有这样的回调。
答案 0 :(得分:2)
您可以实施名为 attributeChangedCallback
的生命周期回调:
我-portrait.html:强>
proto.attributeChangedCallback = function ( name, old, value )
{
if ( name == "src" )
this.querySelector( "img" ).src = value
//...
}
name
是修改(或添加)属性的名称,old
是属性的旧值,如果刚创建,则为undefined
,value
是属性的新值(类型为string
)。要调用回调,请对自定义元素使用 setAttribute
方法。
主要文档:
<script>
var myPortrait = document.createElement( "my-portrait" )
myPortrait.setAttribute( "src", "images/pic2.jpg" ) // OK
document.body.appendChild( myPortrait )
</script>
示例强>:
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
this.innerHTML = document.querySelector("template").innerHTML
var path = this.getAttribute("src")
if (path)
this.load(path)
}
},
attributeChangedCallback: {
value: function(name, old, value) {
if (name == "src")
this.load(value)
}
},
load: {
value: function(path) {
this.querySelector("img").src = path
}
}
})
document.registerElement("image-test", { prototype: proto })
function add() {
var el = document.createElement("image-test")
el.setAttribute("src", "https://placehold.it/100x50")
document.body.appendChild(el)
}
&#13;
<image-test src="https://placehold.it/100x100">
</image-test>
<template>
<img title="portrait" />
</template>
<button onclick="add()">
add
</button>
&#13;