quickDom.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * @Description: 构建弹窗
  3. * @Autor: kindring
  4. * @Date: 2021-10-12 17:16:30
  5. * @LastEditors: kindring
  6. * @LastEditTime: 2021-11-15 10:37:16
  7. * @LastDescript:
  8. */
  9. class CustomPop {
  10. constructor(option) {
  11. let defaultOption = {
  12. type: 'tip', //tip,custom,loading,text居中文本
  13. mask: false,
  14. centerDoms: null, //中间的所有dom元素,用于自定义提示,数组模式,字符串
  15. text: null,
  16. }
  17. // 小窗口弹窗,则默认只允许设置为body
  18. this.el = option.el || window.document.body;
  19. this.maskEl = null;
  20. this.parentEl = null;
  21. this.type = option.type || defaultOption.type;
  22. this.mask = option.mask;
  23. this.tipNum = 0;
  24. this.tipStep = 40;
  25. this.centerDoms = option.centerDoms
  26. if (this.type == 'tip') {
  27. this.el == window.document.body;
  28. } else if (this.type == 'custom') {
  29. // if(window.document.body)
  30. // this.maskEl = this.buildMask();
  31. this.create();
  32. }
  33. if (option.autoClose) {
  34. this.parentEl.addEventListener('click', (e) => {
  35. this.hide()
  36. })
  37. }
  38. this.option = option;
  39. this.nowCustomKey = null;
  40. this.bind();
  41. }
  42. // 绑定操作,将dom元素绑定到指定的dom元素中,指定dom元素自动添加 relative
  43. bind() {
  44. // console.log(this.el.style.position);
  45. if (!this.el.style.position) {
  46. this.el.style.position = 'relative'
  47. }
  48. }
  49. // 创建自定义的dom元素
  50. create() {
  51. let parentDom = document.createElement('div');
  52. // 设置dom元素样式
  53. this.setStyle(parentDom, {
  54. display: 'none',
  55. position: 'absolute',
  56. left: 0,
  57. top: 0,
  58. width: '100%',
  59. height: '100%',
  60. 'justify-center': 'center',
  61. 'alignItems': 'center'
  62. });
  63. if (this.mask) {
  64. let maskEl = document.createElement('div');
  65. this.setStyle(maskEl, {
  66. position: 'absolute',
  67. left: 0,
  68. top: 0,
  69. width: '100%',
  70. height: '100%',
  71. backgroundColor: 'rgba(0,0,0)',
  72. opacity: '0.3'
  73. })
  74. this.maskEl = maskEl;
  75. parentDom.appendChild(maskEl);
  76. }
  77. if (this.centerDoms) {
  78. this.centerDoms.forEach(item => {
  79. item.el.parentElement.removeChild(item.el)
  80. })
  81. }
  82. this.parentEl = parentDom;
  83. // 添加元素至dom元素中
  84. this.el.appendChild(parentDom);
  85. }
  86. // 显示界面,优先匹配中间内容
  87. show(text, theme) {
  88. // console.log(this.type);
  89. if (this.type == 'tip') {
  90. let _time = this.tipNum;
  91. _time = Math.min(10, _time);
  92. // 设置dom延时进行弹窗提示
  93. setTimeout(() => {
  94. // console.log(this.type);
  95. // 构建tip
  96. let tipDom = this.buildTip(theme);
  97. tipDom.innerHTML = text;
  98. //自动添加到body中去
  99. this.el.appendChild(tipDom);
  100. // 自动显示dom元素并且隐藏
  101. setTimeout(() => {
  102. this.setStyle(tipDom, {
  103. opacity: '1'
  104. })
  105. setTimeout(() => {
  106. this.setStyle(tipDom, {
  107. top: `${50+(_time * this.tipStep)}px`
  108. })
  109. }, 100);
  110. setTimeout(() => {
  111. this.setStyle(tipDom, {
  112. opacity: 0,
  113. top: `${200+(_time * this.tipStep)}px`
  114. })
  115. setTimeout(() => {
  116. this.setStyle(tipDom, {
  117. display: 'none',
  118. })
  119. this.tipNum--;
  120. this.el.removeChild(tipDom);
  121. }, 900);
  122. }, 2200);
  123. }, 1);
  124. }, this.tipNum * this.tipStep);
  125. this.tipNum++;
  126. return;
  127. } else if (this.type == 'custom') {
  128. let centerDom = null;
  129. if (text) {
  130. let doms;
  131. if (this.centerDoms) {
  132. doms = this.centerDoms.find(item => {
  133. if (item.key == text) {
  134. return item;
  135. }
  136. })
  137. }
  138. if (!doms) {
  139. doms = {
  140. el: document.createElement('span'),
  141. key: 'null'
  142. }
  143. doms.el.innerHTML = text;
  144. }
  145. centerDom = doms;
  146. } else if (this.option.centerDoms) {
  147. //默认选择第一个dom元素
  148. centerDom = this.option.centerDoms[0];
  149. } else {
  150. //如果没有字符串,并且也没有默认节点,则无视此窗口
  151. console.error('错误');
  152. }
  153. if (centerDom) {
  154. if (this.nowCustomKey == text) {
  155. // 直接显示dom元素
  156. } else {
  157. // 修改dom元素
  158. this.parentEl.innerHTML = '';
  159. if (this.mask) {
  160. this.parentEl.appendChild(this.maskEl)
  161. }
  162. centerDom.el.addEventListener('click', function(e) {
  163. e = e || window.event;
  164. e.preventDefault();
  165. });
  166. // 重新构建
  167. this.parentEl.appendChild(centerDom.el)
  168. }
  169. }
  170. this.nowCustomKey = text;
  171. this.setStyle(this.parentEl, {
  172. display: 'flex'
  173. })
  174. }
  175. };
  176. // hide隐藏界面
  177. hide() {
  178. if (this.type == 'custom') {
  179. this.setStyle(this.parentEl, {
  180. display: 'none'
  181. });
  182. } else {
  183. console.error('其他类型的元素正在制作中');
  184. }
  185. }
  186. buildMask() {
  187. return maskEl
  188. }
  189. /**
  190. * 构建提示元素
  191. * @param {'info'|'success'|'warn'|'error'} _theme 样式主题,
  192. */
  193. buildTip(_theme) {
  194. let el = document.createElement('div');
  195. _theme = _theme || 'default';
  196. this.setStyle(el, {
  197. 'transition': 'all 0.5s',
  198. position: 'absolute',
  199. top: '555px',
  200. left: '50%',
  201. transform: 'translate(-50%,0)',
  202. display: 'block',
  203. padding: '5px 25px',
  204. 'border-radius': '5px',
  205. opacity: 0,
  206. })
  207. if (_theme == 'error' || _theme == 'err') {
  208. this.setStyle(el, {
  209. color: '#D8000C',
  210. backgroundColor: '#FFBABA',
  211. border: '1px solid rgb(219 176 176)'
  212. })
  213. } else if (_theme == 'success' || _theme == 'ok') {
  214. this.setStyle(el, {
  215. color: '#4F8A10',
  216. backgroundColor: '#DFF2BF',
  217. border: '1px solid rgb(227 253 182)'
  218. })
  219. } else if (_theme == 'warn' || _theme == 'warning' || _theme == 'waring') {
  220. this.setStyle(el, {
  221. color: '#9F6000',
  222. backgroundColor: '#FEEFB3',
  223. border: '1px solid rgb(241 229 180)'
  224. })
  225. } else {
  226. this.setStyle(el, {
  227. color: '#31708f',
  228. backgroundColor: '#d9edf7',
  229. border: '1px solid #bce8f1'
  230. })
  231. }
  232. return el;
  233. }
  234. // 辅助函数,设置dom元素的样式
  235. setStyle(el, params) {
  236. Object.keys(params).forEach(key => {
  237. let strArr = key.split('-');
  238. let strKey = key;
  239. if (strArr.length >= 2) {
  240. strKey = strArr.reduce((acc, current, index) => {
  241. // console.log();
  242. // 第一位
  243. return index == 0 ? current : acc + (current.replace(current[0], current[0].toUpperCase()))
  244. }, '')
  245. } else {
  246. strKey = strArr[0]
  247. }
  248. el.style[strKey] = params[key];
  249. })
  250. return el;
  251. }
  252. // 确认的函数
  253. onOk() {
  254. }
  255. // 取消弹窗的函数
  256. onCancel() {
  257. }
  258. }