指针事件为null的元素“单击”(或替代方法)

时间:2019-03-10 15:00:32

标签: javascript jquery html css iframe

我已经将iframe嵌入到我的网站中,并且想要在其顶部放置一个叠加层。我的最终目标是在youtube视频的顶部放置一个叠加层和文本,当我播放视频时会消失,而在暂停视频时会重新出现。

我希望能够在iframe包装器上切换视频播放类,然后根据父级是否有该类显示和隐藏重叠式广告。

我将叠加层放置在iframe的顶部,并在叠加层上添加了pointer-events:none,以便当我将鼠标悬停在叠加层上时,叠加层本身会被忽略,我仍然可以点击并播放iframe youtube位于其下方的视频。

我的问题是我需要注册一个在播放和暂停iframe时运行的功能,但我不能这样做

  1. 带有pointer-events:none的叠加层使我无法在iframe上注册onclick。
  2. 我无法在叠加层本身上注册onclick,因为我需要能够单击位于其下方的youtube视频,因此需要pointer-events:none

是否有任何方法可以使叠加层上具有与pointer-events:none等效的功能,但仍然能够注册侦听器并单击位于其下方的元素上的事件?

1 个答案:

答案 0 :(得分:2)

也许您可以使用实际的官方youtube iframe API来代替通过用户是否点击覆盖图来猜测播放状态(这可能会导致错误,例如单击音量或全屏按钮)。它包含许多功能,而您可能最感兴趣的功能是onStateChange event。通过附加到它,您可以可靠地检查播放器是在播放还是在暂停(或处于“缓冲”之类的任何其他状态)。根据API文档和您的要求,我创建了一个codepen,其中包含一个随播放状态而变化的覆盖图。

PS。由于某些原因,由于Failed to execute ‘postMessage’ on ‘DOMWindow’错误,嵌入式stackoverflow片段无法嵌入youtube iframe,但是出于完整性考虑,我还是在下面发布了代码。有关有效的演示,请参见上面链接的codepen。

var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        height: '390',
        width: '640',
        videoId: 'M7lc1UVf-VE',
        events: {
'onStateChange': onPlayerStateChange
        }
    });
}

let overlay = document.querySelector('.overlay');

function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
      overlay.classList.remove("paused");
      overlay.classList.add("playing");
    }
    if (event.data == YT.PlayerState.PAUSED) {
      overlay.classList.add("paused");
      overlay.classList.remove("playing");
    }
}
.wrapper {
  position: relative;
  display: inline-block;
}
.overlay {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  pointer-events:none;
}
.playing:before {
  position: absolute;
  content:"";
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  opacity: 0.3;
  background-color: green;
}
.playing:after{
  content: "playing";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: white;
  text-shadow: #000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px,
             #000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px;
}

.paused:before {
  position: absolute;
  content: "";
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  opacity: 0.3;
  background-color: orange;
}

.paused:after{
  content: "paused";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: white;
  text-shadow: #000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px,
             #000 0px 0px 1px,   #000 0px 0px 1px,   #000 0px 0px 1px;
}
<div class="wrapper">
  <div id="player"></div>
  <div class="overlay"></div>
</div>

更新

如果从CMS添加了iframe,您仍然可以使用youtube API方法并将其附加到现有的iframe元素上,例如此codepen中的显示。基本上,您只向YT.Player构造函数提供事件定义(而不是提供整个videoID,高度,宽度等参数列表):

player = new YT.Player('player', {
    events: {
        'onStateChange': onPlayerStateChange
    }
});