油猴脚本:Whois信息卡片 2.0 - 大佬论坛

同步来源:树洞剪藏 源站剪藏 ID:245 原文地址:https://www.dalao.net/thread-38926.htm
油猴脚本:Whois信息卡片 2.0 - 大佬论坛
set 限制解除
网站指南 商家中心
发帖
搜索
消息 0
X (UID: 2618)
空间
退出
油猴脚本:Whois信息卡片 2.0
阿呆 ( UID: 1)
站长
14小时前 [复制链接]
465 15
更新:已适配进论坛系统,无需手动添加脚本
临时下线功能,切换使用 who.cx ? ,正在适配中
对论坛上帖子、评论提到的域名添加 “?”,并且在点击时弹出 whois 卡片信息。
该脚本使用了 https://who.0du.ru/ ? 的 whois 功能,本来想用 who.cx ? 的,但是有跨域限制。
一些细节没有优化,比如: 中文及 IDN 域名未添加识别;
卡片的加载显示时间取决于 who.0du.ru ? 的响应速度和存活情况。
修复:(该修复内容没有全部同步到下方脚本)
修复原域名含超链接时将卡片也加入超链接导致冲突问题;
修复将.php、.png 等文件识别成域名后缀问题;
修复将代码块中域名添加 “问号” 的问题;
修复 “?” 被错误的插入到路径中的问题;
修复域名存在超链接时问号无法点击的问题;
若干细节优化。
脚本内容:
// ==UserScript== // @name dalao.net 查询whois卡片 // @version 2.0 // @grant none // @description 在 dalao.net 上对域名点击时显示 whois 查询卡片 // @author 大佬论坛 // @match ://dalao.net/ // @match ://www.dalao.net/ // ==/UserScript==
( function ( ) { // 创建关闭按钮 function createCloseButton ( card ) { const closeButton = document . createElement ( 'button' ) ; closeButton . innerText = 'X' ; closeButton . style . position = 'absolute' ; closeButton . style . top = '0px' ; closeButton . style . right = '0px' ; closeButton . style . borderTopRightRadius = '0.6rem' ; closeButton . style . backgroundColor = 'red' ; closeButton . style . color = 'white' ; closeButton . style . border = 'none' ; closeButton . style . cursor = 'pointer' ; closeButton . style . padding = '0px 6px' ; closeButton . addEventListener ( 'click' , ( event ) => { card . style . display = 'none' ; event . stopPropagation ( ) ; // 阻止事件冒泡,防止关闭卡片时误触发点击外部事件 } ) ; return closeButton ; }
function loadExternalCSS ( ) { const style = document . createElement ( 'style' ) ; style . innerHTML = ` .text-sm { font-size: .875rem; line-height: 1.25rem; } .whitespace-pre-wrap { white-space: pre-wrap; } .w-full { width: 100%; } .text-secondary { color: #6b6b74; } .text-xs { font-size: .75rem; line-height: 1rem; } .py-0\.5 { padding-top: .125rem; padding-bottom: .125rem; } .px-1 { padding-left: .25rem; padding-right: .25rem; } .border { border-width: 1px; } .rounded { border-radius: .25rem; } .whitespace-nowrap { white-space: nowrap; } .items-center { align-items: center; } .flex-nowrap { flex-wrap: nowrap; } .flex-row { flex-direction: row; } .cursor-pointer { cursor: pointer; } .inline-flex { display: inline-flex; } .m-0\.5 { margin: .125rem; } .w-2\.5 { width: .625rem; } .h-2\.5 { height: .625rem; } .mr-1 { margin-right: .25rem; } .shrink-0 { flex-shrink: 0; } .w-3 { width: .75rem; } .h-3 { height: .75rem; } .w-3\.5 { width: .875rem; } .h-3\.5 { height: .875rem; } .inline { display: inline; } .ml-1\.5 { margin-left: .375rem; }
` ; document . head . appendChild ( style ) ; }
// 创建显示 WHOIS 信息的卡片 function createHoverCard ( domain ) { const card = document . createElement ( 'div' ) ; card . className = 'rounded-lg border bg-card text-card-foreground shadow' ; card . style . position = 'absolute' ; card . style . zIndex = '29' ; // 确保卡片显示在最上层 card . style . backgroundColor = 'white' ; card . style . border = '1px solid black' ; card . style . padding = '0 0 10px 0;' ; card . style . display = 'none' ; card . style . borderRadius = '0.6rem' ;
// 添加可拖动栏 const dragBar = document . createElement ( 'div' ) ; dragBar . style . backgroundColor = '#f0f0f0' ; dragBar . style . borderTopLeftRadius = '0.6rem' ; dragBar . style . borderTopRightRadius = '0.6rem' ; dragBar . style . padding = '10px' ; dragBar . style . cursor = 'move' ; dragBar . style . borderBottom = '1px solid #ccc' ; card . appendChild ( dragBar ) ;
const closeButton = createCloseButton ( card ) ; dragBar . appendChild ( closeButton ) ;
const contentDiv = document . createElement ( 'div' ) ; contentDiv . style . width = '300px' ; contentDiv . style . height = '200px' ; contentDiv . style . overflowY = 'auto' ; card . appendChild ( contentDiv ) ;
// 实现拖动功能 let offsetX , offsetY ; dragBar . addEventListener ( 'mousedown' , ( e ) => { offsetX = e . clientX - card . offsetLeft ; offsetY = e . clientY - card . offsetTop ; document . addEventListener ( 'mousemove' , mouseMoveHandler ) ; document . addEventListener ( 'mouseup' , mouseUpHandler ) ; } ) ;
function mouseMoveHandler ( e ) { card . style . left = ( e . clientX - offsetX ) + 'px' ; card . style . top = ( e . clientY - offsetY ) + 'px' ; }
function mouseUpHandler ( ) { document . removeEventListener ( 'mousemove' , mouseMoveHandler ) ; document . removeEventListener ( 'mouseup' , mouseUpHandler ) ; }
// 加载 WHOIS 信息并插入卡片 const loadWhois = async ( ) => { if ( contentDiv . innerHTML === '' ) { try { // 加载外部 CSS loadExternalCSS ( ) ;
const response = await fetch ( https://who.0du.ru/ ${ domain } ) ;
const text = await response . text ( ) ;
const parser = new DOMParser ( ) ;
const doc = parser . parseFromString ( text , 'text/html' ) ;
// 提取 whois 信息,并将其放入指定的表格容器内 const whoisTable = doc . querySelector ( 'table.w-full.text-sm.mb-4.whitespace-pre-wrap' ) ; if ( whoisTable ) { contentDiv . innerHTML = '' ; // 清空当前内容 contentDiv . appendChild ( whoisTable ) ; // 插入 WHOIS 信息的表格 } else { contentDiv . innerHTML = '无法获取 WHOIS 信息' ; } } catch ( error ) { contentDiv . innerHTML = '请求失败' ; } } } ;
// 点击卡片外部关闭卡片 const closeOnClickOutside = ( event ) => { if ( ! card . contains ( event . target ) ) { card . style . display = 'none' ; document . removeEventListener ( 'click' , closeOnClickOutside ) ; } } ;
document . addEventListener ( 'click' , closeOnClickOutside ) ;
return { card , loadWhois } ; }
// 查找文本节点并处理 function findTextNodesInContainers ( containers ) { const textNodes = [ ] ; containers . forEach ( container => { // 如果容器本身是 ,直接跳过 if ( container . matches ( 'pre' ) || container . closest ( 'pre' ) ) { return ; }
const walker = document . createTreeWalker ( container , NodeFilter . SHOW_TEXT , null , false ) ; let node ; while ( node = walker . nextNode ( ) ) { // 如果文本节点的父节点是 ,跳过 if ( ! node . parentNode . closest ( 'pre' ) ) { textNodes . push ( node ) ; } } } ) ; return textNodes ; }
// 验证域名是否有效 function isValidDomain ( domain , validTLDs ) { const domainParts = domain . split ( '.' ) ; const tld = domainParts [ domainParts . length - 1 ] ; return validTLDs . has ( tld . toLowerCase ( ) ) ; }
// 添加问号图标并绑定点击事件 async function addQuestionMarkToDomains ( textNode , validTLDs ) { const text = textNode . nodeValue ; const domainRegex = / \ b ( ? : [ a - z0 - 9 - ] + \ . ) + [ a - z0 - 9 ] { 2 , 6 } ( ? ! \ . [ a - z0 - 9 ] { 2 , 6 } ) \b / gi ; const matches = [ ... text . matchAll ( domainRegex ) ] ;
if ( matches . length ) { const span = document . createElement ( 'span' ) ; const parts = [ ] ; let lastIndex = 0 ;
matches . forEach ( match => { parts . push ( text . slice ( lastIndex , match . index ) ) ; // 插入前半部分 const domain = match [ 0 ] ;
// 验证域名是否有效 if ( isValidDomain ( domain , validTLDs ) ) { const parentAnchor = textNode . parentNode . closest ( 'a' ) ;
if ( parentAnchor ) { // 如果域名在超链接中,不替换内容,而是在超链接外部插入问号 const questionMark = document . createElement ( 'span' ) ; questionMark . textContent = '?' ; questionMark . style . marginLeft = '4px' ; questionMark . style . cursor = 'pointer' ; questionMark . style . color = 'blue' ; questionMark . addEventListener ( 'click' , ( event ) => { event . stopPropagation ( ) ;
// 创建并显示 WHOIS 卡片
const { card , loadWhois } = createHoverCard ( domain ) ;
document . body . appendChild ( card ) ;
card . style . display = 'block' ;
card . style . left = ${ event . pageX + 10 } px ;
card . style . top = ${ event . pageY + 10 } px ;
loadWhois ( ) ;
} ) ;
// 如果问号不存在,则插入到超链接后方 if ( ! parentAnchor . nextSibling || parentAnchor . nextSibling . textContent !== '?' ) { parentAnchor . insertAdjacentElement ( 'afterend' , questionMark ) ; } } else { // 如果域名不在超链接中,按原逻辑处理 const spanDomain = document . createElement ( 'span' ) ; spanDomain . textContent = domain ;
const questionMark = document . createElement ( 'span' ) ; questionMark . textContent = '?' ; questionMark . style . marginLeft = '4px' ; questionMark . style . cursor = 'pointer' ; questionMark . style . color = 'blue' ; questionMark . addEventListener ( 'click' , ( event ) => { event . stopPropagation ( ) ;
// 创建并显示 WHOIS 卡片
const { card , loadWhois } = createHoverCard ( domain ) ;
document . body . appendChild ( card ) ;
card . style . display = 'block' ;
card . style . left = ${ event . pageX + 10 } px ;
card . style . top = ${ event . pageY + 10 } px ;
loadWhois ( ) ;
} ) ;
const containerSpan = document . createElement ( 'span' ) ; containerSpan . appendChild ( spanDomain ) ; containerSpan . appendChild ( questionMark ) ;
parts . push ( containerSpan ) ; } } else { parts . push ( domain ) ; // 如果不是有效域名,保持原样 } lastIndex = match . index + domain . length ; } ) ;
parts . push ( text . slice ( lastIndex ) ) ; span . append ( ... parts ) ;
// 替换原始文本节点 if ( ! textNode . parentNode . closest ( 'a' ) ) { textNode . replaceWith ( span ) ; } } }
// 获取所有包含文本的容器 const containers = Array . from ( document . querySelectorAll ( '.message.break-all.box-shadow, .message.mt-1.break-all' ) ) ;
// 下载域名后缀名单 async function fetchValidTLDs ( ) { try { const response = await fetch ( 'https://www.dalao.net/lunbo/domain.txt' ) ; const text = await response . text ( ) ; const validTLDs = new Set ( text . trim ( ) . split ( ' ' ) . map ( tld => tld . toLowerCase ( ) ) ) ; return validTLDs ; } catch ( error ) { console . error ( 'Failed to fetch valid TLDs:' , error ) ; return new Set ( ) ; // 返回空集以防后续错误 } }
// 初始化并处理文本节点 fetchValidTLDs ( ) . then ( validTLDs => { const textNodes = findTextNodesInContainers ( containers ) ; textNodes . forEach ( textNode => { addQuestionMarkToDomains ( textNode , validTLDs ) ; } ) ; } ) ; } ) ( ) ;
JavaScript 复制
啊?????
已有评论 ( 15 )
只看楼主
倒序
mrma ( UID: 5047)
@Ta
14小时前
(米表 https://miuu.top )
1 楼
用上了。感谢大佬
回复
" title=举报> 举报
阿呆 ( UID: 1)
站长
楼主
@Ta
13小时前
(啊?????)
2 楼
mrma
用上了。感谢大佬
更新了一下,修复一些问题
回复
mrma
用上了。感谢大佬
更新了一下,修复一些问题 ' title=举报> 举报
阿呆 ( UID: 1)
站长
楼主
@Ta
10小时前
(啊?????)
3 楼
已适配进论坛
回复
" title=举报> 举报
hello ( UID: 212)
@Ta
7小时前
(米表https://tt.ax/)
4 楼
好东西
回复
" title=举报> 举报
心 ( UID: 35)
@Ta
7小时前
(域名滞销,请帮帮我们 di.bi!)
5 楼
👍👍👍
回复
" title=举报> 举报
一夜七次郎 ( UID: 520)
赞助会员
@Ta
6小时前
(米表 hupo.cc)
6 楼
加iframe白名单了
回复
" title=举报> 举报
郡主 ( UID: 1686)
@Ta
6小时前
7 楼
好
回复
" title=举报> 举报
shuai ( UID: 2782)
@Ta
5小时前
(米表222.domains低价收单字国别Wx:691699)
8 楼
这个小?手机版的时候不太容易点到
回复
" title=举报> 举报
王德发 ( UID: 5183)
@Ta
4小时前
9 楼
测试 qq.com ?
回复
" title=举报> 举报
阿呆 ( UID: 1)
站长
楼主
@Ta
2小时前
(啊?????)
10 楼
一夜七次郎
加iframe白名单了
好,暂时就用那个了,等那个老哥的死了换你的
回复
一夜七次郎
加iframe白名单了
好,暂时就用那个了,等那个老哥的死了换你的 " title=举报> 举报
小归客 ( UID: 1719)
@Ta
2小时前
(更多源码,请关注ID977,联系QQ:9892054)
11 楼
有这个,都没人去查whois了
回复
" title=举报> 举报
BigDick ( UID: 4667)
@Ta
1小时前
12 楼
坛友们 我想问问 阿呆为啥这么nb
回复
" title=举报> 举报
清玖 ( UID: 4748)
@Ta
1小时前
13 楼
真的很方便
回复
" title=举报> 举报
shuai ( UID: 2782)
@Ta
1小时前
(米表222.domains低价收单字国别Wx:691699)
14 楼
搞个后备,省的出问题措手不及
回复
" title=举报> 举报
mrma ( UID: 5047)
@Ta
2分钟前
(米表 https://miuu.top )
15 楼
像这样的在打开时会在网址里面添加?,转过去是打不开的
回复
像这样的在打开时会在网址里面添加?,转过去是打不开的 ' title=举报> 举报
X
16 楼
回帖 [表情]
高级回复
创建新帖
阿呆
UID:1 王富贵
站长
1783
主题数
6434
评论数
15
推荐数
私信
Tips: 侮辱谩骂,永久封号!
广告推广 ( 点击空位自助购买 )
狗云服务器 流量变现 莆田潮牌鞋 权益兑换 木啊 吾爱博客 NET双拼米表 单字符域名 域名论坛
服务器赞助: 狗云 / 智联 © 始于2020.10.10 大佬论坛 Time: 0.127, SQL: 108
小黑屋 | 支持我们 | 规范 | 关于 | FAQ | 群组
| 订阅
| 友链 | 酷站 | Xiuno驱动
IP检测信息 刷新IP信息 展开信息 查询IP
展开信息
验证码
拖动下方滑块完成拼图
确定 '>