如何定位 "hidden" iframe? (应用:链接到 "poster image hidden" 嵌入的 Youtube 视频的起始位置)

How to target "hidden" iframes? (application: links to starting positions of a "poster image hidden"-embedded Youtube video)

Meta: 关于本地存储的 A/V 文件的类似问题可以在这里找到:.


亲爱的 Whosebug 社区的人们,

申请

我有一个 iframe <iframe name="video"..。被命名为video,被视为某个视频的"main player"。

由于我还无法获得该视频的交互式文字记录,因此我在视频中调用了不同的 playing/starting 位置:<a href="//www.youtube.com/embed/...&start=60" target="video">1:00</a>,例如第二个 60.

这在 <iframe name="video".. 已经是 "active" 时工作正常:然后 link 移动视频在 iframe 中的播放位置。这太棒了!

然而 not 工作正常,当 <iframe name="video".. 还不是 "active" 时,情况就是这样:那么 link 然后在不同的浏览器选项卡中打开,而不是在 iframe 内部(或 iframe 应该显示的位置)。

隐藏是什么意思

我所说的 iframe 不是 "active" 的意思如下:通过以下代码在 "poster image" 后面 "hidden":

<div onclick="play();" id="vid" style="...; background: ... url('...poster.image.url...') no-repeat center;-webkit-background-size: cover; ...;overflow:hidden"></div>

<script type="text/javascript">function play(){document.getElementById('vid').innerHTML = '<iframe name="video" ... src="//www.youtube.com/embed/...?&...start=0"></iframe>';}</script>


换句话说:我特别想要“<a target="_blank"”行为。我猜 target="video" 现在不能正常工作,因为 iframe 在海报图片后面 "hidden"。

我确信当 iframe 根本不被隐藏时不会发生这种行为。我对此进行了多次测试。此外,使用当前的 "hidden" 海报功能,当首先单击海报图像时(在单击 <a href="...></a> 之前)也不会发生此行为。

如果您想亲眼看到这种行为,可以在我的 site 上看到。最好是look/CTRL-F for "stef",然后打开▾̲ ̲u̲n̲d̲e̲r̲l̲i̲n̲e̲d̲ ̲t̲o̲g̲g̲l̲e̲,你会在那里找到。

那么如何在不打开新浏览器的情况下成功 "target" "hidden" iframe window/tab?

如有任何帮助,我们将不胜感激。非常感谢,Vincent Verheyen。

我们到了! fiddle.

HTML

您的 html 将包含立面和跳线来完成您的要求。

什么是立面?

facade: "the principal front of a building, that faces on to a street or open space."

这将是您播放视频或点击任何跳线之前显示的图像,html 将如下所示:

<div class="videoFacade" data-name="video1" data-video="ByJFdTFEwF4" data-start="8">
    <img src="http://i.imgur.com/xeUiWGn.png" />
</div>

什么是跳线?

跳线是一个锚点,它将 iframe 的 url 更新到视频中所需的时间,它看起来像这样:

JavaScript

window.addEventListener("load", initVideoFacade);

function initVideoFacade() {
    var allFacades = document.querySelectorAll(".videoFacade");
    for (var i = 0; i < allFacades.length; i++) {
        var facade = allFacades[i];
        setUpFacade(facade);
    }

    var allJumpers = document.querySelectorAll(".videoJumper");
    for (var i = 0; i < allJumpers.length; i++) {
        var jumper = allJumpers[i];
        setUpJumper(jumper);
    }
}

function setUpJumper(jumper) {
    jumper.addEventListener("click", function (e) {
        e.preventDefault();
        jumpTo(jumper);
        var video = jumper.dataset.video;
        var facade = getFacadeByVideo(video);
        if (facade) playVideo(facade);
        return false;
    });
}

function setUpFacade(facade) {
    facade.addEventListener("click", function () {
        playVideo(facade);
    });
}

function getFacadeByVideo(video) {
    return document.querySelector(".videoFacade[data-name=" + video + "]");
}

function getIframeByVideo(video) {
    return document.querySelector(".videoIframe[data-name=" + video + "]");
}

function updateVideoSource(iframe, start, end) {
    var iframeSrc = iframe.src.replace(/start=[0-9]+/i, "start=" + start);
    var hasEnd = iframeSrc.indexOf("end") != -1;
    if (hasEnd) iframeSrc = iframeSrc.replace(/end=[0-9]+/i, "end=" + end);
    else iframeSrc += "&end=" + end;
    return iframeSrc;
}

function updateFacadeData(facade, start, end) {
    facade.setAttribute("data-start", start);
    facade.setAttribute("data-end", end);
}

function jumpTo(jumper) {
    var start = jumper.dataset.start;
    var end = jumper.dataset.end;
    var video = jumper.dataset.video;
    var iframe = getIframeByVideo(video);
    if (iframe) {
        var iframeSrc = updateVideoSource(iframe, start, end);
        iframe.src = iframeSrc;
    } else {
        var facade = getFacadeByVideo(video);
        updateFacadeData(facade, start, end);
    }
}

function playVideo(facade) {
    var start = facade.dataset.start || 0;
    var end = facade.dataset.end;
    var name = facade.dataset.name;
    var video = facade.dataset.video;
    var iframe = document.createElement("iframe");
    iframe.dataset.name = name;
    iframe.className = "videoIframe";
    var iframeSrc = "http://www.youtube.com/embed/" + video + "?&cc_load_policy=1&modestbranding=1&autoplay=1&rel=0&showinfo=0&theme=light&start=" + start;
    if (end) iframeSrc += "&end=" + end;
    iframe.src = iframeSrc;
    iframe.frameBorder = 0;
    replaceNode(facade, iframe);
}

function replaceNode(node1, node2) {
    var parent = node1.parentNode;
    var next = node1.nextSibling;
    parent.insertBefore(node2, next);
    parent.removeChild(node1);
}

这是一个时间表:

  • 我们将initVideoFacade()方法添加到页面的加载事件中,这将确保我们所有的门面和跳线都已启动并且运行在做任何事情之前。

  • initVideoFacade()方法会找到所有跳线和门面,并使用setUpFacade()setUpJumper()方法进行设置。

  • setUpJumper() 方法会在跳线上添加一个click event 并告诉它跳转到视频中的确定时间,在跳线中指定。此外,如果视频尚未播放,现在会播放。

  • jumpTo() 方法将更新 iframe 的 src(如果视频未播放则为门面初始数据)使用一对 regular expressions 替换 &start=&end= iframe src 的部分。

  • setUpFacade() 方法将简单地播放视频,移除外观并插入 iframe。

  • playVideo() 方法将从外观创建一个新的 iframe,替换它并将它的源、开始和结束时间分配给视频。

CSS

这只是处理外观和 iframe 的样式:)

.videoFacade, .videoIframe {
    position: relative;
    width: 360px;
    height: 202.5px;
    margin:5px;
}
.videoFacade {
    cursor: pointer;
    border:1px solid black;
}
.videoFacade img {
    position: absolute;
    width: 50px;
    height: 50px;
    left: 50%;
    top: 50%;
    margin: -25px 0 0 -25px;
}

希望对您有所帮助!