背景

在日常的需求开发中我们经常需要用到弹窗,那么在我们构建弹窗时,在引用组件是都需要引入组件DOM,然后通过事件来控制组件的影藏显示,调用也不是很方便;

本组件使用事前注册DOM的方式,业务方在使用时刻直接调用暴露的方法即可,无需再引用DOM。

示例

组件使用示例

import newDialog from “*./components/newDialog”

newDialog.open({title: "退出发布",content: '是否需要保存草稿箱?',btn: [{ text: "不保存" },{ text: "保存" }],callback: (event)=>{if(event.result == 2){//TODO}else { //TODO}}
});

API

参数 说明 类型 是否必填
title 弹窗标题 String
content 弹窗展示内容 String|ReactDom
btn 弹窗按钮可配置一个或者两个 Array
callback 弹窗响应回调方法 Function

弹窗按钮说明

//弹窗按钮是json数组配置的 最多配置两个
btn: [{ text: "不保存" },{ text: "保存" }],
//每个按钮只需要配置text按钮文案即可 样式和颜色都集成到css
//如果配置一个按钮就是底部长按钮 配置两个根据配置的数组顺序从左向右展示

回调参数

//点击按钮会返回回调数据并关闭弹出
{result: 1/2 //返回按钮的索引值
}

完整代码

js代码newDialog.tsx

'use strict';
import './newDialog.scss';
import * as React from 'react';
import cs from "classnames";
import * as ReactDOM from 'react-dom';
import { isIphoneX } from './../../util/util';
/** * @description 解决移动端滚动穿透事件 **/
const ModalHelper = (function (bodyCls) {var scrollTop;return {afterOpen: function () {scrollTop = document.scrollingElement.scrollTop;document.body.classList.add(bodyCls);document.body.style.top = -scrollTop + 'px';},beforeClose: function () {document.body.classList.remove(bodyCls);// scrollTop lost after set position:fixed, restore it back.document.scrollingElement.scrollTop = scrollTop;}};
})('modal-open');interface IAppProps {title?: string;content?: any;btn?: any;callback?: Function;
}interface IAppState {showToast?: Boolean;title?: string;content?: any;btn?: any;callback?: Function;isIPhoneX?: Boolean;
}
let DialogDiv;
class Dialog extends React.Component<IAppProps, IAppState> {constructor(props: IAppProps) {super(props);this.state = {showToast: true,isIPhoneX: false};}componentWillMount() {let isIPhoneX = isIphoneX();this.setState({isIPhoneX});}static open = (options) => {const { ...props } = options || {};DialogDiv = document.createElement('div');setTimeout(()=>{document.body.appendChild(DialogDiv);ReactDOM.render(<Dialog {...props}/> ,DialogDiv); },100);ModalHelper.afterOpen();}close = (param) => {let result = param +1;this.props.callback({ result: result });this.setState({showToast: false});document.body.removeChild(DialogDiv);ModalHelper.beforeClose();}render() {const { showToast, isIPhoneX } = this.state;const { title, content, btn } = this.props;let _twoBtn = btn.length > 1 ? true : false;return (<divclassName={cs('dialog-container', {show: showToast})}><div className="pay-box"><div className="new-dialog-box"><div className="dialog-title"> {title} </div><div className="dialog-content"> {content} </div><div className={cs('dialog-bottom flex', { isIPhoneX: isIPhoneX })}>{btn.map((item, idx) => {return (<divonClick={() => {this.close(idx);// item.callback();}}className={cs('dialog-btn', {margin_r: _twoBtn && idx == 0,default: _twoBtn && idx == 0})}>{item.text}</div>);})}</div></div></div></div>)}
}
export default Dialog;

css代码newDialog.scss

$baseFontSize: 16px !default;// pixels to rems
@function pxToRem($px) {@return $px / $baseFontSize * 1rem;
}.dialog-container {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, .7);display: none;z-index: 9999;&.show {display: block;}
}.new-dialog-box {width: 100%;min-height: pxToRem(195px);background: rgba(255, 255, 255, 1);position: absolute;box-sizing: border-box;margin: 0;bottom: 0;z-index: 9999;transition: all 0.3s;border-radius: pxToRem(8px) pxToRem(8px) 0 0;// display: flex;.dialog-title {font-size: pxToRem(19px);margin: pxToRem(25px) auto pxToRem(25px);text-align: center;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: rgba(51, 51, 51, 1);line-height: pxToRem(19px);}.dialog-content {padding: 0 pxToRem(25px);font-size: pxToRem(14px);font-family: PingFangSC-Regular, PingFang SC;color: rgba(51, 51, 51, 1);margin: 0 auto pxToRem(15px);text-align: center;color: rgba(0, 0, 0, 1);line-height: pxToRem(27px);min-height: pxToRem(50px);}.dialog-bottom {height: pxToRem(45px);padding: 0 pxToRem(20px);margin-bottom: pxToRem(15px);display: flex;&.isIPhoneX {margin-bottom: pxToRem(49px);}}.dialog-btn {// margin: 0 auto pxToRem(30px);// width: pxToRem(300px);flex: 1;height: pxToRem(45px);background-image: linear-gradient(-44deg, #FCAF3C 0%, #F25228 98%);box-shadow: 0 8px 14px 0 rgba(190,118,22,0.20);border-radius: pxToRem(45px);text-align: center;line-height: pxToRem(45px);font-size: pxToRem(15px);font-family: PingFangSC-Medium, PingFang SC;color: rgba(255, 255, 255, 1);&.margin_r {margin-right: pxToRem(24px);}&.default {background: #FFFFFF;border: 1px solid #E6E6E6;box-shadow: 0 10px 20px -8px rgba(173,173,173,0.30);border-radius: pxToRem(45px);font-size: pxToRem(15px);font-family: PingFang-SC-Medium, PingFang-SC;color: rgba(85, 85, 85, 1);}}
}

另外附上代码中iPhone X系列机型判断方法

export const isIphoneX = function() {// iPhone X、iPhone XSvar isIPhoneX =/iphone/gi.test(window.navigator.userAgent) &&window.devicePixelRatio &&window.devicePixelRatio === 3 &&window.screen.width === 375 &&window.screen.height === 812;// iPhone XS Maxvar isIPhoneXSMax =/iphone/gi.test(window.navigator.userAgent) &&window.devicePixelRatio &&window.devicePixelRatio === 3 &&window.screen.width === 414 &&window.screen.height === 896;// iPhone XRvar isIPhoneXR =/iphone/gi.test(window.navigator.userAgent) &&window.devicePixelRatio &&window.devicePixelRatio === 2 &&window.screen.width === 414 &&window.screen.height === 896;if (isIPhoneX || isIPhoneXSMax || isIPhoneXR) {return true;}return false;
}

React+TS免注册DOM页面dialog弹窗相关推荐

  1. 自定义dialog弹窗html,自定义H5页面dialog弹窗

    弹窗一: 样式如下: HTML代码://弹出窗 通知 取消 确认 //遮罩层 $('.dialog .content').text(text); $('.dialog, .mark').removeC ...

  2. html页面弹出dialog,自定义H5页面dialog弹窗

    弹窗一: 样式如下: HTML代码://弹出窗 通知 取消 确认 //遮罩层 $('.dialog .content').text(text); $('.dialog, .mark').removeC ...

  3. 【实习小tip】多层dialog弹窗遮罩问题、elementUI的form表单组件的select框在只读的情况下没办法拿到传来的数据、从弹窗子组件获取数据后需要刷新页面

    解决elementui多层dialog弹窗遮罩问题 弹窗套娃出现了整个屏幕都是遮罩层的问题,需要鼠标点击一下才能正常. 在弹窗组件代码上加上 append-to-body 就可以了,表示这个弹窗是嵌在 ...

  4. React+TS学习和使用(三):React Redux和项目的路由配置

    开启学习react+ts,本篇主要是学习使用React Redux和项目的路由配置 一.React Redux 需求:使用TS+React Redux实现一个累加. A. 安装 $ yarn add ...

  5. React + TS项目开发小技巧总结

    一.react hook知识 1.基本使用 最常用的Hook,有两个:useState.useEffect import React, { useState } from "react&qu ...

  6. 百度云的高速下载技巧系列2---多线程文件下载工具idm v6.28.1绿色免注册版(PC)

    原帖 https://www.landiannews.com/archives/33946.html IDM是国外非常流行的网络文件下载工具,其最大的特点就是功能方面几乎是用户可能使用到的都已经有了. ...

  7. React TypeScript react+ts 包下载

    react+ts下载使用 要使用 TypeScript 启动新的 Create React App 项目,您可以做以下 搭建TS+React的开发环境 Create React App 是一种官方支持 ...

  8. React + Ts项目搭建

    一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 一个好的项目必须有一个规范,所以得安装esl ...

  9. 免注册登陆以及QQ登陆

    (一)QQ登陆 (1)基本调用过程分析: ①生成授权连接,需要配置回调地址 https://graph.qq.com/oauth2.0/authorize?response_type=code& ...

最新文章

  1. [CVPR 2016] Weakly Supervised Deep Detection Networks论文笔记
  2. iOS transform解决连续多次旋转缩放,实现图片旋转缩放效果
  3. 简明python教程在线-Python简明教程
  4. Android跨进程通信一 Messenger
  5. 如何利用ESP8266模块实现远程控制
  6. toString、equals方法进阶
  7. 面试官系统精讲Java源码及大厂真题 - 17 并发 List、Map源码面试题
  8. python-利用生成器函数生成斐波那契数列
  9. MySQL日期处理-查询间隔数据
  10. CXF WebService整合SpringMVC的maven项目
  11. python二分法代码_Python的算法之二分法
  12. Java学习系列(十二)Java面向对象之序列化机制及版本
  13. 思科无线服务器,【CISCO wlan】思科无线网络_3-基本配置v2.pdf
  14. 卷积的本质及物理意义
  15. 大脚战场插件怎么关闭_魔兽战场插件 capping插件怎么关闭
  16. python编译原理 书籍_如何想学点编译原理,又不想直接看龙虎之类的书籍,太多理论,干燥?...
  17. 客房管理android源码,c++ 客房管理系统完整源码(含数据库)
  18. 手机浏览器简单搜索ua标识
  19. 四、函数的基本概念和使用
  20. 数据建模和数据库设计

热门文章

  1. prim算法详解java_Prim算法(三)之 Java详解
  2. 前端面试准备---浏览器和网络篇(一)
  3. Swift 4.0 中对 Dictionary 的改进(转载)
  4. sqoop 把 hdfs 和关系型数据库 (mysql等)互导
  5. 演示:思科交换机的Telnet管理与SSH管理
  6. Show ip arp 和 Show mac-address-table
  7. 让VS2008真正支持JQuery的智能感知
  8. Linux操作系统使用基础02:Linux系统安装与登陆
  9. NASM汇编语言与计算机系统11-9号与0X16号中断显示键盘输入(int)
  10. Intellij IDEA-我常用的快捷键