首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么视频标签不加载在这个视频播放器网络组件中?

为什么视频标签不加载在这个视频播放器网络组件中?
EN

Stack Overflow用户
提问于 2022-02-24 02:04:25
回答 2查看 117关注 0票数 2

我正在尝试构建一个视频播放器Web组件,但我似乎无法正确地呈现videosource元素。

代码语言:javascript
复制
customElements.define('video-player',
  class extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById('video-player-template').content;
      console.log(template)
      const shadowRoot = this.attachShadow({mode: 'open'});
      shadowRoot.appendChild(template.cloneNode(true));
    }
  }
);
代码语言:javascript
复制
<template id="video-player-template">
    <video controls width="720" height="380" muted autoplay>
        <slot name="video-src" />
    </video>
    <slot></slot>
</template>


<video-player>
    <h1>Video player web component</h1>
    <source slot="video-src" src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" type="video/webm" />
</video-player>

为什么video元素不呈现?

EN

回答 2

Stack Overflow用户

发布于 2022-02-24 17:12:37

请参阅文档:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video

<video>想要一个<source>元素作为立即子元素,

因此,您不能在那里使用<slot>

( <table>也是如此,它不能拥有<slot>)

src组件中提取<video-player src="...">

然后创建,即<source>标记。

我为完整的示例添加了所有shadowDOM样式选项

代码语言:javascript
复制
customElements.define('video-player',
  class extends HTMLElement {
    constructor() {
      super()
        .attachShadow({mode:'open'})
        .append(document.getElementById(this.nodeName).content.cloneNode(true));
    }
    connectedCallback() {
      let src = this.getAttribute("source");
      let ext = src.split(".").slice(-1)[0];
      this.shadowRoot
          .querySelector("video")
          .innerHTML = `<source src="${src}" type="video/${ext}">`;
    }
  }
);
代码语言:javascript
复制
<video-player source="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm">
  <span slot="title">A beautiful video</span>
  <div class="desc">My video description</div>
</video-player>
<video-player source="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm">
  <span slot="title">Another beautiful video</span>
  <div class="desc">And more description</div>
</video-player>

<template id="VIDEO-PLAYER">
  <style>
    :host { display:inline-block }
    h1 { margin:0px;background:var(--bgcolor,green);text-align:center }
  </style>
  <div part="videoContainer">
    <h1><slot name="title"></slot></h1>
    <video controls width="100%" muted></video>
    <div><slot><!-- all non-slot labeled content goes here --></slot></div>
  </div>
</template>

<style>
  video-player {
    font: 10px Arial; /* Inheritable styles style shadowDOM */
    width: 240px;
    --bgcolor: gold; /* CSS properties can style shadowDOM */
  }
  .desc { /* container/global CSS styles slotted content!!!!  */
    width: 100%;
    background: beige;
  }
  ::part(videoContainer){ /* shadowParts style all usages in shadowDOM */
    border: 5px solid grey;
  }
</style>

ShadowDOM的样式如下:

票数 2
EN

Stack Overflow用户

发布于 2022-02-24 17:57:09

使用observedAttributes提取设置值的方法略有不同.

逻辑是这样的:

  • 创建基本的<template id="video-player-template"> </template>标记
  • 每次都将组件作为<video-player>标记重用。
  • 视频标记值是从<video-player>的标记设置代码中提取的。
  • 动态创建<video>标记对象,并从<video-player>中提取值。

下面是一些可测试的代码:

代码语言:javascript
复制
<html>
<head>
<style>

</style>
</head>
<body>

<!-- 1) create template -->
<template id="video-player-template">

<slot></slot>

</template>

<!-- 2) test as Component -->
<!-- test Component #1 with video loop -->
<video-player id="vidplayer1" width="400" height="300" muted autoplay controls loop type="video/webm" 
src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" >
</video-player>

<!-- test Component #2  -->
<video-player id="vidplayer2" width="200" height="120" muted autoplay controls type="video/webm" 
src="https://www.w3schools.com/tags/movie.mp4" >
</video-player>

<!-- controller scripts -->

<script type="text/javascript">

/*
test files
> MP4:  https://www.w3schools.com/tags/movie.mp4
> WEBM: https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"
*/

var template;
var nodes;
var shadowRoot;

customElements.define(
    'video-player',
    class extends HTMLElement 
    {
        constructor() 
        {
            super();
            template = document.getElementById('video-player-template').content;

            console.log(template)

            shadowRoot = this.attachShadow({mode: 'open'});
            shadowRoot.appendChild(template.cloneNode(true));
        }
        
        //# get component attributes (from template tag setup)
        static get observedAttributes() 
        {
            //# extract values from video tag template to use in output video tag
            //# eg:  controls id width height muted loop autoplay ... etc
            return ['src', 'id', 'width', 'height', 'controls', 'muted', 'autoplay', 'loop'];
        }

        //# attribute change
        attributeChangedCallback(property, oldValue, newValue) 
        {
            if (oldValue === newValue) { return; }
            else { this[ property ] = newValue; }
        }

        //# connect component
        connectedCallback() 
        {

            //# component is ready to be accessed

            //# generate dynamic video tag
            let player_code = "";
            player_code += `<video `;

            if( `${ this.id }` != "undefined")
            { player_code += `id="${ this.id }" `}

            if( `${ this.width }` != "undefined")
            { player_code += `width="${ this.width }" `; }

            if( `${ this.height }` != "undefined")
            { player_code += `height="${ this.height }" `; }

            if( `${ this.controls }` != "undefined")
            { player_code += `controls `; }

            if( `${ this.muted }` != "undefined")
            { player_code += `muted `; }

            if( `${ this.autoplay }` != "undefined")
            { player_code += `autoplay `; }

            if( `${ this.loop }` != "undefined")
            { player_code += `loop `; }
            
            player_code += `<source src="${ this.src }" `;
            
            //# get TYPE for video ( because ".type" is a reserved keyword )
            if( String((`${ this.src }`).indexOf(".webm")) != -1)
            { player_code += `type="video/webm" `; }
            else if( String((`${ this.src }`).indexOf(".mp4")) != -1)
            { player_code += `type="video/mp4" `; }

            player_code += `/> </video> `;

            //# apply code of dynamic video tag (add to page)...
            this.innerHTML = player_code;
            
    }
});

</script>
</body>
</html>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71246216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档