一个知乎脚本,用来自动收起已读的答案
自用的一个 chrome 脚本,请搭配 Tampermonkey 链接 使用。
前言
很多时候,知乎里的长帖很多很多,有时候想在看过的问题里寻找新答案,很是痛苦,所以有了这么个脚本。
正文
直接上图,请看效果图:
- 第一次查看答案时,记录查看时间。
- 再次查看到已读答案时,自动淡化并收起。
脚本
请复制以下代码后另存为zhihu.no_see_read_again2.user.js 文件使用。
// ==UserScript==
// @name zhihu.no_see_read_again2
// @description zhihu.no_see_read_again2
// @auth wyx@wanyaxing.com
// @include https://www.zhihu.com/*
// @include http://www.zhihu.com/*
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
if (!this.GM_getValue || this.GM_getValue.toString().indexOf("not supported")>-1) {
this.GM_getValue=function (key,def) {
return localStorage[key] || def;
};
this.GM_setValue=function (key,value) {
return localStorage[key]=value;
};
}
var ON_SCREEN_HEIGHT = 0;
// var ON_SCREEN_HEIGHT = Infinity;
var ON_SCREEN_WIDTH = 0;
// var ON_SCREEN_WIDTH = Infinity;
var isOnScreen = function (element) {
var rect = element.getBoundingClientRect();
var windowHeight = window.innerHeight || document.documentElement.clientHeight;
var windowWidth = window.innerWidth || document.documentElement.clientWidth;
var elementHeight = element.offsetHeight;
var elementWidth = element.offsetWidth;
var onScreenHeight = ON_SCREEN_HEIGHT > elementHeight ? elementHeight : ON_SCREEN_HEIGHT;
var onScreenWidth = ON_SCREEN_WIDTH > elementWidth ? elementWidth : ON_SCREEN_WIDTH;
// 元素在屏幕上方
var elementBottomToWindowTop = rect.top + elementHeight;
var bottomBoundingOnScreen = elementBottomToWindowTop >= onScreenHeight;
// 元素在屏幕下方
var elementTopToWindowBottom = windowHeight - (rect.bottom - elementHeight);
var topBoundingOnScreen = elementTopToWindowBottom >= onScreenHeight;
// 元素在屏幕左侧
var elementRightToWindowLeft = rect.left + elementWidth;
var rightBoundingOnScreen = elementRightToWindowLeft >= onScreenWidth;
// 元素在屏幕右侧
var elementLeftToWindowRight = windowWidth - (rect.right - elementWidth);
var leftBoundingOnScreen = elementLeftToWindowRight >= onScreenWidth;
return bottomBoundingOnScreen && topBoundingOnScreen && rightBoundingOnScreen && leftBoundingOnScreen;
};
Date.prototype.format = function(format)
{
var o =
{
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(), //day
"h+" : this.getHours(), //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
};
if(/(y+)/.test(format))
{
format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o)
{
if(new RegExp("("+ k +")").test(format))
{
format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
}
}
return format;
};
var _uniqueCheck;
function uniqueCheck()
{
if (!_uniqueCheck)
{
linkCheck2();
}
else if (_uniqueCheck)
{
clearTimeout(_uniqueCheck);
}
_uniqueCheck = setTimeout( ()=> {
linkCheck2();
_uniqueCheck = null;
}, 500);
}
function linkCheck2()
{
console.log('linkCheck2');
// 新版正文
// var aNodes = document.querySelectorAll('.ContentItem-time a:not([no_see_read_again])');
var aNodes = document.querySelectorAll('.ContentItem[name]:not([no_see_read_again])');
Array.prototype.forEach.call(aNodes, function(el, i){
var _this = el;
// console.log(_this);
var answer = _this.getAttribute('name');
if (answer)
{
var lastView = GM_getValue('answer_'+answer);
if (lastView)
{
_this.setAttribute('no_see_read_again','read_before');
// 淡化效果
var zm_item_answer = _this;//.closest('.ContentItem');
if (_this.closest('.List-item'))
{
_this.closest('.List-item').setAttribute('no_see_read_again','read_before');
}
zm_item_answer.style.opacity='0.3';
// 补充显示上次查看
var divNode = document.createElement('span');
divNode.style.cssText = 'float:right;';
divNode.innerHTML = ' 上次查看:'+lastView;
_this.prepend(divNode);
// 开始处理正文
var zm_editable_content = zm_item_answer.querySelector('.RichContent .RichContent-inner');
// 放弃注释掉图片属性,因为速度太快,图片都下载回来了。
// 收起正文
zm_editable_content.style.maxHeight = '30px';
zm_editable_content.style.overflow = 'hidden';
zm_editable_content.style.borderBottom = '1px dotted black';
// 注册点击事件
zm_item_answer.onclick = function(){
zm_editable_content.style.maxHeight = 'none';
zm_editable_content.style.overflow = 'none';
zm_editable_content.style.borderBottom = 'none';
zm_item_answer.style.opacity='1';
};
}
else
{
if (isOnScreen(_this))
{
lastView = (new Date()).format('yyyy-MM-dd hh:mm:ss');
GM_setValue('answer_'+answer, lastView);
_this.setAttribute('no_see_read_again','read_now');
var divNode = document.createElement('span');
divNode.style.cssText = 'float:right;';
divNode.innerHTML = '已记录本次查看';
_this.prepend(divNode);
}
}
}
});
var listItemNodes = document.querySelectorAll('#QuestionAnswers-answers .List-item[no_see_read_again]');
if (listItemNodes.length>10)
{
Array.prototype.forEach.call(listItemNodes, function(el, i){
el.parentNode.removeChild(el);
});
document.body.scrollTop = 0;// document.body.scrollHeight;
document.documentElement.scrollTop = 0;// document.body.scrollHeight;
}
}
uniqueCheck();
//当滚动结束时触发检测。
var lastScrollTime2 = null;
unsafeWindow.onscroll = function(){
var thisTime = lastScrollTime2 = (new Date).getTime();
setTimeout(function(){
if (thisTime == lastScrollTime2)
{
uniqueCheck();
}
},100);
};
if (document.querySelector('.List-item'))
{
document.querySelector('.List-item').parentNode.addEventListener("DOMNodeInserted", function() {
setTimeout(function(){
uniqueCheck();
},500);
});
}
后语
很久前写的这么个脚本,功能能用,就一直这么用着了,代码如上,供大家参考。
X