树洞剪藏#剪藏#树洞剪藏

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

2024 年 12 月 5 日1 分钟
分享Twitter / XTelegram微博

同步来源:树洞剪藏 源站剪藏 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

展开信息

验证码

拖动下方滑块完成拼图

确定 '>

相关文章