🏠 Home 

คุณต้องเข้าสู่ระบบหรือลงทะเบียนก่อนดำเนินการต่อ

Modal

Generic modal window

สคริปต์นี้ไม่ควรถูกติดตั้งโดยตรง มันเป็นคลังสำหรับสคริปต์อื่น ๆ เพื่อบรรจุด้วยคำสั่งเมทา // @require https://update.greasyfork.org/scripts/384230/704110/Modal.js

  1. // ==UserScript==
  2. // @name Modal
  3. // @name:en Modal
  4. // @description Generic modal window
  5. // @description:en Generic modal window
  6. // @namespace https://greasyfork.org/users/174399
  7. // @version 0.1.0
  8. // @include *://*.mozilla.org/*
  9. // @grant none
  10. // ==/UserScript==
  11. (function(window, undefined) {
  12. // const btn = document.body.appendChild(createSElement(`
  13. // <div style="position: fixed; bottom: 0; right: 0; width: 10%; height: 10%; background: green; z-index: 99999; display: flex;">
  14. // <label for="modal-cbox" style="flex: 1"></label>
  15. // </div>
  16. // `));
  17. // setTimeout(() => querySelector('label', btn).click(), 2000);
  18. function Modal({
  19. content: {
  20. css: contentCSS = {},
  21. } = {},
  22. header: {
  23. html: headerHTML = '',
  24. css: headerCSS = {},
  25. onClick: onClickHeader,
  26. } = {},
  27. body: {
  28. html: bodyHTML = '',
  29. css: bodyCSS = {},
  30. onClick: onClickBody,
  31. } = {},
  32. footer: {
  33. html: footerHTML = '',
  34. css: footerCSS = {},
  35. onClick: onClickFooter,
  36. } = {},
  37. withClose = true,
  38. } = {}) {
  39. const wrapper = querySelector('.modal-wrapper') || Modal.create();
  40. const content = querySelector('.modal-content', wrapper);
  41. const mheader = querySelector('.modal-header', wrapper);
  42. const mfooter = querySelector('.modal-footer', wrapper);
  43. const mbody = querySelector('.modal-body', wrapper);
  44. // html
  45. mheader.appendChild(createSElement(headerHTML));
  46. mfooter.innerHTML = footerHTML;
  47. mbody.innerHTML = bodyHTML;
  48. // style
  49. setStyle(content, contentCSS);
  50. setStyle(mheader, headerCSS);
  51. setStyle(mfooter, footerCSS);
  52. setStyle(mbody, bodyCSS);
  53. // onclick
  54. addEventListener(mheader, 'click', onClickHeader);
  55. addEventListener(mfooter, 'click', onClickFooter);
  56. addEventListener(mbody, 'click', onClickBody);
  57. // return object
  58. this.wrapper = wrapper;
  59. this.content = content;
  60. this.header = mheader;
  61. this.footer = mfooter;
  62. this.body = mbody;
  63. this.onClickHeader = onClickHeader;
  64. this.onClickFooter = onClickFooter;
  65. this.onClickBody = onClickBody;
  66. }
  67. Modal.toggle = function() {
  68. const btn = querySelector('.modal-wrapper .modal-close-background');
  69. return btn && btn.click();
  70. };
  71. Modal._open = function(visible = true) {
  72. (querySelector('.modal-wrapper #modal-cbox') || {}).checked = visible;
  73. };
  74. Modal.close = function() { Modal._open(false); };
  75. Modal.open = function() { Modal._open(true); };
  76. Modal.WRAPPER_HTML = `
  77. <div class="modal-wrapper">
  78. <input type="checkbox" checked style="display: none" id="modal-cbox" />
  79. <div class="modal-container">
  80. <label for="modal-cbox" class="modal-close-background" ></label>
  81. <div class="modal-content">
  82. <div class="modal-header">
  83. <label for="modal-cbox" title="close" class="modal-close-x"><div></div></label>
  84. </div>
  85. <div class="modal-body"></div>
  86. <div class="modal-footer"></div>
  87. </div>
  88. </div>
  89. </div>`.replace(/\s+/g, ' ').replace(/\n/g, ' ').trim();
  90. Modal.WRAPPER_CSS = `
  91. .modal-container {
  92. opacity: 0;
  93. visibility: hidden;
  94. }
  95. #modal-cbox:checked + .modal-container {
  96. position: fixed;
  97. z-index: 9999999;
  98. visibility: visible;
  99. opacity: 1;
  100. top: 0;
  101. right: 0;
  102. bottom: 0;
  103. left: 0;
  104. transition: opacity .25s;
  105. }
  106. #modal-cbox:checked + .modal-container .modal-content {
  107. bottom: 0;
  108. }
  109. .modal-content {
  110. position: absolute;
  111. background-color: gray;
  112. min-width: 400px;
  113. min-height: 100px;
  114. opacity: 1;
  115. display: flex;
  116. flex-direction: column;
  117. align-items: center;
  118. right: 0;
  119. bottom: -20%;
  120. transition: all .25s;
  121. }
  122. .modal-header {
  123. display: flex;
  124. flex-direction: row;
  125. position: relative;
  126. align-items: center;
  127. width: 100%;
  128. height: 40px;
  129. }
  130. .modal-close-x {
  131. position: absolute;
  132. right: 10px;
  133. }
  134. .modal-close-x div {
  135. display: flex;
  136. flex-direction: row;
  137. justify-content: center;
  138. }
  139. .modal-close-x,
  140. .modal-close-x div {
  141. width: 24px;
  142. height: 24px;
  143. }
  144. .modal-close-x div:after,
  145. .modal-close-x div:before {
  146. content: "";
  147. position: absolute;
  148. background: #ccc;
  149. width: 2px;
  150. height: 24px;
  151. display: block;
  152. transform: rotate(45deg);
  153. }
  154. .modal-close-x div:before {
  155. transform: rotate(-45deg);
  156. }
  157. .modal-close-background {
  158. position: absolute;
  159. background-color: black;
  160. width: 100%;
  161. height: 100%;
  162. opacity: 0.4;
  163. }
  164. `.replace(/\s+/g, ' ').replace(/\n/g, ' ').trim();
  165. Modal.create = function() {
  166. let wrapper = querySelector('.modal-wrapper');
  167. if (wrapper) {
  168. return wrapper;
  169. }
  170. if (document.readyState === 'loading') {
  171. throw new Error('you can\'t insert HTMLElement to DOMTree while document is loading');
  172. }
  173. const {
  174. body = querySelector('body'),
  175. head = querySelector('head'),
  176. } = document;
  177. if (!body) {
  178. throw new Error('document.body not found');
  179. }
  180. if (!head) {
  181. throw new Error('document.head not found');
  182. }
  183. wrapper = createSElement(Modal.WRAPPER_HTML);
  184. const style = createElement('style', Modal.WRAPPER_CSS);
  185. head.appendChild(style);
  186. return body.appendChild(wrapper);
  187. };
  188. function createSElement(html) {
  189. return createElement('div', html).firstElementChild;
  190. }
  191. function createElement(tag, html) {
  192. const elem = document.createElement(tag);
  193. if (typeof html !== 'undefined') {
  194. elem.innerHTML = html;
  195. }
  196. return elem;
  197. }
  198. function querySelector(selector, context) {
  199. return (context || document).querySelector(selector);
  200. }
  201. function querySelectorAll(selector, context = document) {
  202. return (context || document).querySelectorAll(selector);
  203. }
  204. function setStyle(elem, css, val) {
  205. if (!elem) {
  206. return;
  207. }
  208. switch (typeof css) {
  209. case 'object':
  210. Object.keys(css).map(toCamelCase).forEach(key => setStyle(elem, key, css[key]));
  211. break;
  212. case 'string':
  213. elem.style[css] = val;
  214. break;
  215. }
  216. }
  217. function toCamelCase(str) {
  218. return str.replace(/\-([a-z])/g, (match, p1) => p1.toUpperCase());
  219. }
  220. function addEventListener(elem, event, callback) {
  221. if (!elem || typeof event !== 'string' || typeof callback !== 'function') {
  222. return;
  223. }
  224. return elem.addEventListener(event, callback);
  225. }
  226. const { ESModules = {} } = window;
  227. ESModules.Modal = Modal;
  228. window.ESModules = ESModules;
  229. // Modal.create();
  230. // setTimeout(Modal.toggle, 4000);
  231. })(window);