您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
美化 V2EX,提升浏览体验!
当前为
// ==UserScript== // @name V2EX 非同一般的扩展 // @namespace LeoKu(https://leoku.top) // @version 0.5.7 // @description 美化 V2EX,提升浏览体验! // @author LeoKu // @match https://www.v2ex.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=v2ex.com // @grant none // @license MIT // ==/UserScript== "use strict"; // src/web-scripts/style.ts var style = `body{--v2p-font-noto-sans: -apple-system, BlinkMacSystemFont, "Noto Sans SC", sans-serif;--v2p-color-main-100: #f1f5f9;--v2p-color-main-200: #e2e8f0;--v2p-color-main-300: #cbd5e1;--v2p-color-main-400: #94a3b8;--v2p-color-main-500: #64748b;--v2p-color-main-600: #475569;--v2p-color-main-700: #334155;--v2p-color-main-800: #1e293b;--v2p-color-main-900: #0f172a;--v2p-color-accent-50: #ecfdf5;--v2p-color-accent-100: #d1fae5;--v2p-color-accent-200: #a7f3d0;--v2p-color-accent-300: #6ee7b7;--v2p-color-accent-400: #34d399;--v2p-color-accent-500: #10b981;--v2p-color-accent-600: #059669;--v2p-color-border: rgb(238 238 238);--v2p-color-wrapper-bg: rgb(249 250 252);--v2p-color-content-bg: rgb(255 255 255);--color-fade: #94a3b8;--color-gray: #94a3b8;--link-color: #1e293b;--box-border-color: #f1f5f9;--box-foreground-color: #1e293b;color:var(--v2p-color-main-800);font-family:var(--v2p-font-noto-sans);background-color:var(--v2p-color-wrapper-bg)}body #Top{height:55px;background-color:var(--v2p-color-content-bg);border:none}body #Bottom{border:none}body #Wrapper{background-color:inherit;background-image:none}body #Wrapper .content{display:flex;gap:15px}body #Leftbar{order:1;float:none}body #Main{flex:1;order:2;margin:0}body #Rightbar{order:3;float:none}body .box{overflow:hidden;background-color:var(--v2p-color-content-bg);border:none;border-radius:8px;box-shadow:none}body .box .header .gray{color:var(--v2p-color-main-400)}body .button.normal,body .button.super{position:relative;display:inline-flex;gap:5px;align-items:center;height:28px;padding:0 12px;color:var(--v2p-color-main-500);font-weight:500;font-size:14px;font-family:inherit;line-height:28px;background:none;background-color:var(--v2p-color-main-100);border:none;border-radius:6px;outline:none;box-shadow:0 1.8px 0 var(--v2p-color-main-200),0 1.8px 0 var(--v2p-color-main-100);cursor:pointer;user-select:none}body .button.normal:hover:enabled,body .button.super:hover:enabled{color:var(--v2p-color-main-500);font-weight:500;text-shadow:none;background-color:var(--v2p-color-main-100);border:none;box-shadow:0 1.8px 0 var(--v2p-color-main-200),0 1.8px 0 var(--v2p-color-main-100)}body .button.normal.hover_now,body .button.normal.disable_now,body .button.super.hover_now,body .button.super.disable_now{color:var(--v2p-color-main-500) !important;text-shadow:none !important;background-color:var(--v2p-color-main-100) !important}body .button.normal.disable_now,body .button.super.disable_now{cursor:default;opacity:.5;pointer-events:none}body .button.normal kbd,body .button.super kbd{position:relative;right:-4px;padding:0 3px;line-height:initial;border:1px solid var(--v2p-color-main-200);border-radius:4px}body .button.v2p-prev-btn,body .button.v2p-next-btn{padding:0 15px}body .page_normal:link,body .page_normal:visited,body .page_current:link,body .page_current:visited{border:none}body .page_normal:link,body .page_normal:visited{background-color:var(--v2p-color-content-bg);box-shadow:0 2px 2px var(--v2p-color-main-200)}body .page_current:link,body .page_current:visited{font-weight:500;background-color:var(--v2p-color-main-200);box-shadow:none}body .page_input{display:none}::selection{color:currentcolor;background-color:var(--v2p-color-main-200)}img::selection{background-color:var(--v2p-color-main-400)}#reply-box.reply-box-sticky{bottom:20px;overflow:hidden;border:none;border-radius:10px;box-shadow:0 0 15px 5px var(--v2p-color-main-200)}#reply-box #reply_content{border-color:var(--v2p-color-main-300);border-radius:6px}#Main #reply-box>.cell.flex-one-row,#Main #reply-box>.cell.flex-row-end{padding:12px 10px;font-size:12px}#search-container{height:30px;margin:0 30px;background-color:var(--v2p-color-main-100);border:none;border-radius:6px}#search-container::before{top:0;left:4px;background-size:14px 14px;opacity:.6;filter:none}#search-container.active{background-color:var(--v2p-color-main-100)}#search-container #search-result{top:42px;box-shadow:0 0 15px 5px var(--v2p-color-main-200)}#no-comments-yet{color:var(--v2p-color-main-400);border-color:var(--v2p-color-main-400)}.box .tag,.box>.cell:first-of-type .tag{color:currentcolor;font-size:12px;background-color:var(--v2p-color-main-100);border-radius:5px}#Top .content{height:100%}#Top .site-nav{height:100%;padding:0}#Top .tools{display:flex;gap:8px 15px;align-items:center;justify-content:flex-end;font-weight:400;font-size:14px}#Top .tools .top{margin-left:0;padding:3px 5px;color:var(--v2p-color-main-400);border-radius:4px}#Top .tools .top:hover{color:var(--v2p-color-main-800)}#Top .tools .top:not(.effect-btn):hover{background-color:var(--v2p-color-main-100)}#Top .tools .top.effect-btn{transition:color .3s}#Main>.box{padding:0 12px}#Main>.box .cell{padding:20px 10px}#Main .topic_content{font-size:16px}#Main .cell_tab_current{border-color:var(--v2p-color-main-800)}#Main .cell.item{border-bottom:1px solid var(--v2p-color-border)}#Main .cell.item .item_title{font-weight:600;opacity:.8}#Main .cell.item .item_title:hover{opacity:1}#Main .cell.item .topic-link{color:var(--v2p-color-main-800);text-decoration:none}#Main .cell.item .topic-link:visited{color:var(--v2p-color-main-400)}#Main .cell.item .topic_info{position:relative}#Main .cell.item .topic_info::after{position:absolute;top:0;right:0;bottom:-6px;left:0;z-index:1;background-color:var(--v2p-color-content-bg);content:""}#Main .cell.item .topic_info .node{padding:5px 6px;color:var(--v2p-color-main-400);font-size:13px;background-color:var(--v2p-color-main-100);border-radius:4px}#Main .cell.item .topic_info .votes,#Main .cell.item .topic_info .node,#Main .cell.item .topic_info strong:first-of-type,#Main .cell.item .topic_info span:first-of-type{position:relative;z-index:99}#Main .cell.item:hover .count_livid{opacity:1}#Main .cell.item .count_livid{display:inline-block;padding:5px 10px;color:var(--v2p-color-main-400);font-weight:400;white-space:nowrap;background-color:var(--v2p-color-main-200);border-radius:5px;opacity:.8}#Main .cell.item tr>td:nth-child(2){width:30px}#Main #Tabs{display:flex;gap:6px 8px;align-items:center}#Main #SecondaryTabs{padding:10px;background-color:var(--v2p-color-main-100);border-radius:5px}#Main .cell[id^=r]:hover>table td:last-of-type .fr a{opacity:1}#Main .cell[id^=r]>table:first-of-type td:first-of-type{width:40px}#Main .cell[id^=r]>table:first-of-type td:first-of-type .avatar{width:40px !important;border-radius:5px}#Main .cell[id^=r]>table~.cell{padding:20px 0 0 15px;border:none}#Main .cell[id^=r]>table~.cell .cell{padding:20px 0 0;border:none}#Main .cell[id^=r]>table~.cell tr td:first-of-type{width:25px}#Main .cell[id^=r]>table~.cell tr td:first-of-type .avatar{width:25px !important;border-radius:4px}#Main .cell[id^=r]>table~.cell tr td:nth-child(3) strong a{font-size:13px;opacity:.75}#Main .cell[id^=r]>table~.cell .reply_content{font-size:14px}#Main .cell[id^=r]>table td:nth-of-type(2){width:15px}#Main .cell[id^=r]>table td:last-of-type a.dark{color:var(--v2p-color-main-600);text-decoration:none}#Main .cell[id^=r]>table td:last-of-type .fr{position:relative;top:-3px;user-select:none}#Main .cell[id^=r]>table td:last-of-type .fr a{opacity:0}#Main .cell[id^=r] .no{position:relative;top:-4px;padding:5px 10px;color:var(--v2p-color-main-300);font-size:12px;background-color:rgba(0,0,0,0);border-radius:5px;user-select:none}#Main .cell[id^=r] .badge.op,#Main .cell[id^=r] .badge.mod{padding:2px 5px;color:var(--v2p-color-accent-500);font-weight:600;background-color:var(--v2p-color-accent-50);border:1px solid var(--v2p-color-accent-400);border-radius:4px;user-select:none}#Main .topic_content a[href^=http],#Main .reply_content a[href^=http]{color:var(--v2p-color-main-500);text-decoration:none;background-color:var(--v2p-color-main-100)}#Main .topic_content a[href^=http]:hover,#Main .reply_content a[href^=http]:hover{color:var(--v2p-color-accent-500);background-color:var(--v2p-color-accent-50)}#Main .reply_content{font-size:15px}#Main .reply_content a[href^=http]{color:var(--v2p-color-main-500);text-decoration:none;background-color:var(--v2p-color-main-100)}#Main .reply_content a[href^=http]:hover{color:var(--v2p-color-accent-500);background-color:var(--v2p-color-accent-50)}#Main .reply_content a[href^="/member"]{color:var(--v2p-color-main-400);font-size:13px;text-decoration:underline;background-color:var(--v2p-color-main-100)}#Main .thank_area{font-size:12px}#Main .tab{margin:0;background-color:rgba(0,0,0,0)}#Main .tab:not(.effect-btn):hover{background-color:var(--v2p-color-main-100)}#Main .tab_current{background-color:var(--v2p-color-main-700)}.topic_buttons{display:flex;flex-direction:row-reverse;align-items:center;padding:8px 0;column-gap:5px;background:none}.topic_buttons .topic_stats{margin-left:auto;padding:0 !important;font-size:12px}.topic_buttons a.tb:link{display:flex;flex-direction:row-reverse;align-items:center;padding:8px 5px;column-gap:5px;background:none;border-radius:4px}.topic_buttons .tb:hover:not(.effect-btn){background:var(--v2p-color-main-100);filter:none}.topic_buttons #topic_thank .tb::after{content:"\u{1F64F}"}.topic_buttons .tb:nth-child(2)::after{content:"\u2B50"}.topic_buttons .tb:nth-child(3)::after{content:"\u{1F426}"}.topic_buttons .tb:nth-child(4)::after{content:"\u{1F648}"}#Rightbar .box{opacity:.5;transition:opacity .25s}#Rightbar .box:hover{opacity:1}#Rightbar .balance_area{display:flex;align-items:center}#Bottom .inner .small.fade{display:none}body.modal-open{overflow:hidden}.effect-btn{position:relative;z-index:1;margin:0;background:none;background-color:rgba(0,0,0,0);cursor:pointer;user-select:none}.effect-btn::before{position:absolute;top:0;right:-5px;bottom:0;left:-5px;z-index:-1;background-color:var(--v2p-color-main-100);border-radius:5px;transform:scale(0.6);opacity:0;transition:transform .3s,opacity .3s;content:""}.effect-btn:hover::before{transform:scale(1);opacity:1}.v2p-popular-btn{padding:5px 0}.v2p-dot{margin:0 8px;font-weight:800;font-size:20px;font-size:15px}.v2p-paging{background:none !important}.v2p-cm-mask{position:fixed;z-index:999;padding:60px;overflow:hidden;overflow-y:auto;background-color:rgba(0,0,0,.25);inset:0}.v2p-cm-content.box{position:relative;box-sizing:border-box;width:800px;height:100%;margin:0 auto;padding:0 20px;overflow-x:hidden;overflow-y:auto}.v2p-cm-content.box .v2p-ac-reply{display:none}.v2p-cm-content.box .no{pointer-events:none}.v2p-cm-bar{position:sticky;top:0;right:0;left:0;z-index:10;display:flex;align-items:center;padding:20px 0;background-color:var(--v2p-color-content-bg)}.v2p-cm-close-btn{margin-left:auto}.heart-box{position:relative;top:3px;display:inline-flex;align-items:center;column-gap:5px}.icon-heart{display:inline-flex;width:16px;height:16px;color:#f43f5e}.icon-heart svg{fill:#ffe4e6}@supports not selector(:has(*)){#Main .cell[id^=r]>table:hover .v2p-controls{opacity:1}}@supports selector(:has(*)){#Main .cell[id^=r]:not(:has(.cell:hover))>table:hover .v2p-controls{opacity:1}}.v2p-controls{display:inline-flex;align-items:center;font-size:12px;column-gap:15px;opacity:0}.v2p-controls>a{text-decoration:none;opacity:1}.v2p-control{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:4px 0;color:var(--v2p-color-main-400)} `; function addGlobalStyle() { $(`<style type='text/css'>${style}</style>`).appendTo("head"); } // src/web-scripts/globals.ts var loginName = $('#Top .tools > a[href^="/member"]').text(); var topicOwnerName = $("#Main > .box:nth-child(1) > .header > small > a").text(); var topicContentBox = $("#Main .box:has(.topic_content)"); var commentBox = $('#Main .box:has(.cell[id^="r_"])'); var commentCells = commentBox.find('.cell[id^="r_"]'); var cellTableRows = commentCells.find("table > tbody > tr"); var commentData = cellTableRows.map((idx, tr) => { const id = commentCells[idx].id; const td = $(tr).find("> td:nth-child(3)"); const name = td.find("> strong > a").text(); const content = td.find("> .reply_content").text(); const likes = Number(td.find("span.small").text()); const floor = td.find("span.no").text(); return { id, name, content, likes, floor, index: idx }; }).get(); // src/web-scripts/topic.ts function popular() { topicContentBox.find("a[href]").attr("target", "_blank"); const popularCommentData = commentData.filter(({ likes }) => likes > 0).sort((a, b) => b.likes - a.likes); if (popularCommentData.length > 0) { const cmMask = $('<div class="v2p-cm-mask">'); const cmContent = $(` <div class="v2p-cm-content box"> <div class="v2p-cm-bar"> <span>\u672C\u9875\u5171\u6709 ${popularCommentData.length} \u6761\u70ED\u95E8\u56DE\u590D</span> <button class="v2p-cm-close-btn normal button">\u5173\u95ED<kbd>Esc</kbd></button> </div> </div> `); const cmContainer = cmMask.append(cmContent).hide(); { const commentBoxCount = commentBox.find(".cell:first-of-type > span.gray"); const countText = commentBoxCount.text(); const newCountText = countText.substring(0, countText.indexOf("\u56DE\u590D") + 2); const countTextSpan = `<span class="count-text">${newCountText}</span><span class="v2p-dot">\xB7</span>`; let boundEvent = false; const clickHandler = (e) => { if ($(e.target).closest(cmContent).length === 0) { handleModalClose(); } }; const keyupHandler = (e) => { if (e.key === "Escape") { handleModalClose(); } }; const handleModalClose = () => { $(document).off("click", clickHandler); $(document).off("keydown", keyupHandler); boundEvent = false; cmContainer.fadeOut("fast"); document.body.classList.remove("modal-open"); }; const handleModalOpen = () => { if (!boundEvent) { $(document).on("click", clickHandler); $(document).on("keydown", keyupHandler); boundEvent = true; } cmContainer.fadeIn("fast"); document.body.classList.add("modal-open"); }; const closeBtn = cmContainer.find(".v2p-cm-close-btn"); closeBtn.on("click", handleModalClose); const popularBtn = $('<span class="v2p-popular-btn effect-btn">\u{1F525} \u67E5\u770B\u70ED\u95E8\u56DE\u590D</span>'); popularBtn.on("click", (e) => { e.stopPropagation(); handleModalOpen(); }); commentBoxCount.empty().append(countTextSpan).append(popularBtn); } const templete = $("<templete></templete>"); popularCommentData.forEach(({ index }) => { templete.append(commentCells.eq(index).clone()); }); cmContent.append(templete.html()); commentBox.append(cmContainer); } } var iconHeart = ` <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" /> </svg> `; function replaceHeart() { commentCells.find(".small.fade").addClass("heart-box").find('img[alt="\u2764\uFE0F"]').replaceWith(` <span class="icon-heart"> ${iconHeart} </span> `); } function setControls() { const thankAreas = commentCells.find(".thank_area"); thankAreas.each((_, el) => { const thankArea = $(el); const thanked = thankArea.hasClass("thanked"); const controls = $('<span class="v2p-controls">'); const thankIcon = $(` <span class="v2p-control"> ${iconHeart} </span> `); if (thanked) { thankIcon.attr("title", "\u5DF2\u611F\u8C22").css({ color: "#f43f5e", cursor: "default" }); controls.append($("<a>").append(thankIcon)); } else { const hide = thankArea.find("> a").eq(0).removeClass("thank"); const thank = thankArea.find("> a").eq(1).removeClass("thank"); hide.html(` <span class="v2p-control effect-btn" title="\u9690\u85CF"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88" /> </svg> </span> `); thankIcon.attr("title", "\u611F\u8C22").addClass("effect-btn"); thank.empty().append(thankIcon); controls.append(hide).append(thank); } const reply = thankArea.find("+ a"); reply.find('> img[alt="Reply"]').replaceWith(` <span class="v2p-control v2p-ac-reply effect-btn" title="\u56DE\u590D"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" /> </svg> </span> `); controls.append(reply); controls.replaceAll(thankArea); }); } function nestedComments() { let i = 1; while (i < commentCells.length) { const cellDom = commentCells[i]; const { name, content } = commentData[i]; if (name === topicOwnerName) { cellDom.classList.add("owner"); } if (name === loginName) { cellDom.classList.add("self"); } if (content.includes("@")) { for (let j = i - 1; j >= 0; j--) { if (content.match(`@${commentData[j].name}`)) { cellDom.classList.add("responder"); commentCells[j].append(cellDom); break; } } } i++; } } function paging() { const notCommentCells = commentBox.find('> .cell:not([id^="r_"])'); if (notCommentCells.length <= 1) { return; } const pagingCells = notCommentCells.slice(1).addClass("v2p-paging"); const pageBtns = pagingCells.find(".super.button"); pageBtns.eq(0).addClass("v2p-prev-btn"); pageBtns.eq(1).addClass("v2p-next-btn"); } // src/web-scripts/index.ts { $("#Top .site-nav .tools > .top").addClass("effect-btn"); $("#Main .tab").addClass("effect-btn"); $("#Main .topic_buttons a.tb").addClass("effect-btn"); $("#Main .topic-link, .item_hot_topic_title > a, .item_node").attr("target", "_blank"); } addGlobalStyle(); replaceHeart(); setControls(); popular(); nestedComments(); paging();