您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A userscript to play youtube videos by hovering over their thumbnails.
- // ==UserScript==
- // @name YouTube Preview
- // @author sooqua
- // @namespace https://github.com/sooqua/
- // @version 0.9
- // @description A userscript to play youtube videos by hovering over their thumbnails.
- // @match *://*.youtube.com/*
- // @run-at document-end
- // @grant none
- // ==/UserScript==
- var APIready = new Promise(function(resolve) {
- window.onYouTubeIframeAPIReady = resolve;
- });
- (function() {
- 'use strict';
- function init() {
- // requesting api
- var scriptTag = document.createElement('script');
- scriptTag.src = "https://www.youtube.com/iframe_api";
- var firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);
- addGlobalStyle(
- ".watch-sidebar-section { " +
- "z-index: auto !important; " +
- "} " +
- ".yt-lockup-thumbnail:not(.yt-pl-thumb),.thumb-wrapper { " +
- "-webkit-transition: all 200ms ease-in !important; " +
- "-webkit-transform: scale(1) !important; " +
- "-moz-transition: all 200ms ease-in !important; " +
- "-moz-transform: scale(1) !important; " +
- "transition: all 200ms ease-in !important; " +
- "transform: scale(1) !important; " +
- "} " +
- ".yt-lockup-thumbnail:not(.yt-pl-thumb):hover,.thumb-wrapper:hover { " +
- "z-index: 9999999999 !important; " +
- "box-shadow: 0px 0px 100px #000000 !important; " +
- "-webkit-transition: all 200ms ease-in !important; " +
- "-webkit-transform: scale(2.0) !important; " +
- "-moz-transition: all 200ms ease-in !important; " +
- "-moz-transform: scale(2.0) !important; " +
- "transition: all 200ms ease-in !important; " +
- "transform: scale(2.0) !important; " +
- "} " +
- ".yt-thumb.video-thumb, .yt-uix-simple-thumb-wrap.yt-uix-simple-thumb-related { " +
- "background-color: black !important; " +
- "} " +
- ".xspinner { " +
- "pointer-events: none; " +
- "position: absolute; " +
- "top: 0; " +
- "right: 0; " +
- "bottom: 0; " +
- "left: 0; " +
- "background: rgba(255,255,255,0.5); " +
- "font-size: 14px; " +
- "text-align: center; " +
- "line-height: 2; " +
- "color: rgb(0,0,0); " +
- "font-weight: bold; " +
- "} ");
- initOn(document);
- var mo = new MutationObserver(function(muts) {
- muts.forEach(function(mut) {
- [].forEach.call(mut.addedNodes, function(node) {
- if (node instanceof HTMLElement) {
- initOn(node);
- }
- });
- });
- });
- mo.observe(document.body, {childList: true, subtree: true});
- }
- function initOn(base) {
- [].forEach.call(base.querySelectorAll('.yt-lockup-thumbnail:not(.yt-pl-thumb) a[href^="/watch"], .thumb-wrapper a[href^="/watch"]'), function(thumbnail) {
- thumbnail.parentNode.addEventListener('mouseover', function() {
- if(thumbnail.overlocker) return;
- thumbnail.overlocker = new Promise(function (unlock) {
- var rect = thumbnail.parentElement.getBoundingClientRect();
- var farRight = (rect.right + thumbnail.parentElement.clientWidth/2.0) > window.innerWidth;
- var farDown = (rect.bottom + thumbnail.parentElement.clientHeight/2.0) > window.innerHeight;
- var farLeft = (rect.left - thumbnail.parentElement.clientWidth/2.0) < 0;
- var farUp = (rect.top - thumbnail.parentElement.clientHeight/2.0) < 0;
- if(farRight || farDown || farLeft || farUp) {
- var transformOrig = (farRight ? 'right ':'') + (farDown ? 'bottom ':'') + (farLeft ? 'left ':'') + (farUp ? 'top ':'');
- thumbnail.parentElement.style.webkitTransformOrigin = transformOrig;
- thumbnail.parentElement.style.mozTransformOrigin = transformOrig;
- thumbnail.parentElement.style.transformOrigin = transformOrig;
- }
- var spinner = document.createElement('div');
- spinner.className = 'xspinner';
- spinner.textContent = 'Loading...';
- var childThumb = thumbnail.querySelector('.yt-thumb.video-thumb, .yt-uix-simple-thumb-wrap.yt-uix-simple-thumb-related');
- childThumb.appendChild(spinner);
- thumbnail.watchedContainer = [];
- for (var el = thumbnail; el; el = el.parentElement) {
- if (el.classList.contains('watched')) {
- thumbnail.watchedContainer.push(el);
- el.classList.remove('watched');
- }
- }
- thumbnail.watchedBadgeContainer = [];
- [].forEach.call(thumbnail.parentNode.querySelectorAll('.watched-badge'), function (watchedBadge) {
- thumbnail.watchedBadgeContainer.push(watchedBadge);
- watchedBadge.style.display = 'none';
- });
- thumbnail.imageContainer = [];
- [].forEach.call(thumbnail.getElementsByTagName('img'), function(img) {
- thumbnail.imageContainer.push(img);
- img.style.opacity = 0;
- });
- var vidId = thumbnail.href.split('v=')[1];
- thumbnail.PPlayer = new Promise(function (resolve) {
- var playerTag = document.createElement('div');
- playerTag.id = vidId;
- playerTag.style.pointerEvents = 'none';
- playerTag.style.position = 'absolute';
- childThumb.insertBefore(playerTag, childThumb.firstChild);
- APIready.then(function () {
- var pplayer = new YT.Player(playerTag.id, {
- width: childThumb.offsetWidth,
- height: childThumb.offsetHeight,
- videoId: vidId,
- playerVars: {
- 'enablejsapi': 1, 'autoplay': 1, 'showinfo': 0, 'controls': 0,
- 'modestbranding': 1, 'ps': 'docs', 'iv_load_policy': 3, 'rel': 0,
- 'vq': 'medium'
- },
- events: {
- 'onReady': function() { resolve(pplayer); }
- }
- });
- });
- });
- thumbnail.PPlayer.then(function () {
- childThumb.removeChild(spinner);
- unlock();
- });
- });
- });
- thumbnail.parentNode.addEventListener('mousemove', function(evt) {
- if (thumbnail.spinner) return;
- if(thumbnail.lastX !== evt.screenX) {
- var offsetX = evt.offsetX || evt.layerX - thumbnail.offsetLeft;
- if(thumbnail.PPlayer) {
- thumbnail.PPlayer.then(function (PPlayer) {
- try {
- PPlayer.seekTo(PPlayer.getDuration() * offsetX / thumbnail.parentElement.offsetWidth, true);
- } catch (e){}
- });
- }
- }
- thumbnail.lastX = evt.screenX;
- });
- thumbnail.parentNode.addEventListener('mouseout', function(evt) {
- if(!thumbnail.overlocker) return;
- thumbnail.overlocker.then(function () {
- if(evt.relatedTarget) {
- if (thumbnail.parentElement.contains(evt.relatedTarget)) return;
- if (evt.relatedTarget.className.indexOf('yt-uix-tooltip-tip') !== -1) return;
- }
- if(thumbnail.watchedContainer) {
- for (var i = 0; i < thumbnail.watchedContainer.length; i++)
- thumbnail.watchedContainer[i].classList.add('watched');
- thumbnail.watchedContainer = null;
- }
- if(thumbnail.watchedBadgeContainer) {
- for (var i = 0; i < thumbnail.watchedBadgeContainer.length; i++)
- thumbnail.watchedBadgeContainer[i].style.display = null;
- thumbnail.watchedBadgeContainer = null;
- }
- if(thumbnail.imageContainer) {
- for (var i = 0; i < thumbnail.imageContainer.length; i++)
- thumbnail.imageContainer[i].style.opacity = null;
- thumbnail.imageContainer = null;
- }
- if(thumbnail.PPlayer) {
- thumbnail.PPlayer.then(function(PPlayer) {
- if(PPlayer.a.parentNode)
- PPlayer.a.parentNode.removeChild(PPlayer.a);
- thumbnail.PPlayer = null;
- thumbnail.overlocker = null;
- });
- }
- else {
- thumbnail.overlocker = null;
- }
- });
- });
- });
- }
- function addGlobalStyle(css) {
- var head = document.getElementsByTagName('head')[0];
- if (!head) { return; }
- var style = document.createElement('style');
- style.type = 'text/css';
- style.innerHTML = css;
- head.appendChild(style);
- }
- init();
- })();