如何使用 Ref 触发 iframe youtube 视频播放按钮?

How to useRef to trigger a iframe youtube video play button?

提问人:May W. 提问时间:11/17/2022 更新时间:11/17/2022 访问量:766

问:

代码优先。

import React, { useRef } from 'react';

const VideoWithPlayButton: React.FC<Props> = () => {
  const playButton = useRef<HTMLDivElement>(null);
  const video = useRef<HTMLIFrameElement>(null);

  const playVideo = () => {
    if(video.current) {
      video.current.click();
    }
  }

  return (
    <div>
      <iframe ref={video} width="100%" height="100%" src={https://www.youtube.com/embed/_E2r2vOlqvA?controls=0&showinfo=0&autohide=1&autoplay=0&rel=0} title="YouTube video player" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
      <div>
        <div ref={playButton} onClick={playVideo}>
          <Image src={playButtonImg} alt="play"/>
        </div>
      </div>
    </div>
  );
};
export default VideoWithPlayButton;

为了用客户图标覆盖 YouTube 默认播放按钮(对不起 YouTube)

所以我用 onClick 事件设置了一个 div

然后获取 iframe DOM 元素,触发 click();

很确定我得到了 iframe 元素,但视频无法播放。

有可能吗?

或者我必须在单击按钮后创建带有自动播放功能的 iframe 元素?

reactjs dom iframe 点击 use-ref

评论


答:

0赞 Reinier68 11/17/2022 #1

好吧,碰巧我有一个组件可以做你想要的。加载 Iframe 可能需要一段时间(这对 SEO 不利)。这就是为什么我创建了一个组件,该组件仅加载中间带有 youtube 播放按钮的缩略图。当您单击缩略图时,将加载 Iframe。您可以选择任何您想要的svg作为默认播放按钮。svg

这是组件:

import { useRef } from 'react'

// thumbnailQuality: 'default' | 'hqdefault' | 'mqdefault' | 'sddefault'

export default function YouTubeFrame({ video, width, height }) {
  const divRef = useRef(null)

  const thumbnailQuality = 'sddefault'

  const onClick = () => {
    const iframe = document.createElement('iframe')
    iframe.setAttribute('frameborder', '0')
    iframe.setAttribute('allowfullscreen', '1')
    iframe.setAttribute(
      'allow',
      'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'
    )
    iframe.style.width = width ? width : '560px'
    iframe.style.height = height ? height : '315px'
    iframe.setAttribute('src', `https://www.youtube.com/embed/${video}?rel=0&showinfo=1&autoplay=1`)
    if (divRef.current) {
      divRef.current.innerHTML = ''
      divRef.current.appendChild(iframe)
    }
  }

  return (
    <div ref={divRef} className="relative">
      <span
        onClick={onClick}
        className="absolute left-1/2 top-1/2"
        style={{ transform: 'translate(-50%, -50%)' }}
      >
        <svg version="1.1" viewBox="0 0 68 48" width="60" height="60">
          <path
            d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z"
            fill="#f00"
          ></path>
          <path d="M 45,24 27,14 27,34" fill="#fff"></path>
        </svg>
      </span>
      <img
        onClick={onClick}
        loading="lazy"
        src={`https://img.youtube.com/vi/${video}/${thumbnailQuality}.jpg`}
        alt="YouTube Video Thumbnail"
        className="w-full object-cover object-center sm:h-[400px] lg:h-[360px] xl:h-[425px]"
      />
    </div>
  )
}

用法:

<YoutubeFrame video="eLLdfHcZRDY" /> //use the video id from the youtube url.