【问题标题】:how to play/pause video in React without external library?如何在没有外部库的情况下在 React 中播放/暂停视频?
【发布时间】:2016-05-26 14:31:25
【问题描述】:

我的网页中有一个视频标签 (),还有一个“播放/暂停”按钮,当用户点击它时,视频开始/停止播放。如果我不允许使用 js 来调用“getElementById”然后使用 play()/pause() 内置方法,我该如何做出反应。 任何的想法?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    React 函数组件的更新示例:

    import React, { useRef} from 'react'
    
    function myComponent(props) {
      const vidRef = useRef(null);
      const handlePlayVideo = () => {
        vidRef.current.play();
      }
      return (
        <video ref={vidRef}>
          <source src={[YOUR_SOURCE]} type="video/mp4" />
        </video>
      )
    }
    
    
    

    【讨论】:

    • 非常感谢更新版本
    【解决方案2】:

    最直接的方法是使用refs,这是一个 React 功能,可以让您调用从render() 返回的组件实例上的方法。

    您可以在文档中详细了解它们:https://facebook.github.io/react/docs/more-about-refs.html

    在这种情况下,只需将 ref 字符串添加到您的 video 标记中,如下所示:

    <video ref="vidRef" src="some.mp4" type="video/mp4"></video>
    

    当您向按钮添加点击处理程序时:

    <button onClick={this.playVideo.bind(this)}>PLAY</button>
    

    playVideo 方法可以通过refs 访问您的视频参考:

    playVideo() {
      this.refs.vidRef.play();
    }
    

    这是一个有效的DEMO,因此您可以查看完整示例。

    【讨论】:

    • 酷。有任何选项可以从属于其他组件的按钮调用 playVideo() 吗?
    • 是的。您可以通过 props 将函数引用传递给任何子组件,就像任何父子方法一样。我更新了演示,为视频和按钮使用了两个单独的组件来说明。
    • 是的,但是如果两个类(按钮和视频)都是共同父类的子类怎么办?
    • 在 React 应用程序中保持单向数据流通常是非常的好习惯,因为它使此类情况(以及大多数其他情况)易于推理和处理。所以我的第一个建议是考虑重构。从技术上讲,您仍然可以使用refs 执行此操作,方法是为您的视频组件提供ref='videoComponent',然后将播放/暂停移动到共同父级并通过this.refs.videoComponent.refs.vidRef.play() / .pause() 调用这些方法。但正如你所看到的,这开始变得有点疯狂了。
    • @BradColthurst 我不确定我是否理解此案。是这个吗? &lt;Parent&gt;&lt;Video&gt;&lt;video/&gt;&lt;/Video&gt;&lt;Buttons&gt;&lt;button&gt;&lt;/Buttons&gt;&lt;/Parent&gt; 然后,您可以在Parent 组件中使用this.vidRef = React.createRef()。通过道具将其传递给Video。通过ref 属性将其附加到Videorender 方法中的video 元素。并将ParentonButtonClick 方法通过props 传递给Buttons 组件,将其附加到button 以获取click 事件(通过onClick attr)。然后在ParentonButtonClick 方法中我们可以做this.vidRef.play()。我错过了什么吗?
    【解决方案3】:

    如果您想使用 ES6

    ,则接受的答案是使用旧的反应样式

    一个简单的组件,用于自动播放暂停以及手动控制播放 Polestar 简介:

        import React from "react";
        class Video extends React.Component {
          componentDidMount = () => {
            this.playVideo();
          };
    
          componentWillUnmount = () => {
              this.pauseVideo();
          };
    
    
          playVideo = () => {
            // You can use the play method as normal on your video ref
            this.refs.vidRef.play();
          };
    
          pauseVideo = () => {
            // Pause as well
            this.refs.vidRef.pause();
          };
    
          render = () => {
            return (
              <div>
                <video
                  ref="vidRef"
                  src="https://assets.polestar.com/video/test/polestar-1_09.mp4"
                  type="video/mp4"
                />
    
                <div>
                  <button onClick={this.playVideo}>
                    Play!
                  </button>
                  <button onClick={this.pauseVideo}>
                    Pause!
                  </button>
                </div>
              </div>
            );
          };
        }
    
     export default Video;
    

    来自https://www.polestar.com/cars/polestar-1的视频

    【讨论】:

      【解决方案4】:

      这个答案添加到@mheavers,我赞成。

      有一些区别:

      • 可以将noControls 作为prop 传递给Video 组件,并且仅当&lt;video&gt; 没有默认控件时才应用点击事件noControls已通过)
      • handler 函数是一个切换器;使一个人能够根据其当前状态播放或暂停。
      • 可以通过video__play-button 类创建播放按钮覆盖样式,而同一处理程序 通过is-playing 类将其隐藏。
      • 它还展示了如何使用两个或多个 ref 并将它们作为参数传递给纯渲染函数。
      import React, { useRef } from 'react';
      import PropTypes from 'prop-types';
      
      const renderVideo = ({
        noControls,
        src,
        vidButtonRef,
        vidRef,
        handleToggleVideo,
      }) => (
        <>
          {noControls ? (
            <div ref={vidButtonRef} className="video video__play-button">
              <video
                ref={vidRef}
                src={src}
                onClick={handleToggleVideo}
              ></video>
            </div>
          ) : (
            <video
              src={src}
              controls
              controlsList="nodownload"
            ></video>
          )}
        </>
      );
      
      const Video = props => {
        const vidRef = useRef(null);
        const vidButtonRef = useRef(null);
        const { noControls, src } = props;
        const handlePlay = () => {
          vidRef.current.play();
          // hide overlay play button styles, set by 'video__play-button'
          vidButtonRef.current.classList.add('is-playing');
        };
        const handlePause = () => {
          vidRef.current.pause();
          // show overlay play button styles, set by 'video__play-button'
          vidButtonRef.current.classList.remove('is-playing');
        };
        const handleToggleVideo = () => (vidRef.current.paused ? handlePlay() : handlePause());
        return (
          <>
            {renderVideo({
              noControls,
              src,
              vidButtonRef,
              vidRef,
              handleToggleVideo,
            })}
          </>
        );
      };
      
      Video.propTypes = {
        noControls: PropTypes.bool,
        videoUrl: PropTypes.string,
      };
      
      export default Video;
      

      【讨论】:

        【解决方案5】:

        使用 ref 属性创建指向视频的链接,并使用该引用我们可以在视频组件上使用视频控件

        试试这个代码,

        import React from "react";
        class VideoDemo extends React.Component {
          
          getVideo = elem => {
            this.video = elem
          }
        
          playVideo = () => {
            this.video.play()
          };
        
          pauseVideo = () => {
            this.video.pause();
          };
        
          render = () => {
            return (
              <div>
                <video
                  ref={this.getVideo}
                  src="http://techslides.com/demos/sample-videos/small.mp4"
                  type="video/mp4"
                />
        
                <div>
                  <button onClick={this.playVideo}>
                    Play!
                  </button>
                  <button onClick={this.pauseVideo}>
                    Pause!
                  </button>
                </div>
              </div>
            );
          };
        }
        
        export default VideoDemo;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-29
          • 1970-01-01
          • 2011-10-27
          • 2018-06-25
          • 1970-01-01
          • 2013-01-27
          相关资源
          最近更新 更多