如何在网格/列中创建响应式的YouTube嵌入(响应式IFrame)

4
问题:我需要一个响应式布局(最好是100%页面宽度),左侧放置一个嵌入式YouTube视频,右侧是缩略图网格。

我天真地认为iframes的行为与图片类似,并且它们会在宽度改变时自动调整iframe高度。

以下是我对问题布局中iframes的期望和想法: https://jsfiddle.net/5by8x44b/

但实际效果与期望不符:

https://jsfiddle.net/hfp8mhho/

最基本的代码形式(在jsfiddle中更具体)如下所示: (HTML)
<div style="border: 1px solid pink; overflow: hidden; padding:5%;">

    <div class="left_box" style="background-color:cyan;">
        <iframe src="https://www.youtube.com/embed/2ZR8Oc9hEnM" frameborder="0" allowfullscreen></iframe>
    </div>

    <div class="right_box">
       <!-- Image Grid Below -->
        <!-- 1st row */ -->
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
        <!-- 2nd row */ -->
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
        <!-- 3rd row */ -->
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
        <div class="grd_sqr"></div>
    </div>
</div>

(CSS)

.left_box {
    float: left;
    width: 65%;

}
.right_box {
    float:right;
    width: 35%;
}

iframe {
    width: 100%;
}

img {
    width:100%;
}

.grd_sqr {
    float:left;
    width: 30%;
    padding-bottom: 33%;
    margin:1.33%;
    background-color: #1E1E1E;
}

如果您不清楚差异,可以调整JSFiddle示例的结果窗口大小,问题就会变得清晰明了。

=========================================================

可能的解决方案:我找到了一些关于这个问题核心(响应式Iframes)的文章,其中最值得注意的是:

https://avexdesigns.com/responsive-youtube-embed/

https://benmarshall.me/responsive-iframes/

然而,我正在使用简单的左浮动/右浮动布局来创建两个主列,我怀疑这就是为什么上述链接中的解决方案无法解决我的问题的原因。
我已经做了几天了。有人能帮我解决一下吗?
1个回答

0
我为我的未来网站解决了这个问题。这是我的脚本,不知道你觉得怎么样。它应该适用于任何提供者(YouTube、Vimeo等),保留原始的纵横比,只要在更新页面后运行videoIframe_MakeResponsive('youtube','16/9'),就可以与任何附加的对象一起使用。如果没有指定宽度/高度,则'16/9'是默认的纵横比。我希望这有所帮助!视频将成为父元素的100%宽度。

// Greatest Common Divisor
function Math_gcd(a, b) {
    if (a<b)
        [a, b] = [b, a]
    return b ? Math_gcd(b, a%b) : a
}

// get ratio ('16/9' or something) from dimensions
function Math_ratio(width, height) {
    const gcd = Math_gcd(width, height)
    return width/gcd + '/' + height/gcd
}

// add multiple css properties
function css(element, jsonCSS) {
    for (const property in jsonCSS)
        element.style[property] = jsonCSS[property]
}

// autorun
function autorun(callback) {
    if (document.readyState != 'loading')
        callback()
    else
        document.addEventListener('DOMContentLoaded', callback)
}

// responsive iframe
function videoIframe_MakeResponsive(provider, defaultRatio = '16/9') {
    document.querySelectorAll('iframe[src*="' + provider + '"]').forEach(iframe => {
        if (!iframe.classList.contains('videoIframeFixed')) { // fix only new iframes
            let width = iframe.getAttribute('width')
            let height = iframe.getAttribute('height')
            let aspectratio = (width && height) ? Math_ratio(width, height) : defaultRatio
            iframe.removeAttribute('width') // reset
            iframe.removeAttribute('height') // reset
            iframe.classList.add('videoIframeFixed') // for future reference
            // wrapper container
            let wrapper = document.createElement('div')
            iframe.parentNode.insertBefore(wrapper, iframe)
            wrapper.appendChild(iframe) // move iframe inside
            // style
            css(wrapper, {
                'width': '100%',
                'position': 'relative',
                'aspect-ratio': aspectratio
            })
            css(iframe, {
                'width': '100%',
                'height': '100%',
                'position': 'absolute'
            })
        }
    })
}

// run it on page load
autorun(function () {
    videoIframe_MakeResponsive('youtube')
    videoIframe_MakeResponsive('vimeo')
    /* ... etc ... */
})


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接