MyModal

原生js弹出层

目前为 2023-04-19 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/463930/1177935/MyModal.js

  1. // ==UserScript==
  2. // @name MyModal
  3. // @namespace http://https://wish123.cnblogs.com/?MyModal
  4. // @version 0.1.1.2
  5. // @description 原生js弹出层
  6. // @author Wilson
  7.  
  8. function MyModal(options) {
  9. this.zIndex = 1010
  10. this.config = options || {}
  11. this.modal = null;
  12. if(this.config) {
  13. this.createStyle();
  14. this.create();
  15. }
  16. }
  17. MyModal.prototype.createStyle = function() {
  18. if(document.querySelector("#myModalStyle")) {
  19. return;
  20. }
  21. let style = `
  22. <style id="myModalStyle">
  23. /* The Modal (background) */
  24. .my-modal {
  25. display: none; /* Hidden by default */
  26. position: fixed; /* Stay in place */
  27. z-index: 1010; /* Sit on top */
  28. padding-top: 100px;
  29. left: 0;
  30. top: 0;
  31. width: 100%; /* Full width */
  32. height: 100%; /* Full height */
  33. overflow: auto; /* Enable scroll if needed */
  34. background-color: rgb(0,0,0); /* Fallback color */
  35. background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
  36. }
  37.  
  38. .my-modal button {
  39. background-color: #1c9fff;
  40. color: white;
  41. padding: 14px 20px;
  42. margin: 8px 0;
  43. border: none;
  44. cursor: pointer;
  45. width: 100%;
  46. opacity: 0.9;
  47. }
  48.  
  49. .my-modal button:hover {
  50. opacity:1;
  51. }
  52.  
  53. .my-modal h2{
  54. margin: 15px 0;
  55. }
  56.  
  57. /* Modal Content */
  58. .my-modal .modal-content {
  59. position: relative;
  60. background-color: #fefefe;
  61. margin: auto;
  62. padding: 0;
  63. border: 1px solid #888;
  64. width: 50%;
  65. box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
  66. -webkit-animation-name: animatetop;
  67. -webkit-animation-duration: 0.4s;
  68. animation-name: animatetop;
  69. animation-duration: 0.4s;
  70. border-radius: 5px;
  71. }
  72.  
  73. .my-modal .modal-body-content{
  74. font-size: 16px;
  75. }
  76.  
  77. /* Add Animation */
  78. @-webkit-keyframes animatetop {
  79. from {top:-300px; opacity:0}
  80. to {top:0; opacity:1}
  81. }
  82.  
  83. @keyframes animatetop {
  84. from {top:-300px; opacity:0}
  85. to {top:0; opacity:1}
  86. }
  87.  
  88. /* The Close Button */
  89. .my-modal .close {
  90. color: #333;
  91. float: right;
  92. font-size: 28px;
  93. font-weight: bold;
  94. margin-top: 6px;
  95. }
  96.  
  97. .my-modal .close:hover,
  98. .my-modal .close:focus {
  99. color: #333;
  100. text-decoration: none;
  101. cursor: pointer;
  102. opacity: 0.60;
  103. }
  104.  
  105. .my-modal .modal-header {
  106. padding: 2px 16px;
  107. background-color: #fff;
  108. color: #333;
  109. border-bottom: 1px solid #f0f0f0;
  110. border-radius: 5px;
  111. }
  112.  
  113. .my-modal .modal-body {
  114. padding: 10px 16px;
  115. min-height: 28px;
  116. line-height: 28px;
  117. overflow: auto;
  118. }
  119.  
  120. .my-modal .modal-footer {
  121. padding: 2px 16px;
  122. background-color: #fff;
  123. color: #333;
  124. /* border-top: 1px solid #f0f0f0; */
  125. border-radius: 5px;
  126. }
  127.  
  128. .clearfix::after {
  129. content: "";
  130. clear: both;
  131. display: table;
  132. }
  133.  
  134. .my-modal .cancelbtn,.my-modal .okbtn {
  135. float: right;
  136. width: 50%;
  137. }
  138.  
  139. /* Add a color to the cancel button */
  140. .my-modal .cancelbtn {
  141. background-color: #f1f1f1;
  142. color: #333;
  143. /* border: 1px solid #dedede; */
  144. }
  145.  
  146. /* Add a color to the delete button */
  147. .my-modal .okbtn {
  148. background-color: #1c9fff;
  149. }
  150.  
  151. @media screen and (max-width: 300px) {
  152. .my-modal .cancelbtn,.my-modal .okbtn {
  153. width: 100%;
  154. }
  155. }
  156. </style>
  157. `
  158. document.body.insertAdjacentHTML("beforeend", style);
  159. }
  160. MyModal.prototype.create = function(options) {
  161. options = options || this.config
  162. if(document.querySelector("#myModal")) {
  163. document.querySelector("#myModal").remove();
  164. }
  165. let width = options.width ? 'width:'+options.width+';' : '';
  166. let height = options.height ? 'height:'+options.height+';' : '';
  167. let borderRadius = options.borderRadius ? 'border-radius:'+options.borderRadius+';' : '';
  168. let zIndex = options.zIndex ? 'z-index:'+options.zIndex+';' : '';
  169. let myModal = `
  170. <div id="myModal" class="my-modal" style="${zIndex}${options.top?'padding-top:'+options.top+';':''}">
  171. <div class="modal-content" style="${width}${height}${borderRadius}">
  172. <div class="modal-header" style="${borderRadius}${options.title===null?'display:none;':''}${options.content===null?'border-bottom:none':''}">
  173. <span class="close">&times;</span>
  174. <h2>${options.title||''}</h2>
  175. </div>
  176. <div class="modal-body" style="${options.content===null?'display:none;':''}">
  177. ${options.title===null?'<span class="close">&times;</span>':''}
  178. <div class="modal-body-content">${options.content||''}</div>
  179. </div>
  180. <div class="modal-footer" style="${borderRadius}${options.okText===null&&options.closeText===null?'display:none;':''}">
  181. <div class="clearfix">
  182. <button type="button" class="okbtn" style="${options.okText===null?'display:none;':''}${options.okWidth?'width:'+options.okWidth+';':''}">${options.okText||'OK'}</button>
  183. <button type="button" class="cancelbtn" style="${options.closeText===null?'display:none;':''}${options.closeWidth?'width:'+options.closeWidth+';':''}">${options.closeText||'Cancel'}</button>
  184. </div>
  185. </div>
  186. </div>
  187. </div>`
  188. document.body.insertAdjacentHTML("beforeend", myModal);
  189. this.modal = document.querySelector(`#myModal`);
  190.  
  191. if(options.height) {
  192. document.querySelector("#myModal .modal-body").style.height = (parseFloat(options.height) - 125) + 'px';
  193. }
  194.  
  195. let modalContent = document.querySelector(".modal-content");
  196. setTimeout(()=>{
  197. if(modalContent.offsetHeight){
  198. let padding = document.documentElement.clientHeight - modalContent.offsetHeight;
  199. padding = padding > 0 ? padding : 0;
  200. this.modal.style.paddingTop = (padding/2)+'px';
  201. }
  202. });
  203.  
  204. let _this = this;
  205. //绑定关闭事件
  206. let headerCloseBtn = document.querySelector(`#myModal .modal-header .close`);
  207. if(headerCloseBtn) {
  208. headerCloseBtn.addEventListener("click", function(e){
  209. _this.close();
  210. });
  211. }
  212. let bodyCloseBtn = document.querySelector(`#myModal .modal-body .close`);
  213. if(bodyCloseBtn){
  214. bodyCloseBtn.addEventListener("click", function(e){
  215. _this.close();
  216. });
  217. }
  218. //绑定cancel事件
  219. document.querySelector(`#myModal .cancelbtn`).addEventListener("click", function(e){
  220. if(_this.config.closeFn) {
  221. e.myModal = _this;
  222. _this.config.closeFn(e);
  223. } else {
  224. _this.close();
  225. }
  226. });
  227. //绑定OK事件
  228. document.querySelector(`#myModal .okbtn`).addEventListener("click", function(e){
  229. if(_this.config.okFn) {
  230. e.myModal = _this;
  231. _this.config.okFn(e);
  232. } else {
  233. _this.close();
  234. }
  235. });
  236. //点击空白,菜单消失
  237. document.addEventListener('click', function(e){
  238. if (e.target == _this.modal) {
  239. _this.close();
  240. }
  241. });
  242. }
  243. MyModal.prototype.show = function() {
  244. if(this.modal) {
  245. this.modal.style.display = 'block';
  246. }
  247. }
  248. MyModal.prototype.close = function() {
  249. if(this.modal) {
  250. this.modal.remove();
  251. }
  252. }
  253.  
  254. // //测试1
  255. // document.querySelector("#test1").addEventListener("click", function(){
  256. // new MyModal({
  257. // top: '',
  258. // width: '50%',
  259. // height: 'auto',
  260. // borderRadius: '5px',
  261. // zIndex: 1010,
  262. // //null,不显示title
  263. // title: 'test1',
  264. // //支持HTML格式,null不显示content
  265. // content: 'Hello World!',
  266. // //closeText:null,不显示关闭按钮
  267. // closeText: '关闭',
  268. // closeWidth: '',
  269. // //okText:null,不显示ok按钮
  270. // okText: '好了',
  271. // okWidth: '',
  272. // //closeFn和okFn可以省略
  273. // closeFn: function (e) {
  274. // console.log('closeFn clicked');
  275. // e.myModal.close();
  276. // },
  277. // okFn: function (e) {
  278. // console.log('okFn clicked');
  279. // e.myModal.close();
  280. // }
  281. // }).show();
  282. // });
  283.  
  284. // //测试2
  285. // document.querySelector("#test2").addEventListener("click", function(){
  286. // new MyModal({
  287. // top: '',
  288. // width: '50%',
  289. // height: 'auto',
  290. // borderRadius: '5px',
  291. // zIndex: 1010,
  292. // title: 'test2',
  293. // content: 'Hello World2!',
  294. // closeText: '取消',
  295. // closeWidth: '',
  296. // okText: '确定',
  297. // okWidth: '',
  298. // closeFn: function (e) {
  299. // console.log('closeFn clicked');
  300. // e.myModal.close();
  301. // },
  302. // okFn: function (e) {
  303. // console.log('okFn clicked');
  304. // e.myModal.close();
  305. // }
  306. // }).show();
  307. // });