当前位置: 首页 > news >正文

网站建设需要什么软件有哪些网站下拉菜单设计

网站建设需要什么软件有哪些,网站下拉菜单设计,企业网站建设内容规划,做网站 域名 网站 空间普通的modal组件如下#xff1a; 我们写的modal额外支持#xff0c;后面没有蒙版#xff0c;并且Modal框能够拖拽 还支持渲染在文档流里#xff0c;上面的都是fixed布局#xff0c;我们这个正常渲染到文档下面#xff1a; render部分 RenderDialog{...restState}visi…普通的modal组件如下 我们写的modal额外支持后面没有蒙版并且Modal框能够拖拽 还支持渲染在文档流里上面的都是fixed布局我们这个正常渲染到文档下面 render部分 RenderDialog{...restState}visible{visible}prefixCls{prefixCls}header{renderHeader}attach{attach}closeBtn{renderCloseIcon()}classPrefix{classPrefix}onClose{onClose}onConfirm{onConfirm}footer{footer true ? defaultFooter() : footer}ref{dialogDom}/ 大家记住这个RenderDialog接下来都是上面传参的解释 resetState: 是对象一堆属性的集合哪些属性呢我们往下看 // 其实默认参数写到这里并不科学因为react有个静态属性defaultProps属性支持合并propsconst [state, setState] useSetStateDialogProps({width: 520, // 默认宽度是520visible: false, // 默认visible是falsezIndex: 2500, // 默认zIndex 2500placement: center, // 默认渲染到屏幕中间mode: modal, // 默认的模式是modal是ant那种渲染结果其他模式我们下面谈showOverlay: true, // 是否展示透明黑色蒙版destroyOnClose: false, // 关闭弹窗的时候是否销毁里面的内容draggable: false, // 是否能拖拽modalpreventScrollThrough: true, // 防止滚动穿透...props,}); restState在下面除了state上某些属性。 const { visible, // 控制对话框是否显示 attach, // 对话框挂载的节点默认挂在组件本身的位置。数据类型为 String 时会被当作选择器处理进行节点查询。示例body 或 () document.body closeBtn, // 关闭按钮可以自定义。值为 true 显示默认关闭按钮值为 false 不显示关闭按钮。值类型为 string 则直接显示值// 底部操作栏默认会有“确认”和“取消”两个按钮。值为 true 显示默认操作按钮值为 false 不显示任何内容值类型为 Function 表示自定义底部内容 footer true, // 如果“取消”按钮存在则点击“取消”按钮时触发同时触发关闭事件 onCancel noop, // 如果“确认”按钮存在则点击“确认”按钮时触发或者键盘按下回车键时触发 onConfirm noop, // 如果“确认”按钮存在则点击“确认”按钮时触发或者键盘按下回车键时触发 cancelBtn cancelText, // 取消按钮可自定义。值为 null 则不显示取消按钮。值类型为字符串则表示自定义按钮文本值类型为 Object 则表示透传 Button 组件属性。 confirmBtn confirmText, // 确认按钮。值为 null 则不显示确认按钮。值类型为字符串则表示自定义按钮文本值类型为 Object 则表示透传 Button 组件属性。 onClose noop, // 关闭事件点击取消按钮、点击关闭按钮、点击蒙层、按下 ESC 等场景下触发 ...restState} state; 说了这么多我们接着看RenderDialog组件上传入的属性。 prefixCls不讲了是css属性前缀一个字符串接着看header属性被包装为renderHeader const renderHeader useMemo(() {if (!state.header) return null;const iconMap {info: InfoCircleFilledIcon className{${classPrefix}-is-info} /,warning: InfoCircleFilledIcon className{${classPrefix}-is-warning} /,error: InfoCircleFilledIcon className{${classPrefix}-is-error} /,success: CheckCircleFilledIcon className{${classPrefix}-is-success} /,};return (div className{${prefixCls}__header-content}{iconMap[state.theme]}{state.header}/div);// eslint-disable-next-line react-hooks/exhaustive-deps}, [state.header, state.theme, prefixCls, classPrefix]); 其实就是在header的文字前面多了一个icon比如成功的弹窗如下 接着看closeBtn属性 const renderCloseIcon () {if (closeBtn false) return null;if (closeBtn true) return CloseIcon style{{ verticalAlign: unset }} /;return closeBtn || CloseIcon style{{ verticalAlign: unset }} /;}; 这个是右上角关闭按钮的Icon很简单如果是false什么都不许安然如果是undefined或者true渲染这个icon。 好了我们把整个代码放到下面有代码注释没写注释的是上面咋们已经讲过的内容接着就要进入RenderDialog这个组件内部了。 import 的部分省略了// 渲染 footer的button方法 const renderDialogButton (btn: TdDialogProps[cancelBtn], defaultProps: ButtonProps) {let result null;if (isString(btn)) {result Button {...defaultProps}{btn}/Button;}else if (isFunction(btn)) {result btn();}return result; };const Dialog forwardRef((props: DialogProps, ref: React.RefDialogInstance) {// 这部分忽略就好用来获取全局配置的css前缀字符串const { classPrefix } useConfig();// 这个也忽略获取icon组件的const { CloseIcon, InfoCircleFilledIcon, CheckCircleFilledIcon } useGlobalIcon({CloseIcon: TdCloseIcon,InfoCircleFilledIcon: TdInfoCircleFilledIcon,CheckCircleFilledIcon: TdCheckCircleFilledIcon,});// 用来引用dialog弹框的domconst dialogDom useRefHTMLDivElement();const [state, setState] useSetStateDialogProps({width: 520,visible: false,zIndex: 2500,placement: center,mode: modal,showOverlay: true,destroyOnClose: false,draggable: false,preventScrollThrough: true,...props,});// 国际化有关的const [local, t] useLocaleReceiver(dialog);const confirmText t(local.confirm);const cancelText t(local.cancel);const {visible,attach,closeBtn,footer true,onCancel noop,onConfirm noop,cancelBtn cancelText,confirmBtn confirmText,onClose noop,...restState} state;useEffect(() { setState((prevState) ({...prevState,...props,}));}, [props, setState, isPlugin]);const prefixCls ${classPrefix}-dialog;const renderCloseIcon () {if (closeBtn false) return null;if (closeBtn true) return CloseIcon style{{ verticalAlign: unset }} /;return closeBtn || CloseIcon style{{ verticalAlign: unset }} /;};// 这里把一些外部方法暴露给调用者只需要传入ref就可以获取React.useImperativeHandle(ref, () ({show() {setState({ visible: true });},hide() {setState({ visible: false });},destroy() {setState({ visible: false, destroyOnClose: true });},update(newOptions) {setState((prevState) ({...prevState,...(newOptions as DialogProps),}));},}));const renderHeader useMemo(() {if (!state.header) return null;const iconMap {info: InfoCircleFilledIcon className{${classPrefix}-is-info} /,warning: InfoCircleFilledIcon className{${classPrefix}-is-warning} /,error: InfoCircleFilledIcon className{${classPrefix}-is-error} /,success: CheckCircleFilledIcon className{${classPrefix}-is-success} /,};return (div className{${prefixCls}__header-content}{iconMap[state.theme]}{state.header}/div);// eslint-disable-next-line react-hooks/exhaustive-deps}, [state.header, state.theme, prefixCls, classPrefix]);// 渲染footer的时候点击取消按钮会用到const handleCancel (e: React.MouseEventHTMLButtonElement) {onCancel({ e });onClose({ e, trigger: cancel });};// 渲染footer的时候点击确认按钮会用到const handleConfirm (e: React.MouseEventHTMLButtonElement) {onConfirm({ e });};const defaultFooter () {const renderCancelBtn renderDialogButton(cancelBtn, { variant: outline });const renderConfirmBtn renderDialogButton(confirmBtn, { theme: primary });return ({renderCancelBtn React.cloneElement(renderCancelBtn, {onClick: handleCancel,...renderCancelBtn.props,})}{renderConfirmBtn React.cloneElement(renderConfirmBtn, {onClick: handleConfirm,...renderConfirmBtn.props,})}/);};return (RenderDialog{...restState}visible{visible}prefixCls{prefixCls}header{renderHeader}attach{attach}closeBtn{renderCloseIcon()}classPrefix{classPrefix}onClose{onClose}onConfirm{onConfirm}footer{footer true ? defaultFooter() : footer}ref{dialogDom}/); });Dialog.displayName Dialog; Dialog.defaultProps dialogDefaultProps;export default Dialog; 接着我们要渲染的部分其实很简单包括 背后的黑色蒙层弹框* 弹框的标题* 弹框的内容区域* 弹框的footer还需要弹框动画比如zoom或者fade 渲染黑色蒙层 代码如下很简单 const renderMask () {let maskElement;if (showOverlay) {maskElement (CSSTransitionin{visible}appeartimeout{transitionTime}classNames{${prefixCls}-fade}mountOnEnterunmountOnExitnodeRef{maskRef}div ref{maskRef} className{${prefixCls}__mask} //CSSTransition);}return maskElement;}; 首先介绍一下CSSTransition这是react-transition-group动画库的一个组件用来帮助我们实现css动画的。 其中一些属性说明如下 in ture就是开始动画false就是停止动画appearboolean为 false 时当 CSSTransition 控件加载完毕后不执行动画为 true 时控件加载完毕则立即执行动画。如果要组件初次渲染就有动画则需要设成 true。timeout 动画时间classNames动画的类名比如classNames:‘demo’会自动在进入动画的时候帮你把类名改为 demo-enter-active, demo-enter-done, 在退出动画同样会有类名的改变。mountOnEnter一进来的时候不显示dom元素unmountOnExitboolean为 true 时组件将移除处于隐藏状态的元素为 false 时组件保持动画结束时的状态而不移除元素。一般要设成 true。nodeRef获取蒙层的ref 蒙层主要靠css实现我们看下css position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 1;background: var(--td-mask-active);pointer-events: auto; 渲染弹框主体 也非常简单啊我们把注释写在下面的代码里了其中有一个需要小小注意的功能就是拖拽功能 // 渲染Dialog主体const renderDialog () {const dest: any {};// 把width变为有px结尾的字符串if (props.width ! undefined) {dest.width GetCSSValue(props.width);}// normal 场景下需要设置 zindex 为auto 避免出现多个 dialognormal 出现在最上层if (props.mode normal) {dest.zIndex auto;}// 获取footerconst footer props.footer ? div className{${prefixCls}__footer}{props.footer}/div : null;// 获取headerconst { header } props;// 获取Dialog bodyconst body div className{${prefixCls}__body}{props.body || props.children}/div;// 关闭按钮可以自定义。值为 true 显示默认关闭按钮值为 false 不显示关闭按钮。值类型为 string 则直接显示值如“关闭”。const closer closeBtn (span onClick{handleCloseBtnClick} className{${prefixCls}__close}{closeBtn}/span);const validWindow typeof window object;// 获取屏幕高度const screenHeight validWindow ? window.innerHeight || document.documentElement.clientHeight : undefined;// 获取屏幕宽度const screenWidth validWindow ? window.innerWidth || document.documentElement.clientWidth : undefined;// 设置styleconst style { ...dest, ...props.style };let dialogOffset { x: 0, y: 0 };// 拖拽代码实现部分const onDialogMove (e: MouseEvent) {// offsetWidth是指元素的宽 padding border的总和const { style, offsetWidth, offsetHeight } dialog.current;// diffX是指弹框部分距离body左边部分let diffX e.clientX - dialogOffset.x;let diffY e.clientY - dialogOffset.y;// 拖拽上左边界限制if (diffX 0) diffX 0;if (diffY 0) diffY 0;// 右边的限制if (screenWidth - offsetWidth - diffX 0) diffX screenWidth - offsetWidth;// 下边的限制if (screenHeight - offsetHeight - diffY 0) diffY screenHeight - offsetHeight;style.position absolute;style.left ${diffX}px;style.top ${diffY}px;};const onDialogMoveEnd () {// 恢复指针样式为默认并且注销mousemove mouseup事件dialog.current.style.cursor default;document.removeEventListener(mousemove, onDialogMove);document.removeEventListener(mouseup, onDialogMoveEnd);};// 拖拽开始对应mouseDown事件const onDialogMoveStart (e: React.MouseEventHTMLDivElement) {contentClickRef.current true;// 阻止事件冒泡 mode modeless才能拖拽if (canDraggable e.currentTarget e.target) {const { offsetLeft, offsetTop, offsetHeight, offsetWidth } dialog.current;// 如果弹出框超出屏幕范围 不能进行拖拽if (offsetWidth screenWidth || offsetHeight screenHeight) return;// 拖拽样式设置为movedialog.current.style.cursor move;// 计算鼠标 e.clientX是鼠标在屏幕的坐标offsetLeft是Dialog主体跟body的距离// 所以e.clientX - offsetLeft就是鼠标在是Dialog主体上的横坐标const diffX e.clientX - offsetLeft;const diffY e.clientY - offsetTop;dialogOffset {x: diffX,y: diffY,};// 此时把mousemove和mouseup事件也绑定一下其实不建议绑定在这里直接操作domdocument.addEventListener(mousemove, onDialogMove);document.addEventListener(mouseup, onDialogMoveEnd);}};// 顶部定位实现const positionStyle: any {};if (props.top) {const topValue GetCSSValue(props.top);positionStyle.paddingTop topValue;}// 此处获取定位方式 top 优先级较高 存在时 默认使用 top 定位const positionClass classnames(${prefixCls}__position,{ [${prefixCls}--top]: !!props.top },${props.placement !props.top ? ${prefixCls}--${props.placement} : },);// 然后就是用css去渲染header body和footerconst dialogElement (div className{isNormal ? : ${prefixCls}__wrap}div className{isNormal ? : positionClass} style{positionStyle} onClick{onMaskClick} ref{dialogPosition}divref{dialog}style{style}className{classnames(${prefixCls}, ${prefixCls}--default)}onMouseDown{onDialogMoveStart}div className{classnames(${prefixCls}__header)}{header}{closer}/div{body}{footer}/div/div/div);return (CSSTransitionin{props.visible}appearmountOnEnterunmountOnExit{destroyOnClose}timeout{transitionTime}classNames{${prefixCls}-zoom}onEntered{props.onOpened}onExited{onAnimateLeave}nodeRef{dialog}{dialogElement}/CSSTransition);}; 我们这里贴一下css部分 header .t-dialog__header {color: var(--td-text-color-primary);font: var(--td-font-title-medium);font-weight: 600;display: flex;align-items: flex-start;word-break: break-word; } 这里注意下word-wrap:break-word 它会把整个单词看成一个整体如果该行末端宽度不够显示整个单词它会自动把整个单词放到下一行而不会把单词截断掉的。 body .t-dialog__body {padding: 16px 0;color: var(--td-text-color-secondary);font: var(--td-font-body-medium);overflow: auto;word-break: break-word; } footer width: 100%;text-align: right;padding: 16px 0 0 0; 好了我们结合一下弹框和蒙层看下render函数 const render () {// 。。。省略css部分// 如果不是 modal 模式 默认没有 mask 也就没有相关点击 mask 事件const dialog (div ref{wrap} className{wrapClass} style{wrapStyle} onKeyDown{handleKeyDown} tabIndex{0}{mode modal renderMask()}{dialogBody} // 这里就是我们上面讲的renderDialog/div);return dialog;}; 设置body overflowhiiden 为啥要设置body overflowhiiden这个属性呢你打开modal弹窗的时候如果此时body还有滚动条那么你滚动鼠标滚轮还可以向下滑动但是一般情况下我们打开弹框是希望用户目标锁定在当前交互此时最好不要允许用户滚动界面。 当然你也可以允许用户滚动我们用一个preventScrollThrough参数控制。 先记住当前body的css样式以及body的overflow的值代码如下 useLayoutEffect(() {bodyOverflow.current document.body.style.overflow;bodyCssTextRef.current document.body.style.cssText;}, []); const isModal mode modal; useLayoutEffect(() { // 只有modal数量小于1的时候才重置样式因为可能出现多个弹框那么关闭一个弹框就出现滚动条明显不对if (isModal) {const openDialogDom document.querySelectorAll(${prefixCls}__mode);if (openDialogDom.length 1) {document.body.style.cssText bodyCssTextRef.current;}// 组件销毁后重置 body 样式return () {if (isModal) {// 此处只能查询 mode 模式的 dialog 个数 因为 modeless 会点击透传 normal 是正常文档流const openDialogDom document.querySelectorAll(${prefixCls}__mode);if (openDialogDom.length 1) {document.body.style.cssText bodyCssTextRef.current;document.body.style.overflow bodyOverflow.current;}} };}, [preventScrollThrough, attach, visible, mode, isModal, showInAttachedElement, prefixCls]); 上面的代码还有一个问题就是我们需要preventScrollThrough这个参数去控制是否可以body滚动页面这个也是算比ant更丰富的功能。 const isModal mode modal;useLayoutEffect(() {// 处于显示态if (visible) {// isModal表示是否是普通弹框就是带黑色蒙层的// bodyOverflow.current 引用的是body的overflow属性// preventScrollThrough是代表是否可以滚动body// showInAttachedElement表示不挂载到其他dom上if (isModal bodyOverflow.current ! hidden preventScrollThrough !showInAttachedElement) {// 求出滚动条的宽度const scrollWidth window.innerWidth - document.body.offsetWidth;// 减少回流if (bodyCssTextRef.current ) {let bodyCssText overflow: hidden;;if (scrollWidth 0) {bodyCssText position: relative;width: calc(100% - ${scrollWidth}px);;}document.body.style.cssText bodyCssText;} else {if (scrollWidth 0) {document.body.style.width calc(100% - ${scrollWidth}px);document.body.style.position relative;}document.body.style.overflow hidden;}}// 刚进页面就focus到弹框组件上if (wrap.current) {wrap.current.focus();}} else if (isModal) {const openDialogDom document.querySelectorAll(${prefixCls}__mode);if (openDialogDom.length 1) {document.body.style.cssText bodyCssTextRef.current;}}// 组件销毁后重置 body 样式return () {if (isModal) {// 此处只能查询 mode 模式的 dialog 个数 因为 modeless 会点击透传 normal 是正常文档流const openDialogDom document.querySelectorAll(${prefixCls}__mode);if (openDialogDom.length 1) {document.body.style.cssText bodyCssTextRef.current;document.body.style.overflow bodyOverflow.current;}} else {document.body.style.cssText bodyCssTextRef.current;document.body.style.overflow bodyOverflow.current;}};}, [preventScrollThrough, attach, visible, mode, isModal, showInAttachedElement, prefixCls]); 其实还有一个逻辑是把弹窗渲染到任意dom里需要一个Portal组件我们这里就不说了后续将Popup或者叫trigger组件的时候我们讲吧。一篇文档内容太多不好消化。 好了主逻辑已经写完了很简单吧 接下来看下完整代码没有注释的部分是上面已经讲过的 省去了import// 把css的数字转为有px结尾的字符串这里其实应该写到一个utils文件夹里不应该跟主代码混在一起 function GetCSSValue(v: string | number) {return Number.isNaN(Number(v)) ? v : ${Number(v)}px; }// 动画执行时间这里其实应该写到一个constants文件里不应该跟主代码混在一起 const transitionTime 300;const RenderDialog forwardRef((props: RenderDialogProps, ref: React.RefHTMLDivElement) {// 这里不用看跟国际化有关const [local] useLocaleReceiver(dialog);const {prefixCls, attach, // 对话框挂载的节点默认挂在组件本身的位置。数据类型为 String 时会被当作选择器处理进行节点查询。示例body 或 () document.bodyvisible, // 控制对话框是否显示mode, // 对话框类型有三种模态对话框、非模态对话框和普通对话框。弹出「模态对话框」时只能操作对话框里面的内容不能操作其他内容。弹出「非模态对话框」时则可以操作页面内所有内容。「普通对话框」是指没有脱离文档流的对话框可以在这个基础上开发更多的插件zIndex, // 对话框层级Web 侧样式默认为 2500移动端和小程序样式默认为 1500showOverlay, // 是否显示遮罩层onEscKeydown noop,// 按下 ESC 时触发事件onClosed noop, // 对话框消失动画效果结束后触发onClose noop, // 关闭事件点击取消按钮、点击关闭按钮、点击蒙层、按下 ESC 等场景下触发onCloseBtnClick noop, // 点击右上角关闭按钮时触发onOverlayClick noop, // 如果蒙层存在点击蒙层时触发onConfirm noop, // 如果“确认”按钮存在则点击“确认”按钮时触发或者键盘按下回车键时触发preventScrollThrough, // 防止滚动穿透closeBtn, // 关闭按钮可以自定义。值为 true 显示默认关闭按钮值为 false 不显示关闭按钮。值类型为 string 则直接显示值如“关闭”。值类型为 TNode则表示呈现自定义按钮示例closeOnEscKeydown, // 按下 ESC 时是否触发对话框关闭事件confirmOnEnter, // 是否在按下回车键时触发确认事件closeOnOverlayClick, // 点击蒙层时是否触发关闭事件destroyOnClose, // 是否在关闭弹框的时候销毁子元素showInAttachedElement, // 仅在挂载元素中显示抽屉默认在浏览器可视区域显示。父元素需要有定位属性如position: relative} props;const wrap useRefHTMLDivElement(); // 挂载到包裹弹框的dom上包裹了好几层。。。const dialog useRefHTMLDivElement(); // 引用弹窗domconst dialogPosition useRefHTMLDivElement(); // 包裹弹窗用于定位的dom引用const maskRef useRefHTMLDivElement(); // 蒙层的dom引用const bodyOverflow useRefstring(); const bodyCssTextRef useRefstring();const contentClickRef useRef(false);const isModal mode modal;const isNormal mode normal;const canDraggable props.draggable mode modeless;const dialogOpenClass ${prefixCls}__${mode};useLayoutEffect(() {bodyOverflow.current document.body.style.overflow;bodyCssTextRef.current document.body.style.cssText;}, []);useLayoutEffect(() {if (visible) {if (isModal bodyOverflow.current img srchttps://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCodeif (e.key Escape) {e.stopPropagation();onEscKeydown({ e });if (closeOnEscKeydown ?? local.closeOnEscKeydown) {onClose({ e, trigger: esc });}} else if (e.key Enter || e.key NumpadEnter) {// 回车键触发点击确认事件e.stopPropagation();if (confirmOnEnter) {onConfirm({ e });}}};// 渲染Dialog主体const renderDialog () {const dest: any {};// 把width变为有px结尾的字符串if (props.width ! undefined) {dest.width GetCSSValue(props.width);}// normal 场景下需要设置 zindex 为auto 避免出现多个 dialognormal 出现在最上层if (props.mode normal) {dest.zIndex auto;}// 获取footerconst footer props.footer ? div className{${prefixCls}__footer}{props.footer}/div : null;// 获取headerconst { header } props;// 获取Dialog bodyconst body div className{${prefixCls}__body}{props.body || props.children}/div;// 关闭按钮可以自定义。值为 true 显示默认关闭按钮值为 false 不显示关闭按钮。值类型为 string 则直接显示值如“关闭”。const closer closeBtn (span onClick{handleCloseBtnClick} className{${prefixCls}__close}{closeBtn}/span);const validWindow typeof window object;// 获取屏幕高度const screenHeight validWindow ? window.innerHeight || document.documentElement.clientHeight : undefined;// 获取屏幕宽度const screenWidth validWindow ? window.innerWidth || document.documentElement.clientWidth : undefined;// 设置styleconst style { ...dest, ...props.style };let dialogOffset { x: 0, y: 0 };// 拖拽代码实现部分const onDialogMove (e: MouseEvent) {// offsetWidth是指元素的宽 padding border的总和const { style, offsetWidth, offsetHeight } dialog.current;// diffX是指弹框部分距离body左边部分let diffX e.clientX - dialogOffset.x;let diffY e.clientY - dialogOffset.y;// 拖拽上左边界限制if (diffX 0) diffX 0;if (diffY 0) diffY 0;// 右边的限制if (screenWidth - offsetWidth - diffX 0) diffX screenWidth - offsetWidth;// 下边的限制if (screenHeight - offsetHeight - diffY 0) diffY screenHeight - offsetHeight;style.position absolute;style.left ${diffX}px;style.top ${diffY}px;};const onDialogMoveEnd () {// 恢复指针样式为默认并且注销mousemove mouseup事件dialog.current.style.cursor default;document.removeEventListener(mousemove, onDialogMove);document.removeEventListener(mouseup, onDialogMoveEnd);};// 拖拽开始对应mouseDown事件const onDialogMoveStart (e: React.MouseEventHTMLDivElement) {contentClickRef.current true;// 阻止事件冒泡 mode modeless才能拖拽if (canDraggable e.currentTarget e.target) {const { offsetLeft, offsetTop, offsetHeight, offsetWidth } dialog.current;// 如果弹出框超出屏幕范围 不能进行拖拽if (offsetWidth screenWidth || offsetHeight screenHeight) return;// 拖拽样式设置为movedialog.current.style.cursor move;// 计算鼠标 e.clientX是鼠标在屏幕的坐标offsetLeft是Dialog主体跟body的距离// 所以e.clientX - offsetLeft就是鼠标在是Dialog主体上的横坐标const diffX e.clientX - offsetLeft;const diffY e.clientY - offsetTop;dialogOffset {x: diffX,y: diffY,};// 此时把mousemove和mouseup事件也绑定一下其实不建议绑定在这里直接操作domdocument.addEventListener(mousemove, onDialogMove);document.addEventListener(mouseup, onDialogMoveEnd);}};// 顶部定位实现const positionStyle: any {};if (props.top) {const topValue GetCSSValue(props.top);positionStyle.paddingTop topValue;}// 此处获取定位方式 top 优先级较高 存在时 默认使用 top 定位const positionClass classnames(${prefixCls}__position,{ [${prefixCls}--top]: !!props.top },${props.placement !props.top ? ${prefixCls}--${props.placement} : },);const dialogElement (div className{isNormal ? : ${prefixCls}__wrap}div className{isNormal ? : positionClass} style{positionStyle} onClick{onMaskClick} ref{dialogPosition}divref{dialog}style{style}className{classnames(${prefixCls}, ${prefixCls}--default)}onMouseDown{onDialogMoveStart}div className{classnames(${prefixCls}__header)}{header}{closer}/div{body}{footer}/div/div/div);return (CSSTransitionin{props.visible}appearmountOnEnterunmountOnExit{destroyOnClose}timeout{transitionTime}classNames{${prefixCls}-zoom}onEntered{props.onOpened}onExited{onAnimateLeave}nodeRef{dialog}{dialogElement}/CSSTransition);};const renderMask () {let maskElement;if (showOverlay) {maskElement (CSSTransitionin{visible}appeartimeout{transitionTime}classNames{${prefixCls}-fade}mountOnEnterunmountOnExitnodeRef{maskRef}div ref{maskRef} className{${prefixCls}__mask} //CSSTransition);}return maskElement;};const render () {const style: CSSProperties {};if (visible) {style.display block;}const wrapStyle {...style,zIndex,};const dialogBody renderDialog();const wrapClass classnames(props.className,${prefixCls}__ctx,!isNormal ? ${prefixCls}__ctx--fixed : ,visible ? dialogOpenClass : ,isModal showInAttachedElement ? ${prefixCls}__ctx--absolute : ,props.mode modeless ? ${prefixCls}__ctx--modeless : ,);// 如果不是 modal 模式 默认没有 mask 也就没有相关点击 mask 事件const dialog (div ref{wrap} className{wrapClass} style{wrapStyle} onKeyDown{handleKeyDown} tabIndex{0}{mode modal renderMask()}{dialogBody}/div);let dom null;if (visible || wrap.current) {// normal 模式 attach 无效if (attach || isNormal) {dom dialog;} else {dom (CSSTransitionin{visible}appeartimeout{transitionTime}mountOnEnterunmountOnExit{destroyOnClose}nodeRef{portalRef}Portal attach{attach} ref{portalRef}{dialog}/Portal/CSSTransition);}}return dom;};return render() stylemargin: auto / });RenderDialog.defaultProps dialogDefaultProps;export default RenderDialog; 最后 最近还整理一份JavaScript与ES的笔记一共25个重要的知识点对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识提升工作效率。 有需要的小伙伴可以点击下方卡片领取无偿分享
http://www.dnsts.com.cn/news/61132.html

相关文章:

  • 网站建设实训室介绍wordpress 输出json
  • 南通网站建ui培训哪里好
  • 域名同时做邮箱和网站微网站如何建设方案
  • 西安seo网站设计公司对外贸易平台有哪些
  • 哪个网站的域名到期直接注册如何提高网站设计能力
  • 前端网站页面模板做高端网站公司
  • 襄阳网站排名优化江苏建设工程信息网网
  • 商业网站有什么作用如何在网上建设一个公司网站
  • 临沂做网站电话手机百度网址是什么
  • 2017网站建设报价表网站怎么去优化
  • 介绍自己做的网站的论文python3的网站开发
  • 网站后台公告id修改软件开发公司
  • 买一个成品网站多少钱深圳华南城网站建设
  • 临汾做网站公司哪家好凡客诚品正品官网
  • 医院网站素材怎么选择宜昌网站建设
  • 自己做盗版小说网站网架公司厂家
  • 怎么在欧美做网站推广西宁做网站公司排名
  • 宁波市住房和城乡建设厅网站搜索引擎收录
  • 陕西中洋建设工程有限公司网站网站建设代码模板
  • 做防护用品的网站wordpress头像存储
  • 凡客诚品官方网站查询网络推广方案的主要步骤
  • 柳州 网站建设上海网站营销怎么样
  • 宁波建设商城网站在哪里建网站比较好
  • 烟台定制网站建设公司东莞商城网站建设哪里比较好
  • 国内产品设计网站网页qq空间登录界面
  • 苏州市规划建设局网站网站备案接入商
  • 建设食品网站如何定位郑州大学科技园手机网站建设
  • 十大免费视频素材网站江西省城乡建设培训网站官方网站
  • 贵阳网站建设三思网络奉化区建设局网站
  • 帮人做网站推选的公司删除wordpress logo