在上一个教程“ 如何“延迟加载”嵌入式YouTube视频 ”中,我们研究了如何仅在用户单击时加载YouTube视频。 反过来,这可以帮助我们更快地加载网页,尤其是在其中包含多个Youtube视频的情况下。
如果您完全按照本教程进行操作,您将看到我们必须添加几个div元素以及类 ,样式和脚本才能使其正常工作。
每次都必须添加所有这些不是最方便的方法; 如果我们可以改为使用现成的元素(如<youtube-embed>来代替所有这些呢? 这正是我们在本教程中要做的。 我们将使用“ Web组件”创建功能全面的自定义HTML元素。 查看演示 ,然后潜入!
快速入门
入门
首先,我们需要创建一个新HTML文件。 我们将其命名为“ youtube-embed.html”。 该文件将包含所有用于注册和构建我们的新元素<youtube-embed> 。
它将包含以下JavaScript,因此让我们看一下这些基本内容:
( function( window, document, undefined ) {
// (1)
var thatDoc = document;
var thisDoc = ( thatDoc._currentScript || thatDoc.currentScript ).ownerDocument;
// (2)
var template = thisDoc.querySelector( 'template' ).content;
// (3)
var YoutubeProto = Object.create( HTMLElement.prototype );
// (4)
YoutubeProto.createdCallback = function() {
// (5)
var shadowRoot = this.createShadowRoot();
var clone = thatDoc.importNode(template, true);
shadowRoot.appendChild( clone );
// Add custom code here...
};
// (6)
window.youtubeEmbed = thatDoc.registerElement( 'youtube-embed', {
prototype : YoutubeProto
});
})( window, document );
相当多的事情,但逻辑上编号,所以让我们看一下它的作用:
- 在这里,我们定义了两个引用两个不同“文档”对象的变量。 第一个变量
thatDoc指的是我们在其中部署自定义元素的主文档。 第二个变量thisDoc是我们在其中注册新HTML元素的文档,在本例中为youtube-embed.html。 - 接下来,我们定义一个变量来存储
<template>元素的内容(我们很快就会讨论)。 - 然后,我们基于
HTMLElement对象创建一个新对象。 这将使我们的new元素能够继承任何HTML元素的方法和属性,例如id,className,clientHeith,scrollTop和childeNodes。 -
createdCallback是创建新元素时将立即实例化的函数。 - 在该回调函数中,我们创建“ Shadow DOM”,该阴影确定浏览器中自定义元素
<youtube-embed>的形状。 我们还将在这里开始编写自定义函数。 - 最后,我们注册我们的自定义元素,以便浏览器识别它。
导入HTML
接下来,在将嵌入视频的主文档中,导入youtube-embed.html 。
<script src="webcomponents.min.js"></script>
<link rel="import" href="youtube-embed.html">
Web组件Polyfill
Web组件是放在一起的一系列Web技术(模板,HTML导入,自定义元素和Shadow DOM)。 一些浏览器(例如Opera和Chrome)已经支持这些功能,但是Firefox,Edge和Safari在支持它们方面有自己的看法,因为它们仅部分支持或完全不支持。
因此,如果您希望您的元素适用于各种浏览器(当然可以),那么还需要加载Web Components polyfill 。
<script src="webcomponents.min.js"></script>
完成所有这些操作并将文件放在适当的位置后,我们现在可以添加其他代码片段,以使我们的自定义元素生效。
将定制元素带入生活
首先,在“ youtube-embed.html”中,添加<template>元素。 然后,在其中嵌套div和在上一教程中创建的样式。
<template>
<style>
.youtube {
background-color: #000;
margin-bottom: 30px;
position: relative;
cursor: pointer;
padding-top: 56.25%;
}
.youtube img {
width: 100%;
top: 0;
left: 0;
opacity: 0.7;
}
.youtube .play-button {
width: 90px;
height: 60px;
background-color: #333;
box-shadow: 0 0 30px rgba( 0,0,0,0.6 );
z-index: 1;
opacity: 0.8;
border-radius: 6px;
}
.youtube .play-button:before {
content: "";
border-style: solid;
border-width: 15px 0 15px 26.0px;
border-color: transparent transparent transparent #fff;
}
.youtube img,
.youtube .play-button {
cursor: pointer;
}
.youtube img,
.youtube iframe,
.youtube .play-button,
.youtube .play-button:before {
position: absolute;
}
.youtube .play-button,
.youtube .play-button:before {
top: 50%;
left: 50%;
transform: translate3d( -50%, -50%, 0 );
}
.youtube iframe {
height: 100%;
width: 100%;
top: 0;
left: 0;
}
</style>
<div class="youtube">
<div class="play-button"></div>
</div>
</template>
此时,如果我们部署<youtube-embed>元素并使用Chrome DevTools对其进行检查,我们会发现div元素,而我们刚刚添加的样式现在显示在自定义元素Shadow DOM下。
选择一个影子DOM元素
回到我们JavaScript,我们需要添加以下代码以从Shadow DOM中选择视频包装器元素。 注意,我们从shadowRoot变量中使用querySelector() 。 这是我们稍后将附加Youtube iframe的元素。
YoutubeProto.createdCallback = function() {
...
var video = shadowRoot.querySelector( ".youtube" ); // Select the video wrapper
};
自定义属性
在之前的教程中,我们使用data-embed属性传递了YouTube视频ID。 提醒一下,该ID用于获取视频图像缩略图,并指向正确的视频嵌入 URL。
对于Web组件,可以使用自定义的命名属性。 在这种情况下,例如,我们可以引入embed属性。
<youtube-embed embed="AqcjdkPMPJA">
然后,在createdCallback函数中,我们需要添加以下内容以获得embed属性值。
YoutubeProto.createdCallback = function() {
...
var video = shadowRoot.querySelector( ".youtube" ); // Select the video wrapper.
var embed = this.getAttribute( "embed" ); // Get the embed attribute value.
};
我们将把这两个变量传递给我们的自定义函数。
做事情
也许我的脑袋已经满了,但我想不出该函数的合适名称,因此是doTheThing 。
YoutubeProto.createdCallback = function() {
...
var embed = this.getAttribute( "embed" );
var video = shadowRoot.querySelector( ".youtube" );
this.doTheThing( embed, video );
};
YoutubeProto.doTheThing = function( embedID, videoElem ) {
var source = "https://img.youtube.com/vi/"+ embedID +"/sddefault.jpg";
var image = new Image();
image.src = source;
image.addEventListener( "load", function() {
videoElem.appendChild( image );
});
videoElem.addEventListener( "click", function() {
var iframe = document.createElement( "iframe" );
iframe.setAttribute( "frameborder", "0" );
iframe.setAttribute( "allowfullscreen", "" );
iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ embedID +"?rel=0&showinfo=0&autoplay=1" );
this.innerHTML = "";
this.appendChild( iframe );
} );
};
该函数执行与上一教程中添加的代码相同的行,尽管进行了一些调整。 该功能将显示Youtube视频图像缩略图,并在用户单击时将Youtube视频附加到包装元素.youtube 。
用
在本教程中,我们将上一教程中的代码包装到Web组件中。 现在,我们可以使用新的自定义元素<youtube-embed>更加优雅地嵌入YouTube视频,例如:
<youtube-embed embed="AqcjdkPMPJA"></youtube-embed>
所有代码(JavaScript,CSS,HTML)都封装在单独HTML中,以防止该文件中的潜在错误破坏整个站点。 每当需要在其他项目中重用它时,我们就继续导入HTML youtube-embed.html 。
结语
这只是我们如何使用Web组件的一个示例。 您可以在customelements.io上找到Web组件的更多出色实现。 最后,我希望您喜欢本教程并找到易于理解的参考。
更多资源
- WebComponents.org一个讨论和发展Web组件最佳实践的地方
- 如何使用Web组件创建自己HTML元素
- 自定义元素:探索Web组件的世界
- 一年构建Web组件的实用课程 Google I / O 2016
- 聚合物:使Web组件可访问
1483

被折叠的 条评论
为什么被折叠?



