// ==UserScript==
// @name 返回顶部和底部-美化版
// @version 1.1.0
// @description 一个很漂亮的可返回顶部或底部的可拖拽的按钮,支持忽略网站和右键菜单
// @author 沐雨
// @license MIT
// @match *://*/*
// @grant GM_info
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_getResourceText
// @require http://code.jquery.com/jquery-1.11.0.min.js
// @namespace https://www.yuxi.com/
// @downloadURL none
// ==/UserScript==
; (function () {
'use strict'
// 检查是否在iframe中运行
if (window.self !== window.top) {
// 在iframe中运行,不执行脚本
return;
}
// 检查当前网站是否在忽略列表中
const currentHost = window.location.hostname;
const ignoredSites = JSON.parse(localStorage.getItem('btnScript_ignoredSites') || '[]');
// 如果当前网站在忽略列表中,则不执行脚本
if (ignoredSites.includes(currentHost)) {
return;
}
var TBLink = function () {
var $ = $ || window.$
var $doc = $(document)
var $win = $(window)
// const iconFont = GM_getResourceText('css')
var CreateHtml = function () {
var html = `
`
$('html body').append(html)
// 添加右键菜单
$('#goTopBottom').on('contextmenu', showContextMenu);
}
// 创建右键菜单
var createContextMenu = function() {
var menu = $('').css({
position: 'absolute',
background: 'white',
border: '1px solid #ccc',
borderRadius: '5px',
boxShadow: '0 2px 5px rgba(0,0,0,0.2)',
padding: '5px 0',
zIndex: 10000,
display: 'none'
});
// 创建关闭选项
var closeOption = $('关闭按钮
').css({
padding: '8px 15px',
cursor: 'pointer'
}).hover(
function() { $(this).css('backgroundColor', '#f5f5f5'); },
function() { $(this).css('backgroundColor', 'white'); }
).click(hideScrollButtons);
// 创建忽略网站选项
var ignoreOption = $('忽略此网站
').css({
padding: '8px 15px',
cursor: 'pointer'
}).hover(
function() { $(this).css('backgroundColor', '#f5f5f5'); },
function() { $(this).css('backgroundColor', 'white'); }
).click(ignoreCurrentSite);
menu.append(closeOption).append(ignoreOption);
$('body').append(menu);
return menu;
}
// 显示右键菜单
var showContextMenu = function(e) {
e.preventDefault();
var menu = $('#gtb-context-menu');
if (menu.length === 0) {
menu = createContextMenu();
}
// 设置菜单位置
menu.css({
left: e.clientX + 'px',
top: e.clientY + 'px',
display: 'block'
});
// 点击其他区域关闭菜单
setTimeout(function() {
$(document).one('click', function() {
menu.hide();
});
}, 100);
}
// 隐藏滚动按钮
var hideScrollButtons = function() {
$('#goTopBottom').hide();
}
// 忽略当前网站
var ignoreCurrentSite = function() {
var currentHost = window.location.hostname;
var ignoredSites = JSON.parse(localStorage.getItem('btnScript_ignoredSites') || '[]');
// 添加当前网站到忽略列表
if (!ignoredSites.includes(currentHost)) {
ignoredSites.push(currentHost);
localStorage.setItem('btnScript_ignoredSites', JSON.stringify(ignoredSites));
}
// 隐藏按钮
hideScrollButtons();
}
var CreateStyle = function () {
var style =
'#goTopBottom {position: fixed;bottom: 75px;right: 15px;z-index: 999999;display: flex;flex-direction: column;row-gap: 5px; opacity: 0.7; transition: opacity 0.3s;}' +
'#goTopBottom:hover {opacity: 1;}' +
'#goTopBottom .top {opacity: 0;}' +
'#goTopBottom .t-btn {display: flex;justify-content: center;align-items: center;width: 40px;height: 40px;cursor: pointer;color: #fff;border-radius: 4px;background-image: linear-gradient(to top right,#6966ff,#37e2d3);background-size: 100% 100%;background-color: transparent;}' +
'#goTopBottom .bottom {opacity: 0;}'
// GM_addStyle(iconFont)
GM_addStyle(style)
}
var GoTB = function () {
var upperLimit = 100
var scrollSpeed = 500
var fadeSpeed = 300
var $top = $('#goTopBottom .gotop')
var $bottom = $('#goTopBottom .bottom')
if (getScrollTop() > upperLimit) {
$top.stop().fadeTo(0, 1, function () {
$top.show()
})
}
if (getScrollTop() + $(window).height() < $doc.height() - upperLimit) {
$bottom.stop().fadeTo(0, 1, function () {
$bottom.show()
})
}
$doc.scroll(function () {
if (getScrollTop() > upperLimit) {
$top.stop().fadeTo(fadeSpeed, 1, function () {
$top.css('visibility', 'visible')
})
} else {
$top.stop().fadeTo(fadeSpeed, 0, function () {
$top.css('visibility', 'hidden')
})
}
if (getScrollTop() + $(window).height() < $doc.height() - upperLimit) {
$bottom.stop().fadeTo(fadeSpeed, 1, function () {
$bottom.css('visibility', 'visible')
})
} else {
$bottom.stop().fadeTo(fadeSpeed, 0, function () {
$bottom.css('visibility', 'hidden')
})
}
})
$('#goTopBottom span').click(function () {
var $this = $(this)
var clsName = $this.attr('class')
// 改进的滚动处理,处理懒加载内容
if (clsName.includes('gotop')) {
// 滚动到顶部
$('html, body').animate({
scrollTop: 0
}, scrollSpeed)
} else {
// 滚动到底部,处理懒加载内容
const maxScrollHeight = Math.max(
document.body.scrollHeight,
document.body.offsetHeight,
document.documentElement.clientHeight,
document.documentElement.scrollHeight,
document.documentElement.offsetHeight
);
$('html, body').animate({
scrollTop: maxScrollHeight
}, scrollSpeed)
}
return false
})
}
var getScrollTop = function () {
var scrollTop = $doc.scrollTop() || $('html,body').scrollTop()
return scrollTop
}
/**
* 拖拽
*/
function dragging() {
// 跟踪是否刚刚完成拖拽操作
let justDragged = false;
let dragThreshold = 5; // 拖拽阈值,移动超过这个距离才算拖拽
var position = GM_getValue('gtb_pos') || {}
var $gtbBox = $('#goTopBottom');
$('#goTopBottom')
.off('.gtb')
.on({
'mousedown.gtb': function (el) {
if (el.button !== 0) return; // 只在左键点击时处理
var move = true
var startX = el.pageX
var startY = el.pageY
var startLeft = $gtbBox.offset().left
var startTop = $gtbBox.offset().top
var movedDistance = 0
$doc.on({
'mousemove.gtb': function (docEl) {
if (move) {
var deltaX = docEl.pageX - startX
var deltaY = docEl.pageY - startY
movedDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
// 如果移动距离超过阈值,则认为是拖拽
if (movedDistance > dragThreshold) {
justDragged = true
$gtbBox.offset({
left: startLeft + deltaX,
top: startTop + deltaY
})
}
}
},
'mouseup.gtb': function () {
move = false
$doc.off('.gtb')
// 如果是拖拽操作,延迟重置justDragged标志
if (justDragged) {
setTimeout(function() {
justDragged = false
}, 300) // 300ms后重置,防止误触
}
}
})
}
});
// 修改点击事件,防止拖拽后误触发点击
$('#goTopBottom span').on('click', function(e) {
if (justDragged) {
e.preventDefault()
e.stopPropagation()
return false
}
})
}
this.init = function () {
CreateStyle()
CreateHtml()
dragging()
GoTB()
}
}
var tbl = new TBLink()
tbl.init()
})()