showModal.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * @description 替换android app的uni.showModal
  3. */
  4. let modalIntance = null;
  5. export class fyShowModal {
  6. constructor(options = {}) {
  7. modalIntance = this;
  8. this.modalControl = null; // 模态框句柄
  9. this.cancelModel = null;
  10. this.confirmModel = null;
  11. const { screenHeight, screenWidth } = uni.getSystemInfoSync();
  12. this.modalPaddingTop = 12; // modal顶部的内边距
  13. this.titleHeight = 34; // 标题的高度
  14. this.contentHeight = 60; // 内容得高度
  15. this.contentPaddingBottom = 10; // 内容的底部内边距
  16. this.footerHeight = 50; // 底部按钮的高度
  17. const modalHeight = this.modalPaddingTop + this.contentPaddingBottom + this.titleHeight + this.contentHeight + this.footerHeight; // 模态框内容高度
  18. this.screenHeight = screenHeight;
  19. this.modalWidth = options.contentWidth || screenWidth * 0.82; // 模态框内容宽度
  20. this.modalHeight = modalHeight; // 模态框内容高度
  21. this.modalLeft = (screenWidth - this.modalWidth) / 2; // 模态框距离左边距离
  22. this.modalTop = (screenHeight / 2) - (modalHeight / 2) - 30; // 模态框距离顶部距离
  23. this.titleTop = this.modalPaddingTop + this.modalTop; // title距离顶部的距离
  24. this.contentTop = this.modalPaddingTop + this.modalTop + this.titleHeight; // content距离顶部的距离
  25. this.contentLeft = this.modalLeft + (this.modalWidth * 0.1);
  26. this.contentWidth = this.modalWidth * 0.8; // 内容的宽度
  27. this.footerBorderTop = this.contentPaddingBottom + this.contentTop + this.contentHeight; // footer的边线距离顶部的距离
  28. this.buttonWidth = this.modalWidth/2;
  29. // 物理返回键是否关闭弹框
  30. this.backbutton = Boolean(options.backbutton);
  31. let opacity = options.opacity || 0.6; // mask透明度
  32. let modal_title = options.title || '提示'; // 标题
  33. let model_content = options.content || '提示内容'; // 提示内容
  34. let maskClick = typeof options.maskClick === 'undefined' ? false : options.maskClick; // 是否可以点击mask关闭模态框
  35. let cancelText = options.cancelText || '取消';
  36. let confirmText = options.confirmText || '确定';
  37. let cancelColor = options.cancelColor || '#000000';
  38. let confirmColor = options.confirmColor || '#3CC51F';
  39. let showCancel = typeof options.showCancel === 'undefined' ? true : options.showCancel; // 是否显示取消按钮
  40. let align = options.align || 'center'; // 内容对齐方向
  41. let successFn = () => {};
  42. let failFn = () => {};
  43. this.success = options.success || successFn; // 成功返回模态框
  44. this.fail = options.fail || failFn; // 失败返回模态框
  45. //#ifdef APP-PLUS
  46. this.creatView({ height: `${this.screenHeight}px`, top: 0 }, opacity, maskClick, { 'title': modal_title, 'content': model_content, cancelText, confirmText, confirmColor, cancelColor, showCancel, align });
  47. //#endif
  48. }
  49. //生成提示框view
  50. creatView(style, opa, maskClick, modelInfo) {
  51. try {
  52. style = { left: '0px', width: '100%', ...style };
  53. let view = new plus.nativeObj.View('FyShowModalView', style);
  54. view.draw([
  55. { tag: 'rect', id: 'modal', color: `rgba(0,0,0,${opa})`, position: { top: '0px', left: '0px', width: '100%', height: '100%' } },
  56. { tag: 'rect', id: 'content', color: `rgb(255,255,255)`, rectStyles: { borderWidth: '0px', radius: '8px' }, position: { top: this.modalTop+'px', left: this.modalLeft+'px', width: this.modalWidth+'px', height: this.modalHeight + 'px' } },
  57. { tag: 'font', id: 'title', text: modelInfo.title, textStyles: { size: '18px', weight: 'bold', color: '#000000' }, position: { top: this.titleTop+'px', left: this.modalLeft+'px', width: this.modalWidth+'px', height: this.titleHeight+'px' } },
  58. { tag: 'font', id: 'text', text: modelInfo.content, textStyles: { size: '15px', color: '#666', whiteSpace: 'normal', align: modelInfo.align }, position: { top: this.contentTop+'px', left: this.contentLeft+'px', width: this.contentWidth+'px', height: this.contentHeight+'px' } },
  59. { tag: 'rect', id: 'line', color: '#efeff1', position: { top: this.footerBorderTop+'px', left: this.modalLeft+'px', width: this.modalWidth+'px', height: '1px' } },
  60. { tag: 'rect', id: 'line2', color: '#efeff1', position: { top: this.footerBorderTop+'px', left: '50%', width: modelInfo.showCancel ? '1px' : '0px', height: modelInfo.showCancel ? this.footerHeight+'px' : '0px' } }
  61. ]);
  62. // 取消按钮
  63. if (modelInfo.showCancel) {
  64. let viewCancel = new plus.nativeObj.View('FyShowModalCancel', { width: this.buttonWidth+'px', height: this.footerHeight+'px', top: this.footerBorderTop + 'px', left: this.modalLeft+'px' });
  65. viewCancel.draw([
  66. { tag: 'rect', id: 'cancelBackground', color: `rgba(255,255,255,0)`, rectStyles: { borderWidth: '0px', radius: '8px' }, position: { top: '0px', left: '0px', width: '100%', height: '100%' } },
  67. { tag: 'font', id: 'cancel', text: modelInfo.cancelText, textStyles: { color: modelInfo.cancelColor, size: '16px' } },
  68. ]);
  69. viewCancel.addEventListener('click', (e) => {
  70. viewconfirm.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'confirmBackground');
  71. viewCancel.drawRect('#efeff1', {top:'0px',left:'0px',width:'100%',height:'100%'}, 'cancelBackground');
  72. this.success({ confirm: false, cancel: true, mask: false })
  73. this.hide();
  74. }, false);
  75. viewCancel.addEventListener('touchstart', (e)=>{
  76. viewconfirm.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'confirmBackground');
  77. viewCancel.drawRect({ color: '#efeff1', borderWidth: '0px', radius: '8px' }, {top:'0px',left:'0px',width:'100%',height:'100%'}, 'cancelBackground');
  78. })
  79. this.cancelModel = viewCancel;
  80. }
  81. // 确认
  82. let viewconfirm = new plus.nativeObj.View('FyShowModalConfirm', { width: modelInfo.showCancel ? this.buttonWidth+'px' : this.modalWidth+'px', height: this.footerHeight+'px', top: this.footerBorderTop + 'px', left: modelInfo.showCancel ? '50%' : this.modalLeft+'px' });
  83. // 绘制确认
  84. viewconfirm.draw([
  85. { tag: 'rect', id: 'confirmBackground', color: `rgba(255,255,255,0)`, rectStyles: { borderWidth: '0px', radius: '8px' }, position: { top: '0px', left: '0px', width: '100%', height: '100%' } },
  86. { tag: 'font', id: 'confirm', text: modelInfo.confirmText, textStyles: { color: modelInfo.confirmColor, size: '16px' } },
  87. ]);
  88. // 点击确认
  89. viewconfirm.addEventListener('click', (e) => {
  90. if (this.cancelModel) {
  91. this.cancelModel.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'cancelBackground');
  92. }
  93. viewconfirm.drawRect('#efeff1', {top:'0px',left:'0px',width:'100%',height:'100%'}, 'confirmBackground');
  94. this.success({ confirm: true, cancel: false, mask: false })
  95. this.hide();
  96. }, false);
  97. viewconfirm.addEventListener('touchstart', (e)=>{
  98. if (this.cancelModel) {
  99. this.cancelModel.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'cancelBackground');
  100. }
  101. viewconfirm.drawRect({ color: '#efeff1', borderWidth: '0px', radius: '8px' }, {top:'0px',left:'0px',width:'100%',height:'100%'}, 'confirmBackground');
  102. })
  103. //点击蒙布
  104. if (maskClick) {
  105. view.addEventListener('click', (e) => {
  106. this.success({ confirm: false, cancel: true, mask: true })
  107. this.hide();
  108. if (this.cancelModel) {
  109. this.cancelModel.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'cancelBackground');
  110. }
  111. viewconfirm.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'confirmBackground');
  112. }, false);
  113. } else {
  114. view.addEventListener('click', (e) => {
  115. if (this.cancelModel) {
  116. this.cancelModel.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'cancelBackground');
  117. }
  118. viewconfirm.drawRect({ color: 'rgba(255,255,255,0)', borderWidth: '0px', radius: '8px' }, {}, 'confirmBackground');
  119. }, false);
  120. }
  121. this.modalControl = view;
  122. this.confirmModel = viewconfirm;
  123. } catch(err) {
  124. this.fail(err);
  125. }
  126. }
  127. // 显示模态框
  128. show() {
  129. this.modalControl.show();
  130. if (this.cancelModel) {
  131. this.cancelModel.show();
  132. }
  133. this.confirmModel.show();
  134. if (this.backbutton) {
  135. plus.key.addEventListener('backbutton', this.handlerBackButton);
  136. }
  137. }
  138. // 关闭模态框
  139. hide() {
  140. if (this.backbutton) {
  141. plus.key.removeEventListener('backbutton', this.handlerBackButton);
  142. }
  143. this.modalControl.clear();
  144. if (this.cancelModel) {
  145. this.cancelModel.clear();
  146. }
  147. this.confirmModel.clear();
  148. }
  149. // 物理返回键方法
  150. handlerBackButton() {
  151. try {
  152. modalIntance && modalIntance.success({ confirm: false, cancel: true, mask: false })
  153. modalIntance && modalIntance.hide();
  154. } catch(err) {
  155. console.error(err)
  156. }
  157. }
  158. }
  159. export default fyShowModal;