nuxt-lazytube
Version:
A Nuxt module for lazy loading YouTube and Vimeo videos with lightweight iframes to improve page performance
121 lines (120 loc) • 3.96 kB
JavaScript
const fetchingOembed = async (src, type = "youtube") => {
const url = type === "youtube" ? `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${getYouTubeID(src)}&format=json` : `https://vimeo.com/api/oembed.json?url=${src}`;
return await window.fetch(url);
};
const createIframe = (videoID, urlCompare, getTitle, iframeClass, iframePolicy, type, flag = true) => {
let iframeEl = null;
if (flag) {
iframeEl = document.createElement("iframe");
if (type === "youtube") {
const mergedUrl = mergeQueryParams(
`https://www.youtube.com/embed/${videoID}?enablejsapi=1&autoplay=1`,
urlCompare
);
iframeEl.setAttribute("src", mergedUrl);
} else {
const mergedUrl = mergeQueryParams(
`https://player.vimeo.com/video/${videoID}?autoplay=1`,
urlCompare
);
iframeEl.setAttribute("src", mergedUrl);
}
iframeEl.setAttribute("frameborder", "0");
iframeEl.setAttribute(
"allow",
"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
);
iframeEl.setAttribute("allowfullscreen", "1");
iframeEl.setAttribute("referrerpolicy", "strict-origin-when-cross-origin");
iframeEl.setAttribute("title", `${getTitle}`);
iframeEl.setAttribute("class", `${iframeClass}`);
if (["anonymous", "credentialless"].includes(iframePolicy)) {
iframeEl.setAttribute(`${iframePolicy}`, "");
}
}
return iframeEl;
};
const isPostMessageSupported = () => {
if (!window.postMessage) {
return false;
}
return true;
};
const calcAspect = (aspect) => {
const aspects = aspect.split(":");
return typeof aspects[1] === "undefined" ? 56.25 : Number(aspects[1]) / Number(aspects[0]) * 100;
};
const getYouTubeID = (url) => {
const urlParts = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/u);
return urlParts[2] !== void 0 ? urlParts[2].split(/[^\w\-]/iu)[0] : urlParts[0];
};
const getVimeoID = (url) => {
return new URL(url).pathname.split("/").pop() || "";
};
const mergeQueryParams = (urlBase, urlToCompare) => {
const parseUrl = (url) => {
const [base, queryString] = url.split("?");
const params = new URLSearchParams(queryString || "");
return { base, params };
};
const baseObj = parseUrl(urlBase);
const compareObj = parseUrl(urlToCompare);
compareObj.params.forEach((value, key) => {
if (!baseObj.params.has(key)) {
baseObj.params.set(key, value);
}
});
return `${baseObj.base}?${baseObj.params.toString()}`;
};
const getYoutubeThumbnail = (video_id, quality) => {
if (video_id) {
if (typeof quality === "undefined") {
quality = "high";
}
let quality_key = "maxresdefault";
if (quality === "default") {
quality_key = "default";
} else if (quality === "medium") {
quality_key = "mqdefault";
} else if (quality === "high") {
quality_key = "hqdefault";
} else if (quality === "standard") {
quality_key = "sddefault";
} else if (quality === "maxres") {
quality_key = "maxresdefault";
}
return "https://img.youtube.com/vi/" + video_id + "/" + quality_key + ".jpg";
}
return false;
};
const getVimeoThumbnail = (video_id, quality) => {
if (video_id) {
if (typeof quality === "undefined") {
quality = "high";
}
let quality_key = "960x540";
if (quality === "default") {
quality_key = "200x150";
} else if (quality === "medium") {
quality_key = "295x166";
} else if (quality === "high") {
quality_key = "640x360";
} else if (quality === "standard") {
quality_key = "960x540";
} else if (quality === "maxres") {
quality_key = "1280x720";
}
return "https://i.vimeocdn.com/video/" + video_id + "_" + quality_key + ".jpg";
}
return false;
};
export {
createIframe,
isPostMessageSupported,
calcAspect,
fetchingOembed,
getYouTubeID,
getYoutubeThumbnail,
getVimeoID,
getVimeoThumbnail
};