MediaWiki:Gadget-ScrollUpButton.js:修订间差异
外观
删除的内容 添加的内容
创建页面,内容为“→* * Copyright (c) 2021-present, 安忆. * * @author 安忆 [[zh:U:安忆]] * @file scrollUpButton.js * @license GPL v3: $(function scrollUpButton() { var $window = $(window); var scrollButtonIcon = '//zybkcn.com/w/images/5/59/Font_Awesome_5_regular_arrow-circle-up_blue.svg'; if (!document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image', '1.1')) { scrollButtonIcon = '//zybkcn.com/w/images/5/59/Font_Awesome_5_regular_arrow…” |
重构:节流优化、移除 dead code、修复动画堆积 |
||
| 第8行: | 第8行: | ||
$(function scrollUpButton() { |
$(function scrollUpButton() { |
||
var $window = $(window); |
var $window = $(window); |
||
var |
var icon = mw.config.get('wgServer') + '/w/images/5/59/Font_Awesome_5_regular_arrow-circle-up_blue.svg'; |
||
var visible = false; |
|||
if (!document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#Image', '1.1')) { |
|||
scrollButtonIcon = '//zybkcn.com/w/images/5/59/Font_Awesome_5_regular_arrow-circle-up_blue.svg/32px-Font_Awesome_5_regular_arrow-circle-up_blue.svg.png'; |
|||
function scrollTo(h) { |
|||
$('html, body').stop(true, true).animate({ scrollTop: h }, 500); |
|||
} |
} |
||
var changeOpacity = function changeOpacity(event) { |
|||
function makeBtn(id, onClick, extraCss) { |
|||
event.currentTarget.style.opacity = event.type === 'mouseenter' ? '1' : '0.7'; |
|||
return $('<img>') |
|||
}; |
|||
.addClass('noprint') |
|||
var scrollTop = function scrollTop(height) { |
|||
.attr({ id: id, src: icon, draggable: 'false' }) |
|||
$('html, body').animate({ |
|||
.css({ |
|||
display: 'none', |
|||
}, 660); |
|||
position: 'fixed', |
|||
}; |
|||
right: '18px', |
|||
var $scrollButton = $('<img>').addClass('noprint').attr({ |
|||
cursor: 'pointer', |
|||
opacity: '0.7', |
|||
src: scrollButtonIcon |
|||
width: '40px', |
|||
}).css({ |
|||
zIndex: 9999, |
|||
'-moz-user-select': 'none', |
|||
'-webkit-user-select': 'none', |
|||
'user-select': 'none', |
|||
transition: 'opacity 0.2s', |
|||
...extraCss |
|||
'-moz-user-select': 'none', |
|||
}) |
|||
'-webkit-user-select': 'none', |
|||
.on('mouseenter', function () { this.style.opacity = '1'; }) |
|||
'user-select': 'none' |
|||
.on('mouseleave', function () { this.style.opacity = '0.7'; }) |
|||
}); |
|||
.on('click', onClick) |
|||
var $scrollDownButton = $scrollButton.clone().attr('id', 'scrollDownButton-zhwiki').css('transform', 'rotate(180deg)').on('click', function () { |
|||
.appendTo(document.body); |
|||
scrollTop(($(document).height() || 0) - ($window.height() || 0)); |
|||
} |
} |
||
var $scrollUpButton = $scrollButton.clone().attr('id', 'scrollUpButton-zhwiki').on('click', function () { |
|||
var $up = makeBtn('scrollUpBtn', function () { scrollTo(0); }, { bottom: '85px' }); |
|||
scrollTop(0); |
|||
var $down = makeBtn('scrollDownBtn', function () { |
|||
}); |
|||
scrollTo(($(document).height() || 0) - ($window.height() || 0)); |
|||
var $elements = [$scrollDownButton, $scrollUpButton]; |
|||
}, { bottom: '45px', transform: 'rotate(180deg)' }); |
|||
$elements.forEach(function ($element) { |
|||
$element.on('mouseenter mouseleave', changeOpacity).appendTo(document.body); |
|||
var $elements = $up.add($down); |
|||
}); |
|||
var fadeIn = function fadeIn() { |
|||
function setLeft(px) { |
|||
$elements.css('left', px ? px + 'px' : 'unset'); |
|||
$element.fadeIn('slow'); |
|||
} |
|||
}; |
|||
function setRight(px) { |
|||
$elements. |
$elements.css('right', px ? px + 'px' : 'unset'); |
||
} |
|||
$element.fadeOut('slow'); |
|||
}); |
|||
var isVector2022 = mw.config.get('skin') === 'vector-2022'; |
|||
}; |
|||
var |
var mql = window.matchMedia('(min-width: 1400px)'); |
||
$elements.forEach(function ($element) { |
|||
function onWidthChange(e) { |
|||
$element.css('left', px ? px + 'px' : 'unset'); |
|||
if (isVector2022) { |
|||
setRight(e.matches ? 8 : 18); |
|||
}; |
|||
} |
|||
var right = function right(px) { |
|||
} |
|||
$elements.forEach(function ($element) { |
|||
$element.css('right', px ? px + 'px' : 'unset'); |
|||
if (isVector2022) { |
|||
}); |
|||
}; |
|||
var mediaQueryList = window.matchMedia('(min-width: 1400px)'); |
|||
var isVector2022Match = false; |
|||
if (mw.config.get('skin') === 'vector-2022') { |
|||
var mediaQueryHandler = function mediaQueryHandler(event) { |
|||
if (event.matches) { |
|||
isVector2022Match = true; |
|||
right(8); |
|||
} else { |
|||
isVector2022Match = false; |
|||
right(18); |
|||
} |
|||
}; |
|||
// Check mediaQueryList as Safari doesn't have support for mediaQueryList.addEventListener |
|||
try { |
try { |
||
mql.addEventListener('change', onWidthChange); |
|||
} catch ( |
} catch (_) { |
||
mql.addListener(onWidthChange); |
|||
} |
|||
if (mediaQueryList.matches) { |
|||
isVector2022Match = true; |
|||
right(8); |
|||
} |
} |
||
onWidthChange(mql); |
|||
} |
} |
||
var scrollButtonTimer; |
|||
function onScroll() { |
|||
var |
var y = $window.scrollTop() || 0; |
||
var vector2022Height = isVector2022Match ? 24 : 0; |
|||
if (y > 200 && !visible) { |
|||
$scrollDownButton.css('bottom', dingHeight + vector2022Height + 24 + 'px'); |
|||
visible = true; |
|||
$scrollUpButton.css('bottom', dingHeight + vector2022Height + 65 + 'px'); |
|||
$elements.fadeIn(300); |
|||
if (mw.config.get('wgGEHelpPanelEnabled') && $('#mw-ge-help-panel-cta-button').length || $('#cat_a_lot').length || $('#proveit').length || $('.wordcount').length) { |
|||
} else if (y <= 200 && visible) { |
|||
left(10); |
|||
visible = false; |
|||
$elements.fadeOut(300); |
|||
} |
} |
||
var windowScrollTop = $window.scrollTop() || 0; |
|||
if ( |
if ( |
||
(mw.config.get('wgGEHelpPanelEnabled') && $('#mw-ge-help-panel-cta-button').length) || |
|||
fadeIn(); |
|||
$('#cat_a_lot').length || |
|||
$('#proveit').length || |
|||
$('.wordcount').length |
|||
) { |
|||
setLeft(10); |
|||
} else { |
} else { |
||
setLeft(); |
|||
} |
|||
} |
|||
var ticking = false; |
|||
$window.on('scroll', function () { |
|||
if (!ticking) { |
|||
requestAnimationFrame(function () { |
|||
onScroll(); |
|||
ticking = false; |
|||
}); |
|||
ticking = true; |
|||
} |
} |
||
clearTimeout(scrollButtonTimer); |
|||
scrollButtonTimer = setTimeout(fadeOut, 2000); |
|||
}); |
|||
$elements.forEach(function ($element) { |
|||
$element.on('mouseenter', function () { |
|||
clearTimeout(scrollButtonTimer); |
|||
}); |
|||
}); |
}); |
||
onScroll(); |
|||
}); |
}); |
||
2026年6月12日 (五) 19:30的版本
/**
* Copyright (c) 2021-present, 安忆.
*
* @author 安忆 [[zh:U:安忆]]
* @file scrollUpButton.js
* @license GPL v3
*/
$(function scrollUpButton() {
var $window = $(window);
var icon = mw.config.get('wgServer') + '/w/images/5/59/Font_Awesome_5_regular_arrow-circle-up_blue.svg';
var visible = false;
function scrollTo(h) {
$('html, body').stop(true, true).animate({ scrollTop: h }, 500);
}
function makeBtn(id, onClick, extraCss) {
return $('<img>')
.addClass('noprint')
.attr({ id: id, src: icon, draggable: 'false' })
.css({
display: 'none',
position: 'fixed',
right: '18px',
cursor: 'pointer',
opacity: '0.7',
width: '40px',
zIndex: 9999,
'-moz-user-select': 'none',
'-webkit-user-select': 'none',
'user-select': 'none',
transition: 'opacity 0.2s',
...extraCss
})
.on('mouseenter', function () { this.style.opacity = '1'; })
.on('mouseleave', function () { this.style.opacity = '0.7'; })
.on('click', onClick)
.appendTo(document.body);
}
var $up = makeBtn('scrollUpBtn', function () { scrollTo(0); }, { bottom: '85px' });
var $down = makeBtn('scrollDownBtn', function () {
scrollTo(($(document).height() || 0) - ($window.height() || 0));
}, { bottom: '45px', transform: 'rotate(180deg)' });
var $elements = $up.add($down);
function setLeft(px) {
$elements.css('left', px ? px + 'px' : 'unset');
}
function setRight(px) {
$elements.css('right', px ? px + 'px' : 'unset');
}
var isVector2022 = mw.config.get('skin') === 'vector-2022';
var mql = window.matchMedia('(min-width: 1400px)');
function onWidthChange(e) {
if (isVector2022) {
setRight(e.matches ? 8 : 18);
}
}
if (isVector2022) {
try {
mql.addEventListener('change', onWidthChange);
} catch (_) {
mql.addListener(onWidthChange);
}
onWidthChange(mql);
}
function onScroll() {
var y = $window.scrollTop() || 0;
if (y > 200 && !visible) {
visible = true;
$elements.fadeIn(300);
} else if (y <= 200 && visible) {
visible = false;
$elements.fadeOut(300);
}
if (
(mw.config.get('wgGEHelpPanelEnabled') && $('#mw-ge-help-panel-cta-button').length) ||
$('#cat_a_lot').length ||
$('#proveit').length ||
$('.wordcount').length
) {
setLeft(10);
} else {
setLeft();
}
}
var ticking = false;
$window.on('scroll', function () {
if (!ticking) {
requestAnimationFrame(function () {
onScroll();
ticking = false;
});
ticking = true;
}
});
onScroll();
});