增加隐藏目录按钮功能

main
落雨楓 2 years ago
parent f2ddee690a
commit bff7e4c49c

@ -2,7 +2,7 @@
"name": "Isekai Offcanvas Toc", "name": "Isekai Offcanvas Toc",
"namemsg": "isekai-offcanvastoc-name", "namemsg": "isekai-offcanvastoc-name",
"author": "Hyperzlib", "author": "Hyperzlib",
"version": "1.0.0", "version": "1.0.1",
"url": "https://www.isekai.cn", "url": "https://www.isekai.cn",
"descriptionmsg": "isekai-offcanvastoc-desc", "descriptionmsg": "isekai-offcanvastoc-desc",
"license-name": "MIT", "license-name": "MIT",
@ -36,6 +36,7 @@
"styles": ["ext.isekai.offcanvas-toc.less"], "styles": ["ext.isekai.offcanvas-toc.less"],
"dependencies": [ "dependencies": [
"oojs-ui-core", "oojs-ui-core",
"oojs-ui-toolbars",
"oojs-ui.styles.icons-layout" "oojs-ui.styles.icons-layout"
], ],
"targets": [ "targets": [
@ -43,7 +44,9 @@
"mobile" "mobile"
], ],
"messages": [ "messages": [
"isekai-offcanvastoc-description-item" "isekai-offcanvastoc-description-item",
"isekai-offcanvastoc-hide-menubutton",
"isekai-offcanvastoc-menubutton-hide-success"
] ]
} }
}, },

@ -3,5 +3,8 @@
"isekai-offcanvastoc-desc": "Show Offcanvas TOC on wiki", "isekai-offcanvastoc-desc": "Show Offcanvas TOC on wiki",
"prefs-offcanvas-toc": "Offcanvas TOC", "prefs-offcanvas-toc": "Offcanvas TOC",
"offcanvas-toc-enabled": "Show offcanvas TOC", "offcanvas-toc-enabled": "Show offcanvas TOC",
"isekai-offcanvastoc-description-item": "Description" "isekai-offcanvastoc-description-item": "Description",
"isekai-offcanvastoc-hide-menubutton": "Hide offcanvas TOC Button",
"isekai-offcanvastoc-menubutton-hide-success": "Offcanvas TOC button has been hidden, double click on the content area to show it again"
} }

@ -3,5 +3,8 @@
"isekai-offcanvastoc-desc": "在页面上显示悬浮目录", "isekai-offcanvastoc-desc": "在页面上显示悬浮目录",
"prefs-offcanvas-toc": "悬浮目录", "prefs-offcanvas-toc": "悬浮目录",
"offcanvas-toc-enabled": "显示悬浮目录", "offcanvas-toc-enabled": "显示悬浮目录",
"isekai-offcanvastoc-description-item": "简介" "isekai-offcanvastoc-description-item": "简介",
"isekai-offcanvastoc-hide-menubutton": "隐藏目录按钮",
"isekai-offcanvastoc-menubutton-hide-success": "目录按钮已隐藏,双击内容区域可以再次显示"
} }

@ -1,16 +1,52 @@
var headingList = []; var headingList = [];
var scrollBehaviorAvaliable = (function() { var scrollBehaviorAvaliable = (function() {
// 检测Chrome
var v = navigator.userAgent.match(/Chrome\/(?<version>\S+)/); var v = navigator.userAgent.match(/Chrome\/(?<version>\S+)/);
if (v && v.groups.version) { // 检测chrome版本 if (v && v.groups.version) {
var chromeVersion = parseInt(v.groups.version); var chromeVersion = parseInt(v.groups.version);
return chromeVersion >= 61; return chromeVersion >= 61;
} else { // 非chrome }
// 检测Firefox
v = navigator.userAgent.match(/Firefox\/(?<version>\S+)/);
if (v && v.groups.version) {
var firefoxVersion = parseInt(v.groups.version);
return firefoxVersion >= 36;
}
// 检测Safari
v = navigator.userAgent.match(/Version\/(?<version>\S+)/);
if (v && v.groups.version) { // Safari
var safariVersion = parseFloat(v.groups.version);
return safariVersion >= 14;
}
return false;
})();
var isMobileSafari = (function(){
v = navigator.userAgent.match(/Version\/(?<version>\S+) Mobile\/\S+/);
if (v && v.groups.version) { // Safari
return true; return true;
} }
return false;
})(); })();
var menuHidden = false;
var menuItems = [
{
label: mw.msg('isekai-offcanvastoc-hide-menubutton'),
onClick: () => {
$('#iseai-offcanvas-btn').hide();
menuHidden = true;
mw.notify( mw.msg('isekai-offcanvastoc-menubutton-hide-success'));
},
}
];
function getScrollOffset() { function getScrollOffset() {
if (mw.config.get('skin') === 'timeless' && $(window).width() > 850) { if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
return 60;
} else if (mw.config.get('skin') === 'minerva') {
return 60; return 60;
} else { } else {
return 10; return 10;
@ -18,7 +54,9 @@ function getScrollOffset() {
} }
function getAnchorOffset() { function getAnchorOffset() {
if (mw.config.get('skin') === 'timeless' && $(window).width() > 850) { if (mw.config.get('skin') === 'timeless' && window.innerWidth > 850) {
return 70;
} else if (mw.config.get('skin') === 'minerva') {
return 70; return 70;
} else { } else {
return 20; return 20;
@ -26,8 +64,10 @@ function getAnchorOffset() {
} }
function scrollToAnchor(link) { function scrollToAnchor(link) {
var target = $(link.replace(/\./g, '\\.')); var el = document.getElementById(link.replace(/^#/, ''));
if (target.length > 0) { if (el) {
var target = $(el);
function doScroll() { function doScroll() {
var position = target.offset().top - getScrollOffset(); var position = target.offset().top - getScrollOffset();
@ -103,7 +143,13 @@ function updateActive() {
} }
function openOffcanvas() { function openOffcanvas() {
$('#iseai-offcanvas-btn').show();
menuHidden = false;
let scrollbarWidth = getScrollbarWidth(); let scrollbarWidth = getScrollbarWidth();
$('#isekai-offcanvas-cover').removeClass('hidden');
window.requestAnimationFrame(function() {
$('body').addClass(['toc-offcanvas-show', 'toc-offcanvas-open']) $('body').addClass(['toc-offcanvas-show', 'toc-offcanvas-open'])
.css('margin-right', scrollbarWidth); .css('margin-right', scrollbarWidth);
$('#iseai-offcanvas-btn').css('margin-right', scrollbarWidth); $('#iseai-offcanvas-btn').css('margin-right', scrollbarWidth);
@ -117,18 +163,69 @@ function openOffcanvas() {
let targetY = Math.max(activedItem.eq(0).prop('offsetTop') - 50, 0); let targetY = Math.max(activedItem.eq(0).prop('offsetTop') - 50, 0);
$('#isekai-offcanvas-toc').scrollTop(targetY); $('#isekai-offcanvas-toc').scrollTop(targetY);
} }
});
} }
function closeOffcanvas() { function closeOffcanvas() {
if ($('#iseai-offcanvas-contextmenu').length > 0) {
$('#iseai-offcanvas-contextmenu').remove();
$('#isekai-offcanvas-cover').addClass('hidden');
} else {
$('body').removeClass('toc-offcanvas-open'); $('body').removeClass('toc-offcanvas-open');
setTimeout(function() { setTimeout(function() {
$('body').removeClass('toc-offcanvas-show').css('margin-right', 0); $('body').removeClass('toc-offcanvas-show').css('margin-right', 0);
$('#isekai-offcanvas-cover').addClass('hidden');
$('#iseai-offcanvas-btn').css('margin-right', 0); $('#iseai-offcanvas-btn').css('margin-right', 0);
if (mw.config.get('skin') === 'timeless') { if (mw.config.get('skin') === 'timeless') {
$('#mw-header-container').css('padding-right', 0); $('#mw-header-container').css('padding-right', 0);
} }
}, 260); }, 260);
} }
}
function openContextMenu(position) {
var menuContainer = document.createElement('div');
menuContainer.id = 'iseai-offcanvas-contextmenu';
menuContainer.className = 'oo-ui-toolGroup-tools oo-ui-popupToolGroup-tools oo-ui-listToolGroup-tools oo-ui-toolGroup-enabled-tools oo-ui-popupToolGroup-active-tools';
menuContainer.style.minWidth = 'unset';
// 设置弹出位置
menuContainer.style.position = 'fixed';
menuContainer.style.zIndex = 105;
menuContainer.style.right = position.x ? ($(window).width() - position.x) + 'px' : null;
menuContainer.style.bottom = position.y ? ($(window).height() - position.y) + 'px' : null;
function hideMenu() {
menuContainer.remove();
$('#isekai-offcanvas-cover').addClass('hidden');
}
menuItems.forEach((menuItem) => {
var menuElem = document.createElement('span');
menuElem.className = 'oo-ui-widget oo-ui-widget-enabled oo-ui-tool';
var menuLink = document.createElement('a');
menuLink.className = 'oo-ui-tool-link';
menuLink.tabIndex = 0;
menuLink.role = 'button';
menuLink.addEventListener('click', function(e) {
e.preventDefault();
menuItem.onClick();
hideMenu();
});
var menuLabel = document.createElement('span');
menuLabel.className = 'oo-ui-tool-title';
menuLabel.innerText = menuItem.label;
menuLink.appendChild(menuLabel);
menuElem.appendChild(menuLink);
menuContainer.appendChild(menuElem);
});
$('#isekai-offcanvas-cover').removeClass('hidden');
document.body.appendChild(menuContainer);
}
$(function() { $(function() {
// 创建目录dom // 创建目录dom
@ -136,8 +233,8 @@ $(function() {
<div id="isekai-offcanvas-toc" class="toc-offcanvas"> <div id="isekai-offcanvas-toc" class="toc-offcanvas">
<ul></ul> <ul></ul>
</div> </div>
<button role="button" id="iseai-offcanvas-btn" class="toc-offcanvas-btn" aria-label="Open float table of contents menu"></button> <a role="button" href="#" id="iseai-offcanvas-btn" class="toc-offcanvas-btn" aria-label="Open float table of contents menu"></a>
<div id="isekai-offcanvas-cover" class="toc-offcanvas-cover"></div> <div id="isekai-offcanvas-cover" class="toc-offcanvas-cover hidden"></div>
`); `);
var menuIcon = new OO.ui.IconWidget({ icon: 'menu' }); var menuIcon = new OO.ui.IconWidget({ icon: 'menu' });
$('#iseai-offcanvas-btn').append(menuIcon.$element); $('#iseai-offcanvas-btn').append(menuIcon.$element);
@ -207,11 +304,51 @@ $(function() {
closeOffcanvas(); closeOffcanvas();
}); });
$('#iseai-offcanvas-btn').on('click', function() { $('#iseai-offcanvas-btn').on('click', function(e) {
e.preventDefault();
updateActive(); updateActive();
openOffcanvas(); openOffcanvas();
}); });
var btnElem = $('#iseai-offcanvas-btn')[0];
btnElem.addEventListener('contextmenu', function(e) {
e.preventDefault();
if (e.clientX) {
openContextMenu({
x: e.clientX,
y: e.clientY
});
} else {
openContextMenu({
x: e.pageX - window.scrollX,
y: e.pageY - window.scrollY
});
}
});
if (isMobileSafari) {
// Safari下对长按的特殊处理
var longPressTimer;
btnElem.addEventListener('touchstart', function(e) {
longPressTimer = setTimeout(function() {
e.preventDefault();
openContextMenu({
x: e.pageX - window.scrollX,
y: e.pageY - window.scrollY
});
}, 200);
});
btnElem.addEventListener('touchend', function(e) {
if (longPressTimer) {
clearInterval(longPressTimer);
}
});
}
$('#isekai-offcanvas-toc ul .list-item').on('click', function(e) { $('#isekai-offcanvas-toc ul .list-item').on('click', function(e) {
// 点击链接 // 点击链接
e.preventDefault(); e.preventDefault();
@ -221,10 +358,16 @@ $(function() {
$('#isekai-offcanvas-toc ul .list-item').removeClass('active'); $('#isekai-offcanvas-toc ul .list-item').removeClass('active');
$(this).addClass('active'); $(this).addClass('active');
scrollToAnchor(target); scrollToAnchor(target);
if ($(window).width() < 550) { // 手机端,关闭抽屉 if (window.innerWidth < 550) { // 手机端,关闭抽屉
closeOffcanvas(); closeOffcanvas();
} }
} }
return false; return false;
}); });
$('#content').on('dblclick', function(e) {
if (menuHidden || window._openOffcanvasTocViaDblclick) {
openOffcanvas();
}
});
}); });

@ -74,8 +74,6 @@
.toc-offcanvas-cover { .toc-offcanvas-cover {
position: fixed; position: fixed;
visibility: hidden;
pointer-events: none;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
@ -85,6 +83,10 @@
z-index: 101; z-index: 101;
transition: opacity 250ms linear; transition: opacity 250ms linear;
will-change: opacity; will-change: opacity;
&.hidden {
display: none;
}
} }
.toc-offcanvas-btn { .toc-offcanvas-btn {
@ -107,6 +109,9 @@
background-color: rgba(255, 255, 255, 0.95); background-color: rgba(255, 255, 255, 0.95);
color: #333; color: #333;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12); box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12);
user-select: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
&:hover { &:hover {
background-color: rgba(255, 255, 255, 0.9); background-color: rgba(255, 255, 255, 0.9);
@ -120,6 +125,7 @@
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
right: 24px; right: 24px;
bottom: 15vh;
} }
@media screen and (min-width: 1340px) { @media screen and (min-width: 1340px) {
@ -138,11 +144,6 @@
body.toc-offcanvas-show { body.toc-offcanvas-show {
overflow-y: hidden; overflow-y: hidden;
.toc-offcanvas-cover {
visibility: visible;
pointer-events: auto;
}
.toc-offcanvas { .toc-offcanvas {
visibility: visible; visibility: visible;
} }

Loading…
Cancel
Save