MyModal

原生js弹出层

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

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/463930/1177906/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. }
  95.  
  96. .my-modal .close:hover,
  97. .my-modal .close:focus {
  98. color: #333;
  99. text-decoration: none;
  100. cursor: pointer;
  101. opacity: 0.60;
  102. }
  103.  
  104. .my-modal .modal-header {
  105. padding: 2px 16px;
  106. background-color: #fff;
  107. color: #333;
  108. border-bottom: 1px solid #f0f0f0;
  109. border-radius: 5px;
  110. }
  111.  
  112. .my-modal .modal-body {
  113. padding: 10px 16px;
  114. min-height: 28px;
  115. line-height: 28px;
  116. overflow: auto;
  117. }
  118.  
  119. .my-modal .modal-footer {
  120. padding: 2px 16px;
  121. background-color: #fff;
  122. color: #333;
  123. /* border-top: 1px solid #f0f0f0; */
  124. border-radius: 5px;
  125. }
  126.  
  127. .clearfix::after {
  128. content: "";
  129. clear: both;
  130. display: table;
  131. }
  132.  
  133. .my-modal .cancelbtn,.my-modal .okbtn {
  134. float: right;
  135. width: 50%;
  136. }
  137.  
  138. /* Add a color to the cancel button */
  139. .my-modal .cancelbtn {
  140. background-color: #f1f1f1;
  141. color: #333;
  142. /* border: 1px solid #dedede; */
  143. }
  144.  
  145. /* Add a color to the delete button */
  146. .my-modal .okbtn {
  147. background-color: #1c9fff;
  148. }
  149.  
  150. @media screen and (max-width: 300px) {
  151. .my-modal .cancelbtn,.my-modal .okbtn {
  152. width: 100%;
  153. }
  154. }
  155. </style>
  156. `
  157. document.body.insertAdjacentHTML("beforeend", style);
  158. }
  159. MyModal.prototype.create = function(options) {
  160. options = options || this.config
  161. if(document.querySelector("#myModal")) {
  162. document.querySelector("#myModal").remove();
  163. }
  164. let width = options.width ? 'width:'+options.width+';' : '';
  165. let height = options.height ? 'height:'+options.height+';' : '';
  166. let borderRadius = options.borderRadius ? 'border-radius:'+options.borderRadius+';' : '';
  167. let zIndex = options.zIndex ? 'z-index:'+options.zIndex+';' : '';
  168. let myModal = `
  169. <div id="myModal" class="my-modal" style="${zIndex}${options.top?'padding-top:'+options.top+';':''}">
  170. <div class="modal-content" style="${width}${height}${borderRadius}">
  171. <div class="modal-header" style="${borderRadius}${options.title===null?'display:none;':''}${options.content===null?'border-bottom:none':''}">
  172. <span class="close">&times;</span>
  173. <h2>${options.title||''}</h2>
  174. </div>
  175. <div class="modal-body" style="${options.content===null?'display:none;':''}">
  176. ${options.title===null?'<span class="close">&times;</span>':''}
  177. <div class="modal-body-content">${options.content||''}</div>
  178. </div>
  179. <div class="modal-footer" style="${borderRadius}${options.okText===null&&options.closeText===null?'display:none;':''}">
  180. <div class="clearfix">
  181. <button type="button" class="okbtn" style="${options.okText===null?'display:none;':''}${options.okWidth?'width:'+options.okWidth+';':''}">${options.okText||'OK'}</button>
  182. <button type="button" class="cancelbtn" style="${options.closeText===null?'display:none;':''}${options.closeWidth?'width:'+options.closeWidth+';':''}">${options.closeText||'Cancel'}</button>
  183. </div>
  184. </div>
  185. </div>
  186. </div>`
  187. document.body.insertAdjacentHTML("beforeend", myModal);
  188. this.modal = document.querySelector(`#myModal`);
  189.  
  190. if(options.height) {
  191. document.querySelector("#myModal .modal-body").style.height = (parseFloat(options.height) - 125) + 'px';
  192. }
  193.  
  194. let modalContent = document.querySelector(".modal-content");
  195. setTimeout(()=>{
  196. if(modalContent.offsetHeight){
  197. let padding = document.documentElement.clientHeight - modalContent.offsetHeight;
  198. padding = padding > 0 ? padding : 0;
  199. this.modal.style.paddingTop = (padding/2)+'px';
  200. }
  201. });
  202.  
  203. let _this = this;
  204. //绑定关闭事件
  205. let headerCloseBtn = document.querySelector(`#myModal .modal-header .close`);
  206. if(headerCloseBtn) {
  207. headerCloseBtn.addEventListener("click", function(e){
  208. _this.close();
  209. });
  210. }
  211. let bodyCloseBtn = document.querySelector(`#myModal .modal-body .close`);
  212. if(bodyCloseBtn){
  213. bodyCloseBtn.addEventListener("click", function(e){
  214. _this.close();
  215. });
  216. }
  217. //绑定cancel事件
  218. document.querySelector(`#myModal .cancelbtn`).addEventListener("click", function(e){
  219. if(_this.config.closeFn) {
  220. e.myModal = _this;
  221. _this.config.closeFn(e);
  222. } else {
  223. _this.close();
  224. }
  225. });
  226. //绑定OK事件
  227. document.querySelector(`#myModal .okbtn`).addEventListener("click", function(e){
  228. if(_this.config.okFn) {
  229. e.myModal = _this;
  230. _this.config.okFn(e);
  231. } else {
  232. _this.close();
  233. }
  234. });
  235. //点击空白,菜单消失
  236. document.addEventListener('click', function(e){
  237. if (e.target == _this.modal) {
  238. _this.close();
  239. }
  240. });
  241. }
  242. MyModal.prototype.show = function() {
  243. if(this.modal) {
  244. this.modal.style.display = 'block';
  245. }
  246. }
  247. MyModal.prototype.close = function() {
  248. if(this.modal) {
  249. this.modal.remove();
  250. }
  251. }
  252.  
  253. // //测试1
  254. // document.querySelector("#test1").addEventListener("click", function(){
  255. // new MyModal({
  256. // top: '',
  257. // width: '50%',
  258. // height: 'auto',
  259. // borderRadius: '5px',
  260. // zIndex: 1010,
  261. // //null,不显示title
  262. // title: 'test1',
  263. // //支持HTML格式,null不显示content
  264. // content: 'Hello World!',
  265. // //closeText:null,不显示关闭按钮
  266. // closeText: '关闭',
  267. // closeWidth: '',
  268. // //okText:null,不显示ok按钮
  269. // okText: '好了',
  270. // okWidth: '',
  271. // //closeFn和okFn可以省略
  272. // closeFn: function (e) {
  273. // console.log('closeFn clicked');
  274. // e.myModal.close();
  275. // },
  276. // okFn: function (e) {
  277. // console.log('okFn clicked');
  278. // e.myModal.close();
  279. // }
  280. // }).show();
  281. // });
  282.  
  283. // //测试2
  284. // document.querySelector("#test2").addEventListener("click", function(){
  285. // new MyModal({
  286. // top: '',
  287. // width: '50%',
  288. // height: 'auto',
  289. // borderRadius: '5px',
  290. // zIndex: 1010,
  291. // title: 'test2',
  292. // content: 'Hello World2!',
  293. // closeText: '取消',
  294. // closeWidth: '',
  295. // okText: '确定',
  296. // okWidth: '',
  297. // closeFn: function (e) {
  298. // console.log('closeFn clicked');
  299. // e.myModal.close();
  300. // },
  301. // okFn: function (e) {
  302. // console.log('okFn clicked');
  303. // e.myModal.close();
  304. // }
  305. // }).show();
  306. // });