实现vant Dialog 函数 - 戴向天

大家好!我叫戴向天

QQ群:602504799

如若有不理解的,可加QQ群进行咨询了解
具体CSS样式群里面有。

JS代码如下

// 保持DOM元素唯一
const baseDom = {
  overlay: null,
  dialog: null,
}
// 获取最大的z-index值
const getMaxZndex = () => {
  let arr = [...document.all].map(e => +window.getComputedStyle(e).zIndex || 0);
  return arr.length ? Math.max(...arr) + 1 : 0
}
// 显示
const fadeIn = (dom) => {
  dom.style.display = '';
  dom.classList.add('mobile-fade-enter-active');
  setTimeout(() => {
    dom.classList.remove('mobile-fade-enter-active')
  }, 300)
}
// 隐藏
const fadeOut = (dom) => {
  dom.classList.add('mobile-fade-leave-active');
  setTimeout(() => {
    dom.style.display = 'none';
    dom.classList.remove('mobile-fade-leave-active');
  }, 300)
}
// 背景
const Overlay = (callback) => {
  if (!baseDom.overlay) {
    baseDom.overlay = document.createElement('div');
    document.body.appendChild(baseDom.overlay)
  }
  baseDom.overlay.style.zIndex = getMaxZndex() - 1;
  baseDom.overlay.classList = 'mobile-overlay'

  fadeIn(baseDom.overlay);
  baseDom.overlay.onclick = () => {
    fadeOut(baseDom.overlay)
    callback && callback()
  }
  return baseDom.overlay;
}
// 创建dialog的内容
const generateDialog = async (option) => {
  return await new Promise((r, j) => {
    option = {
      ...option
    }
    let overlay = null;
    if (option.overlay === undefined || option.overlay === true) {
      overlay = Overlay(() => {
        r(false)
      })
    }
    if (!baseDom.dialog) {
      baseDom.dialog = document.createElement('div');
      baseDom.dialog.classList = 'mobile-dialog';
      document.body.appendChild(baseDom.dialog)
    }
    baseDom.dialog.innerHTML = null;
    baseDom.dialog.style.zIndex = getMaxZndex();
    const header = document.createElement('div');
    header.classList = 'mobile-dialog__header';
    header.innerHTML = option.title || '';
    const content = document.createElement('div');
    content.classList = 'mobile-dialog__content';
    const message = document.createElement('div');
    message.classList = 'mobile-dialog__message mobile-dialog__message--has-title';
    message.innerHTML = option.message || '';
    content.appendChild(message)
    header.appendChild(content)
    const footer = document.createElement('div');
    footer.classList = 'mobile-hairline--top mobile-dialog__footer';
    let cancelButton = null;
    if (option.showCancelButton) {
      // 取消按钮
      cancelButton = document.createElement('button');
      cancelButton.classList = 'mobile-button mobile-button--default mobile-button--large mobile-dialog__cancel';
      const cancelSpan = document.createElement('span');
      cancelSpan.classList = 'mobile-button__text';
      cancelButton.innerHTML = option.cancelButtonText || '取消'
      cancelButton.appendChild(cancelSpan);
      footer.appendChild(cancelButton)
      cancelButton.onclick = () => {
        overlay && fadeOut(overlay)
        r(false)
      }
    }
    let confirmButton = null;
    if (option.showConfirmButton === undefined || option.showConfirmButton === true) {
      // 确认按钮

      confirmButton = document.createElement('button');
      confirmButton.classList = 'mobile-button mobile-button--default mobile-button--large mobile-dialog__confirm';
      if (cancelButton) {
        confirmButton.classList.add('mobile-hairline--left')
      }
      const confirmSpan = document.createElement('span');
      confirmSpan.classList = 'mobile-button__text';
      confirmSpan.innerHTML = option.confirmButtonText || '确认'
      confirmButton.appendChild(confirmSpan);
      footer.appendChild(confirmButton)
      confirmButton.onclick = () => {
        overlay && fadeOut(overlay)

        r(true)
      }
    }

    if (confirmButton && cancelButton) {
      footer.classList.add('mobile-dialog__footer--buttons')
    }


    baseDom.dialog.appendChild(header)
    baseDom.dialog.appendChild(content)
    baseDom.dialog.appendChild(footer)

    fadeIn(baseDom.dialog);
  })

}
const Dialog = async (option) => {
  const bool = await generateDialog(option);
  fadeOut(baseDom.dialog)
  return bool
}
Dialog.alert = async (option) => {
  const bool = await generateDialog({ ...option, showCancelButton: false });
  fadeOut(baseDom.dialog)
  return bool
}
Dialog.confirm = async (option) => {
  const bool = await generateDialog({ ...option, showCancelButton: true });
  fadeOut(baseDom.dialog)
  return bool
}
export {
  Dialog
};

使用如下

await Dialog({
  title: 'Dialog',
  message: '欢迎使用',
});
await Dialog.alert({
  title: 'Alert',
  message: '欢迎使用',
})
await Dialog.confirm({
  title: 'Confirm',
  message: '欢迎使用',
})

猜你喜欢

转载自blog.csdn.net/weixin_41088946/article/details/104685178