您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Generic modal window
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/384230/704110/Modal.js
// ==UserScript== // @name Modal // @name:en Modal // @description Generic modal window // @description:en Generic modal window // @namespace https://greasyfork.org/users/174399 // @version 0.1.0 // @include *://*.mozilla.org/* // @grant none // ==/UserScript== (function(window, undefined) { // const btn = document.body.appendChild(createSElement(` // <div style="position: fixed; bottom: 0; right: 0; width: 10%; height: 10%; background: green; z-index: 99999; display: flex;"> // <label for="modal-cbox" style="flex: 1"></label> // </div> // `)); // setTimeout(() => querySelector('label', btn).click(), 2000); function Modal({ content: { css: contentCSS = {}, } = {}, header: { html: headerHTML = '', css: headerCSS = {}, onClick: onClickHeader, } = {}, body: { html: bodyHTML = '', css: bodyCSS = {}, onClick: onClickBody, } = {}, footer: { html: footerHTML = '', css: footerCSS = {}, onClick: onClickFooter, } = {}, withClose = true, } = {}) { const wrapper = querySelector('.modal-wrapper') || Modal.create(); const content = querySelector('.modal-content', wrapper); const mheader = querySelector('.modal-header', wrapper); const mfooter = querySelector('.modal-footer', wrapper); const mbody = querySelector('.modal-body', wrapper); // html mheader.appendChild(createSElement(headerHTML)); mfooter.innerHTML = footerHTML; mbody.innerHTML = bodyHTML; // style setStyle(content, contentCSS); setStyle(mheader, headerCSS); setStyle(mfooter, footerCSS); setStyle(mbody, bodyCSS); // onclick addEventListener(mheader, 'click', onClickHeader); addEventListener(mfooter, 'click', onClickFooter); addEventListener(mbody, 'click', onClickBody); // return object this.wrapper = wrapper; this.content = content; this.header = mheader; this.footer = mfooter; this.body = mbody; this.onClickHeader = onClickHeader; this.onClickFooter = onClickFooter; this.onClickBody = onClickBody; } Modal.toggle = function() { const btn = querySelector('.modal-wrapper .modal-close-background'); return btn && btn.click(); }; Modal._open = function(visible = true) { (querySelector('.modal-wrapper #modal-cbox') || {}).checked = visible; }; Modal.close = function() { Modal._open(false); }; Modal.open = function() { Modal._open(true); }; Modal.WRAPPER_HTML = ` <div class="modal-wrapper"> <input type="checkbox" checked style="display: none" id="modal-cbox" /> <div class="modal-container"> <label for="modal-cbox" class="modal-close-background" ></label> <div class="modal-content"> <div class="modal-header"> <label for="modal-cbox" title="close" class="modal-close-x"><div></div></label> </div> <div class="modal-body"></div> <div class="modal-footer"></div> </div> </div> </div>`.replace(/\s+/g, ' ').replace(/\n/g, ' ').trim(); Modal.WRAPPER_CSS = ` .modal-container { opacity: 0; visibility: hidden; } #modal-cbox:checked + .modal-container { position: fixed; z-index: 9999999; visibility: visible; opacity: 1; top: 0; right: 0; bottom: 0; left: 0; transition: opacity .25s; } #modal-cbox:checked + .modal-container .modal-content { bottom: 0; } .modal-content { position: absolute; background-color: gray; min-width: 400px; min-height: 100px; opacity: 1; display: flex; flex-direction: column; align-items: center; right: 0; bottom: -20%; transition: all .25s; } .modal-header { display: flex; flex-direction: row; position: relative; align-items: center; width: 100%; height: 40px; } .modal-close-x { position: absolute; right: 10px; } .modal-close-x div { display: flex; flex-direction: row; justify-content: center; } .modal-close-x, .modal-close-x div { width: 24px; height: 24px; } .modal-close-x div:after, .modal-close-x div:before { content: ""; position: absolute; background: #ccc; width: 2px; height: 24px; display: block; transform: rotate(45deg); } .modal-close-x div:before { transform: rotate(-45deg); } .modal-close-background { position: absolute; background-color: black; width: 100%; height: 100%; opacity: 0.4; } `.replace(/\s+/g, ' ').replace(/\n/g, ' ').trim(); Modal.create = function() { let wrapper = querySelector('.modal-wrapper'); if (wrapper) { return wrapper; } if (document.readyState === 'loading') { throw new Error('you can\'t insert HTMLElement to DOMTree while document is loading'); } const { body = querySelector('body'), head = querySelector('head'), } = document; if (!body) { throw new Error('document.body not found'); } if (!head) { throw new Error('document.head not found'); } wrapper = createSElement(Modal.WRAPPER_HTML); const style = createElement('style', Modal.WRAPPER_CSS); head.appendChild(style); return body.appendChild(wrapper); }; function createSElement(html) { return createElement('div', html).firstElementChild; } function createElement(tag, html) { const elem = document.createElement(tag); if (typeof html !== 'undefined') { elem.innerHTML = html; } return elem; } function querySelector(selector, context) { return (context || document).querySelector(selector); } function querySelectorAll(selector, context = document) { return (context || document).querySelectorAll(selector); } function setStyle(elem, css, val) { if (!elem) { return; } switch (typeof css) { case 'object': Object.keys(css).map(toCamelCase).forEach(key => setStyle(elem, key, css[key])); break; case 'string': elem.style[css] = val; break; } } function toCamelCase(str) { return str.replace(/\-([a-z])/g, (match, p1) => p1.toUpperCase()); } function addEventListener(elem, event, callback) { if (!elem || typeof event !== 'string' || typeof callback !== 'function') { return; } return elem.addEventListener(event, callback); } const { ESModules = {} } = window; ESModules.Modal = Modal; window.ESModules = ESModules; // Modal.create(); // setTimeout(Modal.toggle, 4000); })(window);