基于JS媒体查询为移动端/桌面端加载不同video元素的问题
Hey there, let's break down what's going on with your video loading issue and fix it step by step!
Why the video won't initialize after setting src dynamically
Browsers load video resources during the initial DOM parsing phase. When you set the src attribute after the DOM has finished loading (in your DOMContentLoaded handler), the browser doesn't automatically trigger a reload of the video resource—it already completed its initial check for that element.
As for why moving the video element in DevTools fixes it: dragging the element forces the browser to re-initialize the video component, which includes checking the new src attribute and loading the video file.
Fixes for your code
1. Trigger video reload manually
The simplest fix is to call the load() method on the video element after updating the src attribute. This tells the browser to re-fetch and initialize the video resource. Here's your updated script:
document.addEventListener("DOMContentLoaded", function () { const desktopVideos = document.querySelectorAll('.i-delete-this-on-mobile'); const mobileVideos = document.querySelectorAll('.i-delete-this-on-desktop'); function handleVideoDisplay(mobileQuery) { if (mobileQuery.matches) { // First set up mobile videos, then remove desktop ones mobileVideos.forEach(video => { const source = video.children[0]; if (source.hasAttribute('video-src')) { source.setAttribute('src', source.getAttribute('video-src')); source.removeAttribute('video-src'); // Force video to reload video.load(); } }); desktopVideos.forEach(video => video.remove()); } else { // First set up desktop videos, then remove mobile ones desktopVideos.forEach(video => { const source = video.children[0]; if (source.hasAttribute('video-src')) { source.setAttribute('src', source.getAttribute('video-src')); source.removeAttribute('video-src'); // Force video to reload video.load(); } }); mobileVideos.forEach(video => video.remove()); } } const mobileSizeQuery = window.matchMedia("(max-width: 767px)"); handleVideoDisplay(mobileSizeQuery); // Optional: Add listener for window resize mobileSizeQuery.addEventListener('change', handleVideoDisplay); });
I also adjusted the order of operations (set up the keepable videos first, then delete the others) to avoid potential index issues, and switched to forEach for cleaner code.
2. A more elegant responsive video approach (recommended)
You don't need to dynamically delete elements or use custom video-src attributes. Modern browsers will only load videos that are visible, so you can use CSS media queries to toggle display, and let the browser handle loading automatically:
<style> .desktop-video { display: block; } .mobile-video { display: none; } @media (max-width: 767px) { .desktop-video { display: none; } .mobile-video { display: block; } } </style> <video class="desktop-video" width="100%" height="100%" muted playsinline loop autoplay> <source type="video/mp4" src="https://player.vimeo.com/external/36742.hd.mp4?s=55921529d3beb0cd8f4a58c85e010f7de&profile_id=174"> </video> <video class="mobile-video" width="100%" height="100%" muted playsinline loop autoplay> <source type="video/mp4" src="https://player.vimeo.com/external/365742.hd.mp4?s=55921529d3beb0cbddf8f4e010f7de&profile_id=174"> </video>
This approach is cleaner, avoids DOM manipulation bugs, and automatically adapts when the window is resized.
Simulating the "move element" fix
If you ever need to replicate the DevTools element-move behavior programmatically, you can remove and reinsert the video element to trigger re-initialization:
// For a single video element const videoEl = document.querySelector('.your-video-class'); const parent = videoEl.parentNode; parent.removeChild(videoEl); parent.appendChild(videoEl);
That said, calling load() is more efficient and direct than this workaround.
内容的提问来源于stack exchange,提问作者AGrush

