简体   繁体   English

使用 JS 媒体查询为移动/桌面加载不同的“视频”元素

[英]Loading different 'video' elements for mobile/desktop with JS media queries

I'm trying to load separate video elements depending if it is on mobile or desktop.我正在尝试加载单独的视频元素,具体取决于它是在移动设备上还是桌面上。 So i'm deleting the unnecessary element and replacing video-src with src on the element i'm keeping using JS and media queries as shown below.所以我要删除不必要的元素,并在我使用 JS 和媒体查询的元素上用 src 替换 video-src,如下所示。 This code works but it seems the video doesn't get initiated if you replace the src like this?此代码有效,但如果您像这样替换 src,似乎视频不会启动? Im just seeing a white square even though the video element is there and all correct and should be working.即使视频元素在那里并且一切正确并且应该可以正常工作,我也只是看到一个白色方块。 Can someone explain why you can't do this and or if i can make it work somehow?有人可以解释为什么你不能这样做,或者我是否可以让它以某种方式工作?

<video desktop class="i-delete-this-on-mobile" width="100%" height="100%" muted playsinline loop autoplay>
    <source type="video/mp4"
        video-src="https://player.vimeo.com/external/36742.hd.mp4?s=55921529d3beb0cd8f4a58c85e010f7de&profile_id=174">
</video>


<video mobile class="i-delete-this-on-desktop" width="100%" height="100%" muted playsinline loop autoplay>
    <source type="video/mp4"
        video-src="https://player.vimeo.com/external/365742.hd.mp4?s=55921529d3beb0cbddf8f4e010f7de&profile_id=174">
</video>

<script>
    document.addEventListener("DOMContentLoaded", function () {

        var desktopvideoEl = document.querySelectorAll('.i-delete-this-on-mobile');
        var mobilevideoEl = document.querySelectorAll('.i-delete-this-on-desktop');

        function displayImages(mobileSize2) {
            if (mobileSize2.matches) { // if mobile
                for (var i = 0; i < desktopvideoEl.length; i++) { //for each desktop video element
                    desktopvideoEl[i].parentNode.removeChild(desktopvideoEl[i]); // remove desktop video element
                    if (mobilevideoEl[i].children[0].getAttribute('video-src')) { //if mobile video element contains a child of video-src
                        mobilevideoEl[i].children[0].setAttribute('src', mobilevideoEl[i].children[0].getAttribute('video-src')); //change mobile source video-src element to src 
                        mobilevideoEl[i].children[0].removeAttribute('video-src'); //remove old video-src tag
                    }
                }
            } else { //if desktop
                for (var i = 0; i < mobilevideoEl.length; i++) { //for each mobilevideo element
                    mobilevideoEl[i].parentNode.removeChild(mobilevideoEl[i]); // remove mobile video element
                    if (desktopvideoEl[i].children[0].getAttribute('video-src')) { //if desktop video element contains a child of video-src
                        desktopvideoEl[i].children[0].setAttribute('src', desktopvideoEl[i].children[0].getAttribute('video-src')); // change desktop source video-src to src
                        desktopvideoEl[i].children[0].removeAttribute('video-src'); //remove old video-src tag
                    }
                }
            }
        }

        //js media query
        var mobileSize2 = window.matchMedia("(max-width: 767px)");

        //run function at runtime
        displayImages(mobileSize2);
    });
</script>

Do video elements only get loaded when the page is first parsed?是否仅在第一次解析页面时才加载视频元素? Because when I manually move the new video element anywhere in the dom using the chrome dev tools it instantly shows.因为当我使用 chrome 开发工具手动将新视频元素移动到 dom 中的任何位置时,它会立即显示。 Is there a way to replicate that movement with code so it 'refreshes' the video element?有没有办法用代码复制该运动,以便“刷新”视频元素?

When you set or change the src attribute of a <source> element, you need to call its parent MediaElement's .load() method so that this latter re-inspects the source.当您设置或更改<source>元素的src属性时,您需要调用其父 MediaElement 的.load()方法,以便后者重新检查源。

 window.onload = (e) => { const url = "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/a4/BBH_gravitational_lensing_of_gw150914.webm/BBH_gravitational_lensing_of_gw150914.webm.480p.webm"; // set both <source> element's src const sources = document.querySelectorAll( 'source' ); sources.forEach( (source) => source.src = url ); // call.load() only on the second <video> document.querySelector( '.reload-me' ).load(); };
 <div> Without load()<br> <video controls> <source> </video> </div> <div> With load()<br> <video controls class="reload-me"> <source> </video> </div>

yes you can.是的你可以。 this pushes the video element above the empty element that we make at the top.这会将视频元素推到我们在顶部制作的空元素之上。 this then reloads and makes the video show somehow.然后重新加载并以某种方式显示视频。 If someone could explain why this is necessary I would greatly appreciate.如果有人能解释为什么这是必要的,我将不胜感激。

<video class="i-delete-this-on-mobile" width="100%" height="100%" muted playsinline loop autoplay>
    <source type="video/mp4"
        video-src="https://player.vimeo.com/external/365229742.hd.mp4?s=55921529d3beb0cb372df8f919a58c85e010f7de&profile_id=174">
</video>


<video class="i-delete-this-on-desktop" width="100%" height="100%" muted playsinline loop autoplay>
    <source type="video/mp4"
        video-src="https://player.vimeo.com/external/365229742.hd.mp4?s=55921529d3beb0cb372df8f919a58c85e010f7de&profile_id=174">
</video>


<script>
    document.addEventListener("DOMContentLoaded", function () {

        var desktopvideoEl = document.querySelectorAll('.i-delete-this-on-mobile');
        var mobilevideoEl = document.querySelectorAll('.i-delete-this-on-desktop');

        function displayImages(mobileSize2) {
            if (mobileSize2.matches) { // if mobile
                for (var i = 0; i < desktopvideoEl.length; i++) { //for each desktop video element
                    desktopvideoEl[i].parentNode.removeChild(desktopvideoEl[i]); // remove desktop video element
                    if (mobilevideoEl[i].children[0].getAttribute('video-src')) { //if mobile video element contains a child of video-src
                        mobilevideoEl[i].children[0].setAttribute('src', mobilevideoEl[i].children[0].getAttribute('video-src')); //change mobile source video-src element to src 
                        mobilevideoEl[i].children[0].removeAttribute('video-src'); //remove old video-src tag
                        if(mobilevideoEl[i].previousElementSibling){mobilevideoEl[i].parentNode.insertBefore(mobilevideoEl[i], mobilevideoEl[i].previousElementSibling)};//THIS MOVES ELEMENT ABOVE THE EMPTY DIV AND RELOADS THE VIDEO ELEMENT
                    }
                }
            } else { //if desktop
                for (var i = 0; i < mobilevideoEl.length; i++) { //for each mobilevideo element
                    mobilevideoEl[i].parentNode.removeChild(mobilevideoEl[i]); // remove mobile video element
                    if (desktopvideoEl[i].children[0].getAttribute('video-src')) { //if desktop video element contains a child of video-src
                        desktopvideoEl[i].children[0].setAttribute('src', desktopvideoEl[i].children[0].getAttribute('video-src')); // change desktop source video-src to src
                        desktopvideoEl[i].children[0].removeAttribute('video-src'); //remove old video-src tag
                        if(desktopvideoEl[i].previousElementSibling){desktopvideoEl[i].parentNode.insertBefore(desktopvideoEl[i], desktopvideoEl[i].previousElementSibling)};//reloads desktop element
                    }
                }
            }
        }

        //window.addEventListener("resize", displayImages);

        //js media query
        var mobileSize2 = window.matchMedia("(max-width: 767px)");

        //run function at runtime
        displayImages(mobileSize2);
    });
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM