gitcat
1/* gitcat 前端交互:移动端菜单、用户菜单、提示条、复制与确认。 */
2(function () {
3 'use strict';
4
5 function $(sel, root) { return (root || document).querySelector(sel); }
6 function $$(sel, root) { return Array.prototype.slice.call((root || document).querySelectorAll(sel)); }
7
8 /* ---------------------------------------------------------- 移动端顶部菜单 */
9 var topbar = $('.topbar');
10 var navtoggle = $('.navtoggle');
11 if (topbar && navtoggle) {
12 navtoggle.addEventListener('click', function (e) {
13 e.stopPropagation();
14 var open = topbar.classList.toggle('open');
15 navtoggle.setAttribute('aria-expanded', open ? 'true' : 'false');
16 navtoggle.setAttribute('aria-label', open ? '关闭菜单' : '打开菜单');
17 });
18 }
19
20 /* ------------------------------------------------------------ 用户下拉菜单 */
21 var usermenu = $('.usermenu');
22 var userbtn = usermenu ? $('.userbtn', usermenu) : null;
23 if (usermenu && userbtn) {
24 userbtn.addEventListener('click', function (e) {
25 e.stopPropagation();
26 var open = usermenu.classList.toggle('open');
27 userbtn.setAttribute('aria-expanded', open ? 'true' : 'false');
28 });
29 }
30
31 document.addEventListener('click', function () {
32 if (usermenu) usermenu.classList.remove('open');
33 if (topbar && topbar.classList.contains('open')) {
34 topbar.classList.remove('open');
35 if (navtoggle) {
36 navtoggle.setAttribute('aria-expanded', 'false');
37 navtoggle.setAttribute('aria-label', '打开菜单');
38 }
39 }
40 });
41 document.addEventListener('keydown', function (e) {
42 if (e.key !== 'Escape') return;
43 if (usermenu) usermenu.classList.remove('open');
44 if (topbar) topbar.classList.remove('open');
45 });
46
47 /* ---------------------------------------------------------------- 提示条 */
48 $$('.flash-x').forEach(function (btn) {
49 btn.addEventListener('click', function () {
50 var box = btn.closest('.flash');
51 if (box) box.remove();
52 });
53 });
54
55 /* ------------------------------------------------------- 危险操作二次确认 */
56 $$('form[data-confirm]').forEach(function (form) {
57 form.addEventListener('submit', function (e) {
58 if (!window.confirm(form.getAttribute('data-confirm'))) e.preventDefault();
59 });
60 });
61
62 /* ---------------------------------------------------------------- 复制按钮 */
63 function copyText(text) {
64 if (navigator.clipboard && window.isSecureContext) {
65 return navigator.clipboard.writeText(text);
66 }
67 return new Promise(function (resolve, reject) {
68 var ta = document.createElement('textarea');
69 ta.value = text;
70 ta.setAttribute('readonly', '');
71 ta.style.position = 'fixed';
72 ta.style.opacity = '0';
73 document.body.appendChild(ta);
74 ta.select();
75 try {
76 document.execCommand('copy') ? resolve() : reject();
77 } catch (err) {
78 reject(err);
79 } finally {
80 document.body.removeChild(ta);
81 }
82 });
83 }
84
85 $$('[data-copy]').forEach(function (btn) {
86 var label = btn.textContent;
87 btn.addEventListener('click', function () {
88 copyText(btn.getAttribute('data-copy')).then(function () {
89 btn.textContent = '已复制';
90 btn.classList.add('copied');
91 }, function () {
92 btn.textContent = '复制失败';
93 }).then(function () {
94 setTimeout(function () {
95 btn.textContent = label;
96 btn.classList.remove('copied');
97 }, 1600);
98 });
99 });
100 });
101})();