微博图片全显示

同屏显示多图微博的全部大图。

目前为 2023-02-20 提交的版本。查看 最新版本

// ==UserScript==
// @name        微博图片全显示
// @namespace   hzhbest
// @include     http://weibo.com/*
// @include     https://weibo.com/*
// @include     http://www.weibo.com/*
// @include     https://www.weibo.com/*
// @description    同屏显示多图微博的全部大图。
// @version     3.96
// @grant       GM_xmlhttpRequest
// @grant       unsafeWindow
// @run-at      document-end
// @license     GNU GPLv3
// ==/UserScript==

(function() {

  // --这里是设置区-- //
var topheight = 60;		//微博顶栏高度
var topspare = 125;		//滚动预留顶部高度
var autorefresh = true;	//是否定时自动检测页面变化

  // --以下是代码区,请不要随意改动-- //

	// http://weibo.com/2710065263/BmxiVDCgt?from=page_1005052710065263_profile&wvr=6&mod=weibotime&type=comment#_rnd1436436058420
	// http://weibo.com/2328516855/CnYCvixUq?type=comment#_rnd1436493435761
var regex = /weibo\.com\/\d{10}\/[a-z0-9A-Z]{9}\??/;
pinit();

function pinit(){
  	var bpimg = document.querySelector('img.big_pic');
	if (regex.test(document.location.href)) {//console.log(document.location.href);
    	if (!bpimg) init();
  	} else {
		var buttonbox = document.querySelector('.big_pic_b');
		if (!!buttonbox) buttonbox.parentNode.removeChild(buttonbox);
	}
  	if (autorefresh){
   		setTimeout(pinit, 1000);//console.log("wait 1 sec");
  	}
}

function init(){
    var list_ul = document.querySelector('div.vue-recycle-scroller__item-view');	//评论框架
	var expbox = document.querySelector('div[class*="picture content_row_-"');	//附加媒体容器
	if (!list_ul && !expbox){console.log("no1");	//未加载评论框架,等候
		setTimeout(init, 1000);
		return;
	} else if (!!list_ul && !expbox) {console.log("no2",expbox);	//评论框架已加载却无附加媒体容器,退出
		//getlongtext()
		return;
	} else {console.log("go");
		//getlongtext()
		go(expbox);//console.log(expbox);
	}
}

function go(expbox){
	var wrpbox = expbox.firstElementChild;
	var feedbox = document.querySelector('.vue-recycle-scroller__item-wrapper');		//评论区容器元素
	var appbox = document.querySelector('WB_app_view');			//应用容器??
	var videobox = document.querySelector('div[class*="card-video_videoBox_"');			//视频容器
	var maintextimg = getElem('//div[@class="WB_detail"]/div[@class="WB_text W_f14"]/a[@imagecard]');	//正文中的图片??
	var dbox = document.body.getElementsByTagName('main')[0].parentNode.parentNode;										//主容器
	dbox.style.maxWidth = "none";
	//console.log(maintextimg.attributes[0]);

	// Insert CSS
	var headID = document.getElementsByTagName("head")[0];
	var cssNode = creaElemIn('style', headID);
	cssNode.type = 'text/css';
	cssNode.innerHTML = '.big_pic{max-width: 890px;} .big_pic_n{max-width: 500px;} .big_pic:hover, .big_pic_n:hover{box-shadow: 0 0 30px 2px #f1ecdf;} .big_pic_poster{outline: 2px dashed #fcde44;outline-offset: -2px;} .big_pic_v{max-width: 60%; max-height: 80%;}';	//大图样式
	cssNode.innerHTML += [
	'main>div[class^="Main_full_"] {width: auto !important;min-width:800px;}',
	'.WB_frame_c {width: auto !important; max-width: 920px; min-width: 600px;}',
	'.WB_text.W_f14, .repeat_list .list_box .WB_text, .WB_expand>.WB_text{width: 490px;}',
	'.WB_frame_c .media_box{display: none !important;}',
	'div[node-type="comment_list"] .media_box{display: block !important;}',
	'div[id^="Pl_Core_RecommendFeed__"]{right: 150px; width: 100px !important; max-height: 35px; overflow: hidden; transition: all ease 0.2s 0.5s;}',
	'div[id^="Pl_Core_RecommendFeed__"]:hover{width: 300px !important; max-height: 1000px;}',
	'div[id^="Pl_Core_RecommendFeed__"] .opt_box{display:none;}',
	'div[id^="Pl_Core_RecommendFeed__"]:hover .opt_box{display: inline-block;}'].join();	//微博自身框架样式
	cssNode.innerHTML += [
	'.big_pic_b{position: fixed; left: 10px; top: 200px;}',
	'.big_pic_btn{height: 20px; min-width: 50px; width: fit-content; padding: 3px; margin-bottom: 20px; border: 1px solid white; color: white; background: rgba(133,133,133,0.6); cursor: pointer; user-select: none;}',
	'.big_pic_btn:hover{background: rgba(133,133,200,0.6);}',
	].join("");	//按钮样式


	var buttonbox = creaElemIn('div', document.body);
	buttonbox.className = 'big_pic_b';
	var sclink = creaElemIn('div', buttonbox);						//直达评论链接
	sclink.className = "big_pic_btn";
	sclink.innerHTML = "直达评论";
	sclink.addEventListener("click", function(){
		var commentbox = document.querySelector('div.wbpro-tab3');
		scrollto(getTop(commentbox) - topheight * 2);
	}, false);

	if (!!videobox) {
		cssNode.innerHTML = [
		'.big_pic_sc{position: fixed; left:10px; padding: 3px; border: 1px solid white; color: white; background: rgba(133,133,133,0.6); cursor: pointer;} ',
		'.big_pic_sc{top: 430px}'].join("");
		return;
	}

	if (!!appbox) {													//检测到应用容器(微博文章或视频)时退出
		// box.appendChild(appbox);
		// if (!!wrpbox) expbox.removeChild(wrpbox);
		// cssNode.innerHTML = [
		// '.media_box{display: none !important;}',
		// '.big_pic_sc{position: fixed; left:10px; padding: 3px; border: 1px solid white; color: white; background: rgba(133,133,133,0.6); cursor: pointer;} ',
		// '.big_pic_sc{top: 430px}'].join("");
		return;
	}

	var imgboxes = document.querySelectorAll('div[class*="woo-box-item-inlineBlock picture_item_"');
	var bpboxes = [], imgsrc, imgn, imgl = imgboxes.length, mtimg;
	var _limited = false;

	if (!!maintextimg) {												//检测到有正文转发含有图片,自动展开
		maintextimg.innerHTML = "";
		maintextimg.parentNode.insertBefore(document.createElement("br"), maintextimg);
		mtimg = creaElemIn("img", maintextimg);
		mtimg.src = maintextimg.getAttribute("imagecard").replace("pid=", "http://ww1.sinaimg.cn/bmiddle/") + ".jpg";
		mtimg.className = "big_pic";
	}

	var j = 0;
	for (var i = 0; i < imgl; i++) {					//提取大图
		// https://wx2.sinaimg.cn/orj360/006QkcF9ly1gz75df9qmuj30nn061dj1.jpg
		// https://wx2.sinaimg.cn/large/006QkcF9ly1gz75df9qmuj30nn061dj1.jpg
		// https://wx4.sinaimg.cn/large/002MwiQagy1gz7le15xtyj60k06851kx02.jpg
		// https://wx3.sinaimg.cn/large/003nJ9EBly1hakhpjuqugj60dc336n5l02.jpg
		bpboxes[i] = creaElemIn('div', expbox);
		creaElemIn('br', expbox);
		var imgnode = imgboxes[i].querySelector('img');
		var imgvnode = imgboxes[i].querySelector('video');		//“动图”(实际上是mp4视频)
		if (/sinaimg.c(om|n)/.test(imgnode.src)) {
			if (/sinaimg.c(om|n)\/(orj|thumb)\d{3}/.test(imgnode.src)) {
				imgsrc = imgnode.src.replace(/(sinaimg\.c(om|n)\/)(orj|thumb)\d{3}/, "$1large");
			} else if (/sinaimg.c(om|n)\/large/.test(imgnode.src)) {
				imgsrc = imgnode.src
			}
			imgn = creaElemIn('img', bpboxes[i]);
			imgn.src = imgsrc;
			imgn.className = "big_pic";
		} else if (!!imgvnode) {
			imgn = creaElemIn('img', bpboxes[i]);
			imgn.src = imgvnode.poster;
			imgn.className = "big_pic big_pic_poster";
			imgn.onclick = function(event) {
				let pnode = event.target;
				let vnode = pnode.parentNode.getElementsByTagName('video')[0];
				pnode.style.display = "none";
                vnode.style.display = "block";
                vnode.play(); console.log("p: ",'played');
			};
			bpboxes[i].appendChild(imgvnode);
			imgvnode.className = "big_pic_v";
			imgvnode.controls = true;
            imgvnode.style.display = 'none';
            imgvnode.addEventListener('ended',function(event) {
                let vnode = event.target;
                let pnode = vnode.parentNode.getElementsByTagName('img')[0]; console.log("p: ",pnode);
                vnode.style.display = "none";
                pnode.style.display = "block";
            });
			imgvnode.onclick = function(event) { console.log("v: ",'clicked');
                //(vnode.paused)? vnode.play() : vnode.pause();
			};
		} else {
			j += 1;	//console.log(j,imgl,j == imgl);
			continue;
		}//console.log(j,imgl);
		if (j == imgl) return;
	}
	if (j == imgl) {													//没找到符合条件的大图,退出
		cssNode.innerHTML = '.big_pic_sc{position: fixed; left:10px; padding: 3px; border: 1px solid white; color: white; background: rgba(133,133,133,0.6); cursor: pointer;} .big_pic_sc{top: 430px}';
		return;
	}
	imgl = bpboxes.length;
	//if (!!mtimg) imgl = imgs.unshift(mtimg); //console.log(imgs.length);
	// console.log(!!wrpbox + "1 " + !!expbox + "2");
	if (!!wrpbox) expbox.removeChild(wrpbox);

	var nclink = creaElemIn('div', buttonbox);						//图片限宽链接
	nclink.className = "big_pic_btn";
	nclink.innerHTML = "图片限宽";
	nclink.addEventListener("click", function(){
		var i;
		if (_limited) {
			for (i = 0; i < imgl; i++) {bpboxes[i].querySelector('img').className = "big_pic";}
			_limited = false;
		} else {
			for (i = 0; i < imgl; i++) {bpboxes[i].querySelector('img').className = "big_pic_n";}
			_limited = true;
		}
	}, false);
	var n1link = creaElemIn('div', buttonbox);						//首个图片链接
	n1link.className = "big_pic_btn";
	n1link.innerHTML = "△首个图片";
	n1link.addEventListener("click", function(){
		scrollto(getTop(bpboxes[0])-topspare);
	}, false);
	var n2link = creaElemIn('div', buttonbox);						//上个图片链接
	n2link.className = "big_pic_btn";
	n2link.innerHTML = "▲上个图片";
	n2link.addEventListener("click", function(){
		var t = document.documentElement.scrollTop; //console.log("t:"+t);
		for (var j=imgl-1; j>=0; j--) { //console.log(j);console.log(getTop(bpboxes[j]),getTop(bpboxes[j]) + bpboxes[j].offsetHeight - topspare);
			if (t > getTop(bpboxes[j]) + bpboxes[j].offsetHeight - topspare) {
				scrollto(getTop(bpboxes[j]) - topspare + 25);
				n2link.innerHTML = "▲上个图片[" + (j+1) + " / " + imgl + "]";
				return;
			}
		}
	}, false);
	var n3link = creaElemIn('div', buttonbox);						//下个图片链接
	n3link.className = "big_pic_btn";
	n3link.innerHTML = "▼下个图片";
	n3link.addEventListener("click", function(){
		var t = document.documentElement.scrollTop; //console.log("t:"+t);
		for (var j=0; j<imgl; j++) { //console.log(j,getTop(bpboxes[j]));
			if (t < getTop(bpboxes[j]) - topspare) {
				scrollto(getTop(bpboxes[j]) - topspare + 25);
				n2link.innerHTML = "▲上个图片[" + (j+1) + " / " + imgl + "]";
				return;
			}
		}
	}, false);
	waitscroll();
	document.onscroll = function(){
		var t = document.documentElement.scrollTop; //console.log("t:"+t);
		for (var j=imgl-1; j>=0; j--) { //console.log(j);console.log(getTop(bpboxes[j]),getTop(bpboxes[j]) + bpboxes[j].offsetHeight - topspare);
			if (t > getTop(bpboxes[j]) - topspare) {
				n2link.innerHTML = "▲上个图片[" + (j+1) + " / " + imgl + "]";
				return;
			}
		}
	};
}

function waitscroll(){	//等待页面完全载入再滚动
	var list_ul = document.querySelector('div.list_ul');	//↓等待评论框架载入,如果评论框架就位就等待评论区或无评论提示载入,再视滚动位置判断
	if (!list_ul || (!list_ul.getElementsByTagName('div')[0] || !document.querySelector('div.tips_rederror')) || document.documentElement.scrollTop < (topheight+70)) {
		setTimeout(waitscroll, 300);	//console.log("wait");
		return;
	} else {
		scrollto(topheight);	//console.log("scroll");
	}
}

function scrollto(pos){	//滚动
	document.documentElement.scrollTop = pos;
}

// Create an element
function creaElemIn(tagname, destin) {
	var theElem = destin.appendChild(document.createElement(tagname));
	return theElem;
}
// Get the first element by xpath
function getElem(xpath) {
	return document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
}
// Get the absolute top of an element
function getTop(e){
	var offset=e.offsetTop;
	if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
	return offset;
}
// 通过模拟请求展开超长微博
function getlongtext() {
	var longtext = document.getElementById('plc_main').querySelectorAll('[action-type="fl_unfold"]')[0];	//可展开的按钮
	if (!longtext) return;
	var mid = longtext.getAttribute('action-data').slice(4);
	GM_xmlhttpRequest({
		'method': 'GET',
		'url': 'http://' + document.domain + '/p/aj/mblog/getlongtext?ajwvr=6&mid=' + mid,
		'onload': function (_h) {
			var html = JSON.parse(_h.responseText).data.html;
			longtext.parentNode.innerHTML = html;
		}
    });
  }

})();