【问题标题】:Clicking HTML 5 Video element to play, pause video, breaks play button单击 HTML 5 视频元素播放、暂停视频、中断播放按钮
【发布时间】:2013-08-22 00:39:30
【问题描述】:

我正在尝试让视频能够像 YouTube 一样播放和暂停(同时使用播放和暂停按钮,然后单击视频本身。)

<video width="600" height="409" id="videoPlayer" controls="controls">
 <!-- MP4 Video -->
 <source src="video.mp4" type="video/mp4">
</video>


<script>
    var videoPlayer = document.getElementById('videoPlayer');

    // Auto play, half volume.
    videoPlayer.play()
    videoPlayer.volume = 0.5;

    // Play / pause.
    videoPlayer.addEventListener('click', function () {
        if (videoPlayer.paused == false) {
            videoPlayer.pause();
            videoPlayer.firstChild.nodeValue = 'Play';
        } else {
            videoPlayer.play();
            videoPlayer.firstChild.nodeValue = 'Pause';
        }
    });
</script>

您知道为什么这会破坏播放和暂停控制按钮吗?

【问题讨论】:

  • 请记住,最新的 firefox 版本开箱即用地支持点击 &lt;video/&gt; 标签时暂停/播放视频。
  • 您不需要添加控件,它是标签本身的一部分。

标签: html video youtube


【解决方案1】:

最简单的形式是使用onclick监听器:

<video height="auto" controls="controls" preload="none" onclick="this.play()">
 <source type="video/mp4" src="vid.mp4">
</video>

无需 jQuery 或复杂的 Javascript 代码。

播放/暂停可以通过onclick="this.paused ? this.play() : this.pause();"完成。

演示:

<video height="200" controls="controls" preload="none" onclick="this.play()">
 <source type="video/webm" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/5/54/Yawning_kitten.ogv/Yawning_kitten.ogv.480p.vp9.webm">
</video>

在 Chromium 89 上:

  • onclick="this.play()" 在初始播放 + 暂停(单击控件仍然有效)后单击主体(而不是控件)来防止视频再次播放,这通常是不可取的。这大概是因为回调让它播放,然后事件传播并且浏览器立即重新暂停它。
  • 没有onclick="this.play()" 的默认行为将是:初始主体单击以在主体上播放不起作用,但在初始播放后单击主体可切换播放/暂停
  • onclick="this.paused ? this.play() : this.pause();" 在初始播放后使身体点击既不能播放也不能暂停,大概类似于 onclick="this.play()" 发生的情况

【讨论】:

  • 这个答案应该被认为是正确的,因为它是最简单的并且不会破坏控件的行为。
  • 将此与约翰答案中的this.paused?this.play():this.pause() 逻辑结合起来,您就有了赢家。
  • 这在 Safari 中不起作用,至少如果您有海报图像。不确定是否没有海报图片是否可行。
【解决方案2】:

HTML:

<video class="video"><source src=""></video>

JAVASCRIPT:“JQUERY”

$('.video').click(function(){this.paused?this.play():this.pause();});

【讨论】:

  • 这在 Firefox、Chrome 和 Safari 中非常适合我。除了我用“video”替换了“div”。
  • 谢谢,很高兴帮助了其他人。此外,很好的收获。你是对的,它应该是“视频”而不是“div”。我的错。
  • 除非我添加了return false;,否则它在 Android 版 Chrome 35 中不起作用
【解决方案3】:

添加 return false; 对我有用:

jQuery 版本:

$(document).on('click', '#video-id', function (e) {
    var video = $(this).get(0);
    if (video.paused === false) {
        video.pause();
    } else {
        video.play();
    }

    return false;
});

原生 JavaScript 版本:

var v = document.getElementById('videoid');
v.addEventListener(
    'play', 
    function() { 
        v.play();
    }, 
    false);

v.onclick = function() {
    if (v.paused) {
        v.play();
    } else {
        v.pause();
    }

    return false;
};

【讨论】:

  • 这对我有用,只是全屏按钮停止工作...... :(为什么?
  • ios-lizard 您使用的是 jQuery 还是 Vanilla JavaScript 版本。全屏按钮在我当前的实现中使用上述 jQuery 版本的代码。
  • 我使用的是 jQuery 2.1.0
  • jQuery 代码对我有用,但在 iPad 上除外。我将$(document).on('click', 'video',... 更改为$('video').on('click',...,奇怪的是它也开始在iPad 上工作。
【解决方案4】:

我在这样做时遇到了无数问题,但最终想出了一个可行的解决方案。

基本上,下面的代码是向视频添加一个点击处理程序,但忽略下部的所有点击(0.82 是任意的,但似乎适用于所有尺寸)。

    $("video").click(function(e){

        // get click position 
        var clickY = (e.pageY - $(this).offset().top);
        var height = parseFloat( $(this).height() );

        // avoids interference with controls
        if(y > 0.82*height) return;

        // toggles play / pause
        this.paused ? this.play() : this.pause();

    });

【讨论】:

  • 你要么是天才,要么是疯子,我分不清。
【解决方案5】:

我遇到了同样的问题,并通过在单击操作之外添加播放操作的事件处理程序来解决它。我在播放时隐藏控件以避免暂停按钮问题。

    var v = document.getElementById('videoID');
    v.addEventListener(
       'play', 
          function() { 
             v.play();
          }, 
        false);

    v.onclick = function() {
      if (v.paused) {
        v.play();
        v.controls=null;
      } else {
        v.pause();
        v.controls="controls";
      }
    };

虽然搜索仍然很有趣,但至少播放控制的混乱已经消失了。希望这会有所帮助。

谁有办法解决这个问题?

【讨论】:

    【解决方案6】:

    跟进 ios-lizard 的想法:

    我发现视频上的控件大约是 35 像素。这就是我所做的:

    $(this).on("click", function(event) {
        console.log("clicked");
        var offset = $(this).offset();
        var height = $(this).height();
        var y = (event.pageY - offset.top - height) * -1;
        if (y > 35) {
            this.paused ? this.play() : this.pause();
        }
    });
    

    基本上,它会找到点击相对于元素的位置。我将它乘以 -1 以使其为正。如果该值大于 35(控件的高度),则意味着用户单击了控件以外的其他位置因此我们暂停或播放视频。

    【讨论】:

      【解决方案7】:

      这个怎么样

      <video class="play-video" muted onclick="this.paused?this.play():this.pause();">
         <source src="" type="video/mp4">
      </video>
      

      【讨论】:

        【解决方案8】:

        在 Chromium 89 和 Firefox 86 上点击正文作品,除了第一次点击 preload="none" 对于 Chromium

        在这些浏览器中:

        • Firefox 完美运行:对视频正文的所有点击切换播放/暂停,就像对控件的相应点击一样。此外,它还显示了一个直观的占位符,让用户清楚地知道点击会起作用:

        • Chromium 有一个错误,即第一次点击无视频正文不适用于具有preload="none" 的视频。然而,进一步的点击工作。

          并且它的占位符并没有明确表明您可以在任何地方点击播放(无论如何您都不能,希望他们会在错误得到修复时添加一个不错的占位符):

        因此,最好的选择是通过仅在第一次点击时播放来最小化地解决该错误:

        <!doctype html>
        <html lang=en>
        <head>
        <meta charset=utf-8>
        <title>Min</title>
        </head>
        <body>
        <video id="vid" height="200" controls="controls" preload="none">
         <source type="video/webm" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/5/54/Yawning_kitten.ogv/Yawning_kitten.ogv.480p.vp9.webm">
        </video>
        <script>
        let first = true;
        document.getElementById('vid').addEventListener('click', (e) => {
          if (first) {
            e.target.play();
          }
          first = false;
        });
        </script>
        </body>
        </html>
        

        这也不会以任何方式破坏 Firefox 的正确行为。

        TODO:通过添加一个清晰地表明初始点击播放将起作用的叠加 div,使该解决方法变得完美,例如类似于:https://codepen.io/wizaRd_Mockingjay/pen/NVGpep,但保留控件。

        JavaScript 解决方案显示在:onclick="this.play()"https://stackoverflow.com/a/35563612/895245 实际上会在第一次播放后中断播放 + 暂停在这些浏览器上工作,所以我不推荐它。

        我的邪恶部分想认为 Chromium 的行为更糟​​糕,因为 YouTube 视频是唯一对他们重要的视频 >:-)

        【讨论】:

          【解决方案9】:

          问题似乎是&lt;video&gt; 元素内的内部冒泡......所以当您点击“播放”按钮时,代码触发,然后播放按钮本身被触发:(

          我找不到一个简单(可靠)的方法来阻止点击冒泡(逻辑告诉我应该有一种方法,但是......它现在让我逃脱了)

          无论如何,我找到的解决方案是在视频上放置一个透明的&lt;div&gt;,其大小适合控件出现的位置...因此,如果您单击 div,则您的脚本控制播放/暂停,但如果用户自己点击控件,然后&lt;video&gt; 元素会为您处理。

          下面的示例是针对我的视频调整大小的,因此您可能需要调整相对 &lt;div&gt;s 的大小,但它应该可以帮助您入门

          <div id="vOverlay" style="position:relative; width:600px; height:300px; z-index:2;"></div>
          <video style="position:relative; top:-300px; z-index:1;width:600px;height:340px;" width="600" height="409" id=videoPlayer controls="controls">
          <source src="video.mp4" type="video/mp4">
          </video>
          
          <script>
              var v = document.getElementById('videoPlayer');
              var vv = document.getElementById('vOverlay');
              <!-- Auto play, Half volume -->
              v.play()
              v.volume = 0.5;
              v.firstChild.nodeValue = "Play";
          
              <!-- Play, Pause -->
              vv.addEventListener('click',function(e){
                  if (!v.paused) {
                      console.log("pause playback");
                      v.pause();
                      v.firstChild.nodeValue = 'Pause';
                  } else {
                      console.log("start playback")
                      v.play();
                      v.firstChild.nodeValue = 'Play';
                  }
                });
          </script>
          

          【讨论】:

            【解决方案10】:

            必须分开这段代码才能正常工作,否则一键暂停和播放!

             $('video').click(function(){this.played ? this.pause() ;});
              $('video').click(function(){this.paused ? this.play() ;});
            

            【讨论】:

              猜你喜欢
              • 2013-06-16
              • 1970-01-01
              • 2014-08-30
              • 1970-01-01
              • 2011-06-06
              • 1970-01-01
              • 2014-03-05
              • 1970-01-01
              相关资源
              最近更新 更多