整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML DOM Dialog 对象

HTML DOM Dialog 对象

Dialog 对象

Dialog 对象是HTML5新增的。

Dialog 对象表示 HTML <dialog> 元素。

注意: 目前只有Chrome Canary,Safari 6 浏览器支持 <dialog> 元素。

访问 Dialog 对象

你可以使用 getElementById() 访问 <dialog> 元素:

var x=document.getElementById("myDialog");

创建 Dialog 对象

你可以使用 document.createElement() 方法创建 <dialog> 元素:

var x=document.createElement("DIALOG");

Dialog 对象属性

属性描述
open设置或者返回对话窗口是否打开
returnValue设置或者返回 dialog 的返回值

Dialog 对象方法

方法描述
close()关闭对话窗口
show()显示的对话框
showModal()显示对话框,并使其成为最顶层的对话框

标准属性和事件

Dialog 对象同样支持标准 属性 和 事件。

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

认功能

基本的对话框窗口是一个定位于视区中的覆盖层,同时通过一个 iframe 与页面内容分隔开(就像 select 元素)。它由一个标题栏和一个内容区域组成,且可以移动,调整尺寸,默认可通过 'x' 图标关闭。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 默认功能</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { $( "#dialog" ).dialog(); }); </script> </head> <body> <div id="dialog" title="基本的对话框"> <p>这是一个默认的对话框,用于显示信息。对话框窗口可以移动,调整尺寸,默认可通过 'x' 图标关闭。</p> </div> </body> </html>

查看演示

动画

可以通过为 show/hide 属性指定一个特效来动画显示对话框。您必须为想使用的特效引用独立的特效文件。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 动画</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { $( "#dialog" ).dialog({ autoOpen: false, show: { effect: "blind", duration: 1000 }, hide: { effect: "explode", duration: 1000 } }); $( "#opener" ).click(function() { $( "#dialog" ).dialog( "open" ); }); }); </script> </head> <body> <div id="dialog" title="Basic dialog"> <p>这是一个动画显示的对话框,用于显示信息。对话框窗口可以移动,调整尺寸,默认可通过 'x' 图标关闭。</p> </div> <button id="opener">打开对话框</button> </body> </html>

查看演示

基本的模态

模态对话框防止用户与对话框以外的页面其他部分进行交互,直到对话框关闭为止。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 基本的模态</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { $( "#dialog-modal" ).dialog({ height: 140, modal: true }); }); </script> </head> <body> <div id="dialog-modal" title="基本的模态对话框"> <p>添加模态覆盖屏幕,让对话框看起来更突出,因为它让页面上其他内容变暗。</p> </div> <p>Sed vel diam id libero <a href="http://www.w3cschool.cc">rutrum convallis</a>. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.</p> </body> </html>

查看演示

模态确认

确认一个动作可能是破坏性的也可能是有意义的。设置 modal 选项为 true,并通过 buttons 选项来指定主要的和次要的用户动作。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 模态确认</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { $( "#dialog-confirm" ).dialog({ resizable: false, height:140, modal: true, buttons: { "Delete all items": function() { $( this ).dialog( "close" ); }, Cancel: function() { $( this ).dialog( "close" ); } } }); }); </script> </head> <body> <div id="dialog-confirm" title="清空回收站吗?"> <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>这些项目将被永久删除,并且无法恢复。您确定吗?</p> </div> <p>Sed vel diam id libero <a href="http://www.w3cschool.cc">rutrum convallis</a>. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.</p> </body> </html>

模态表单

使用模态对话框来请求用户在一个多步骤过程中输入数据。在内容区域嵌入 form 标记,设置 modal 选项为 true,并通过 buttons 选项来指定主要的和次要的用户动作。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 模态表单</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> body { font-size: 62.5%; } label, input { display:block; } input.text { margin-bottom:12px; width:95%; padding: .4em; } fieldset { padding:0; border:0; margin-top:25px; } h1 { font-size: 1.2em; margin: .6em 0; } div#users-contain { width: 350px; margin: 20px 0; } div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; } div#users-contain table td, div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; } .ui-dialog .ui-state-error { padding: .3em; } .validateTips { border: 1px solid transparent; padding: 0.3em; } </style> <script> $(function() { var name=$( "#name" ), email=$( "#email" ), password=$( "#password" ), allFields=$( [] ).add( name ).add( email ).add( password ), tips=$( ".validateTips" ); function updateTips( t ) { tips .text( t ) .addClass( "ui-state-highlight" ); setTimeout(function() { tips.removeClass( "ui-state-highlight", 1500 ); }, 500 ); } function checkLength( o, n, min, max ) { if ( o.val().length > max || o.val().length < min ) { o.addClass( "ui-state-error" ); updateTips( "" + n + " 的长度必须在 " + min + " 和 " + max + " 之间。" ); return false; } else { return true; } } function checkRegexp( o, regexp, n ) { if ( !( regexp.test( o.val() ) ) ) { o.addClass( "ui-state-error" ); updateTips( n ); return false; } else { return true; } } $( "#dialog-form" ).dialog({ autoOpen: false, height: 300, width: 350, modal: true, buttons: { "创建一个帐户": function() { var bValid=true; allFields.removeClass( "ui-state-error" ); bValid=bValid && checkLength( name, "username", 3, 16 ); bValid=bValid && checkLength( email, "email", 6, 80 ); bValid=bValid && checkLength( password, "password", 5, 16 ); bValid=bValid && checkRegexp( name, /^[a-z]([0-9a-z_])+$/i, "用户名必须由 a-z、0-9、下划线组成,且必须以字母开头。" ); // From jquery.validate.js (by joern), contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ bValid=bValid && checkRegexp( email, /^((([a-z]|\d|[!#$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "eg. ui@jquery.com" ); bValid=bValid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "密码字段只允许: a-z 0-9" ); if ( bValid ) { $( "#users tbody" ).append( "<tr>" + "<td>" + name.val() + "</td>" + "<td>" + email.val() + "</td>" + "<td>" + password.val() + "</td>" + "</tr>" ); $( this ).dialog( "close" ); } }, Cancel: function() { $( this ).dialog( "close" ); } }, close: function() { allFields.val( "" ).removeClass( "ui-state-error" ); } }); $( "#create-user" ) .button() .click(function() { $( "#dialog-form" ).dialog( "open" ); }); }); </script> </head> <body> <div id="dialog-form" title="创建新用户"> <p>所有的表单字段都是必填的。</p> <form> <fieldset> <label for="name">名字</label> <input type="text" name="name" id="name" class="text ui-widget-content ui-corner-all"> <label for="email">邮箱</label> <input type="text" name="email" id="email" value="" class="text ui-widget-content ui-corner-all"> <label for="password">密码</label> <input type="password" name="password" id="password" value="" class="text ui-widget-content ui-corner-all"> </fieldset> </form> </div> <div id="users-contain"> <h1>已有的用户:</h1> <table id="users" class="ui-widget ui-widget-content"> <thead> <tr class="ui-widget-header "> <th>名字</th> <th>邮箱</th> <th>密码</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>john.doe@example.com</td> <td>johndoe1</td> </tr> </tbody> </table> </div> <button id="create-user">创建新用户</button> </body> </html>

模态消息

使用模态对话框来在下一步动作执行之前确认信息和动作。设置 modal 选项为 true,并通过 buttons 选项来指定主要的动作(Ok)。

<!doctype html> <html> <head> <meta charset="utf-8"> <title>jQuery UI 对话框(Dialog) - 模态消息</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <script> $(function() { $( "#dialog-message" ).dialog({ modal: true, buttons: { Ok: function() { $( this ).dialog( "close" ); } } }); }); </script> </head> <body> <div id="dialog-message" title="下载完成"> <p> <span class="ui-icon ui-icon-circle-check" style="float:left; margin:0 7px 50px 0;"></span> 您的文件已经成功下载到文件夹中。 </p> <p> 当前使用存储空间的 <b>36%</b>。 </p> </div> <p>Sed vel diam id libero <a href="http://www.w3cschool.cc">rutrum convallis</a>. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.</p> </body> </html>

下前端届最火的技术之一莫过于React + Redux + webpack的技术结合。最近公司内部也正在转react,这周主要做了个React的modal组件,接下来谈下具体实现过程。

基本的HTML结构

虽然React基于虚拟DOM,但他的JSX语法还是离不开最基本的HTML。第一步要做的就是通过HTML&&CSS实现Dialog垂直水平居中框。HTML结构如下:

 <div className="m-mask"></div>
 <div className="m-dialog">
 <div className="md-dialog">
 <div className="md-dialog-title">
 <h4>{title}</h4>
 <span className="btn">
 <i className="iconfont">&times;</i>
 </span>
 </div>
 <div className="md-dialog-content">
 {this.props.children}
 </div>
 <div className="md-dialog-foot">
 <a href="#" className="btns">取消</a>
 <a href="#" className="btns btns-blue">确定</a>
 </div>
 </div>
 </div>

ps: JSX语法的className对应于HTML中的class,其次文中的iconfont图标被换成了&times;

然后写下对应的CSS样式。此处主要说明一下主要的样式布局原理,细节略过。

Modal框的背景mask样式通过position:absolute + top/right/bottom/left:0 + height: 100%实现。

不定宽高的主体内容水平垂直居中的实现通过position:relative + top/left: 50% + translate(-50%, -50%)实现。

React Modal Component

有了已经想好的布局样式,开始实现最基本的Modal组件。因为需要动态控制组件的显隐,所以组件的显隐在内部要通过state方便控制,而其他属性则通过props实现。modal.js代码如下:

import React, { Component, PropTypes } from 'react'

const defaultProps={
    show: false,
    title: '',
    zIndex: 1000,
    onOk:=> {},
    onCancel:=> {},
}

const propTypes={
    title: PropTypes.string,
    zIndex: PropTypes.number,
    onOk: PropTypes.func,
    onCancel: PropTypes.func,
}

export default class Modal extends Component {
    constructor(props) {
        super(props)
        this.state={show: props.show}
    }
    render {
        return (
 // JSX语法的HTML
 );
    }
}

Modal.defaultProps=defaultProps
Modal.propTypes=propTypes

不过显隐内部通过state控制,但父组件还是需要通过props传递初始默认值。而且来回调用同一个modal时,父组件是通过props中的show属性控制。内部的state还是第一次调用时传入的props值。这样无法导致及时控制显隐。此时react的componentWillReceiveProps出场,完美解决这个bug。

俗话说bug是解不完的,虽然上面的组件勉强可以正常使用,但是用于样式通过绝对定位来做的,无形中导致了另外一个坑,如果Modal的父组件采用了相对或者绝对定位,即影响了Modal组件的定位,就会存在Modal出现在了某个div中,而不是理想的body中。bug复现如下:

unstable_renderSubtreeIntoContainer登场

为了保证我们的组件始终处于body中,采取了ReactDOM中的的这个不太正式的API。语法很简单:

ReactDOM.unstable_renderSubtreeIntoContainer(parent, component, dom)

parent一般是this,component是Modal,dom是div 代码实现如下:

export default class extends Component {
    appendMaskIntoDoc {
        ReactDOM.unstable_renderSubtreeIntoContainer(
 this,
 <Modal {...this.props}>
 {this.props.children}
 </Modal>,
 this.container
        )
    }

    componentDidMount {
        this.container=document.createElement('div')
        document.body.appendChild(this.container)
        this.appendMaskIntoDoc
    }

    componentDidUpdate {
        this.appendMaskIntoDoc
    }

    componentWillUnmount {
        document.body.removeChild(this.container)
    }

    render {
        return null
    }
}
API形式

此时,Modal组件已经成功做出来了。父组件可以成功调用,效果如下:

不过,偷偷see了下蚂蚁金服官网的Modal组件调用,还有一种API形式的调用。于是也简单实现了下。这里,简单说下实现思路吧。

Confirm function内部通过setState方法函数接受的参数传递给Modal的父组件dialog,onOk的promise异步回调则是在dialog内部通过处理之后再传递给Modal组件。

此处我是通过正则表达式检测new Promise,如果属于Promise,则给onOk绑定then,内部调用setState控制Modal的隐藏。不过在调用Confirm function之前,

dialog组件已经被render进ReactDOM中,render之前则需要dom节点,就需要能获取到document节点。然后手动创建空div节点添加到body中。

此处代码有点长,省略咯。