javascript - 如何定位 "hidden"iframe? (应用程序: links to starting positions of a "poster image hidden"-embedded Youtube video)

标签 javascript onclick innerhtml target getelementbyid

元: 有关本地存储的 A/V 文件的类似问题可以在此处找到:Clickable "positioning" hyperlinks to A/V (locally stored on your website and “hidden” behind a poster image) .

<小时/>

亲爱的 Stackoverflow 社区的人们,

应用程序

我有一个 iframe <iframe name="video".. 。其名称为video ,并且被视为某个视频的“主要参与者”。

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

<iframe name="video".. 时,这工作正常。已经是“事件的”:那么链接会改变视频在 iframe 内的播放位置。这太棒了!

但是,当 <iframe name="video".. 时,它无法正常工作。尚未“事件”,情况就是这样:然后链接会在不同的浏览器选项卡中打开,而不是在 iframe 内(或 iframe 应该显示的位置)。

隐藏是什么意思

我的意思是 iframe 不处于“事件”状态:它通过以下代码“隐藏”在“海报图像”后面:

<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“隐藏”在海报图像后面。

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

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

那么如何在不打开新的浏览器窗口/选项卡的情况下成功“定位”“隐藏”iframe?

任何帮助将不胜感激。非常感谢,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>

    什么是毛衣?

跳线是一个 anchor ,它将把 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()方法将使用几个 regular expressions 更新 iframe 的 src (或外观初始数据,如果视频未播放)替换 &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;
}

希望对您有帮助!

关于javascript - 如何定位 "hidden"iframe? (应用程序: links to starting positions of a "poster image hidden"-embedded Youtube video),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28013991/

相关文章:

javascript - Reactjs - 如何根据成功的 axios POST 创建 bool 值?

javascript - 使用 npm 编译项目时出错

java - jTable swing获取输入问题

javascript - 无法使用innerhtml或选择节点,返回null

Javascript 改变内部 HTML

javascript - 将原型(prototype)添加到对象字面量中定义的对象构造函数

在 Chrome 扩展中加载沙盒 iframe 的 JavaScript 错误(localstorage、cookie)

javascript - 通过鼠标点击使用 webgl 创建一个圆

javascript - D3和鼠标事件,点击测试不起作用

javascript - 一般来说,在 javascript 中,使用innerHTML 不是一个安全问题吗?