问题
I am displaying a video via HTML tag <video>
. I want to supply a small and a large video depending on the resolution of the users screen. A small screen should then only download the small video. It is no longer possible to do this with the media attribute directly in HTML. The JavaScript solution based on matchMedia
I tried instead is not working.
I tried the following JavaScript code using matchMedia that I found in a video by Google (https://youtu.be/j5fYOYrsocs?t=356):
HTML:
<video>
</video>
JavaScript:
var mq = window.matchMedia('(min-width: 480px)');
if (mq.matches) {
video.src = 'http://techslides.com/demos/sample-videos/small.mp4';
}
else {
video.src = 'http://media.w3.org/2010/05/sintel/trailer.mp4';
}
This code only produces a blank page though. See this pen: https://codepen.io/blueslobster/pen/ROQjOv
回答1:
Offbeatmammal is correct in that it appears the OP has neglected to reference the video tag. In addition to a proper reference to said video, we should "listen" for changes to the viewport if we intend to adapt the video whenever the window is resized. Also, the videos in OP should be reversed, consider the following:
... const mQL = window.matchMedia("(min-width: 481px)");
The media query passed to the matchMedia() method means:
"Apply the following rules, expression, statement, etc. when the viewport width is 481px or greater"
So when this condition is TRUE
, the larger video should be loaded, otherwise the smaller video should be loaded:
if
mQL.matches
then assign larger video tovid.src
else assign smaller video tovid.src
Note: The first video (560x278) which matches the mQL
(min-width: 481px) ergo is TRUE
. The second video was changed from a huge video (854x438 which would also be true) to a video of appropriate size: (480x318). Also of note: the original media query was at 480px and changed to 481px because the best replacement video I have ATM has a natural width of 480px.
Further details are commented in Demo and Pen (the Demo in Full Page mode doesn't appear to work but it does in CodePen, drag the window below 481px width to see the magic)
Demo 1
Two videos using .addListener()
/*
Create a mediaQueryList Object (mQL)
https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList
*/
const mQL = window.matchMedia("(min-width: 481px)");
/*
Bind a listener to mQL -- triggers when window changes and calls vidSec callback function
https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener
*/
mQL.addListener(vidSrc);
/*
Call vidSrc() and pass mQL once to set the video src to the initial viewport. This insures
that the correct video is loaded should the viewport be less than 481px wide. Moreover
it's bad UX to start the page with an empty video tag.
*/
vidSrc(mQL);
/*
Callback function passes the mQL...
Reference the video tag...
Ternary: url is the result of [=]
if mQL .matches property* is [?]
equal to or greater than 481px [TRUE]
"http://techslides.com/demos/sample-videos/small.mp4"
[:] else [FALSE]
"https://html5demos.com/assets/dizzy.mp4"
Assign url to video .src property...
load() video
*/
/* [*] .matches Property:
https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/matches
*/
function vidSrc(mQL) {
const vid = document.querySelector("video");
let url = mQL.matches ? "http://techslides.com/demos/sample-videos/small.mp4" : "https://html5demos.com/assets/dizzy.mp4";
vid.src = url;
vid.load();
}
<video></video>
Demo 2
Pen
Three videos -- multiple mediaQueryLists in an array
const mQLs = [
window.matchMedia(`(max-width: 854px)`),
window.matchMedia(`(max-width: 481px)`)
];
function vidSrc(mQL) {
const vid = document.querySelector("video");
let url;
if (mQLs[0].matches) {
url = "http://techslides.com/demos/sample-videos/small.mp4";
}
if (mQLs[1].matches) {
url = "https://html5demos.com/assets/dizzy.mp4";
}
if (!mQLs[0].matches && !mQLs[1].matches) {
url = "http://media.w3.org/2010/05/sintel/trailer.mp4";
}
vid.src = url;
vid.load();
}
for (let i = 0; i < mQLs.length; i++) {
vidSrc(mQLs[i]);
}
<video></video>
回答2:
you can't reference the video simply as video
because in the javascript that variable hasn't been assigned to anything. If you define the element you want to change, then it should work:
<video id="vid"></video>
<script>
var mq = window.matchMedia('(min-width: 480px)');
var vid = document.getElementById("vid")
if (mq.matches) {
vid.src = 'http://techslides.com/demos/sample-videos/small.mp4';
} else {
vid.src = 'http://media.w3.org/2010/05/sintel/trailer.mp4';
}
</script>
Note that the assignment of vid
has to happen after the DOM is constructed, so either have the script after the HTML element, or only trigger at a point where you know the element has been created so it can be referenced (eg the body onloaded event for the page)
回答3:
You can simply use the width and height property of the window.screen object to get the resolution of the screen.
<video id="video"></video>
Try Using:
var video = document.getElementById("video");
if (window.screen.width > 480) {
//video source for resolution greater than 480p
video.src = 'http://techslides.com/demos/sample-videos/small.mp4';
}else {
//video source for resolution less than 480p
video.src = 'http://media.w3.org/2010/05/sintel/trailer.mp4';
}
来源:https://stackoverflow.com/questions/55730649/html-video-source-switching-via-javascript-matchmedia