• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

JavaScript 练手小HTML5 的 dialog 标签弄一个对话框

武飞扬头像
stones4zd
帮助3

对话框,在应用中常常用来做信息提示、特定操作(如,登录、删除信息等)。

学新通

一、传统对话框做法

以前创建对话框,需要用<div> 标签去模拟,或者使用一些框架、插件,如 artDialogboostrap 等,去创建对话框

如:使用<div> 标签去模拟对话框

  1.  
    <style>
  2.  
    .dialog{
  3.  
    background: #fff;
  4.  
    padding: 15px;
  5.  
    position: fixed;
  6.  
    z-index: 10000;
  7.  
    left:50%;
  8.  
    top:50%;
  9.  
    transform: translateX(-50%) translateY(-50%);
  10.  
    box-shadow: 0 0 20px 0 rgba(0,0,0,0.3);
  11.  
    border-radius:15px;
  12.  
    }
  13.  
    div.mask{
  14.  
    position: fixed;
  15.  
    z-index: 9999;
  16.  
    left:0;
  17.  
    right:0;
  18.  
    bottom:0;
  19.  
    top:0;
  20.  
    background: rgba(0,0,100,0.6);
  21.  
    }
  22.  
    .dialogBtn{
  23.  
    text-align: center;
  24.  
    padding-top: 15px;
  25.  
    }
  26.  
    .dialogBtn button{
  27.  
    cursor: pointer;
  28.  
    padding-left: 15px;
  29.  
    padding-right: 15px;
  30.  
    height: 30px;
  31.  
    background: #3f74e3;
  32.  
    color: #fff;
  33.  
    font-size: 14px;
  34.  
    text-shadow: 1px -1px 0 rgba(0,0,0,0.5);
  35.  
    border:none;
  36.  
    border-radius: 5px;
  37.  
    }
  38.  
    .dialogBtn button:hover{
  39.  
    background: #1846a8;
  40.  
    }
  41.  
    .dialogContent{
  42.  
    min-width: 300px;
  43.  
    min-height:80px;
  44.  
    font-size: 16px;
  45.  
    line-height: 1.5;
  46.  
    display: flex;
  47.  
    justify-content: center;
  48.  
    align-items: center;
  49.  
    }
  50.  
    </style>
  51.  
    <div class="dialog">
  52.  
    <div class="dialogContent">
  53.  
    <p>
  54.  
    对话框的内容
  55.  
    </p>
  56.  
    </div>
  57.  
    <div class="dialogBtn">
  58.  
    <button type="button">确定</button>
  59.  
    </div>
  60.  
    </div>
  61.  
    <div class="mask"></div>
学新通

学新通

二、dialog 标签

<dialog> 是HTML5新增的语义化双标签,用于展示一个交互式的模态对话框

它既可以创建模态化对话框(带半透明背景遮罩层的对话框,必须完成对话框操作后,如单击【确定】或【取消】按钮等将该对话框关闭,才能进行下一步操作。),也可以创建非模态化对话框

既可以使用键盘,点击按钮关闭对话框;也可以使用 esc键 关闭对话框。

  • 模态化对话框

学新通

  •  非模态化对话框

学新通

三、基础使用

1. 基础结构和样式

<dialog>双标签,可以在它的头尾标签之间自定义对话框内容。如:

  1.  
    <dialog>
  2.  
    <h1>这个是对话框的内容</h1>
  3.  
    <p>
  4.  
    这是一个简单的对话框
  5.  
    </p>
  6.  
    </dialog>

默认<dialogo> 标签是不可见的。

要显示对话框,需要添加 open 属性。

  1.  
    <dialog open>
  2.  
    <h1>这个是对话框的内容</h1>
  3.  
    <p>
  4.  
    这是一个简单的对话框
  5.  
    </p>
  6.  
    </dialog>

学新通

 <dialog> 标签基础样式:

  1.  
    dialog {
  2.  
    display: none;
  3.  
    position: absolute;
  4.  
    inset-inline-start: 0px;
  5.  
    inset-inline-end: 0px;
  6.  
    width: fit-content;
  7.  
    height: fit-content;
  8.  
    background-color: canvas;
  9.  
    color: canvastext;
  10.  
    margin: auto;
  11.  
    border-width: initial;
  12.  
    border-style: solid;
  13.  
    border-color: initial;
  14.  
    border-image: initial;
  15.  
    padding: 1em;
  16.  
    }
  17.  
    dialog[open] {
  18.  
    display: block;
  19.  
    }
学新通

注意几个细节:

  1. <dialog> 标签的显示与隐藏是通过 display:block/none; 进行操作的。意味着,<dialog> 标签默认不能进行透明度渐隐变化。

  2. <dialog> 标签默认是绝对定位的。

  3. <dialog> 标签自带有 1em 的 padding 值。

  4. <dialog> 标签是通过设置 margin:auto 实现的水平居中。

2. JS控制对话框的显示隐藏

<dialog> 标签常用方法:

(1)show()

非模态化显示对话框,对其添加open属性。在非模态化下,不能使用 esc 键让对话框消失。

如:点击按钮,显示对话框。

  1.  
    let btn = document.getElementById("btn");
  2.  
    let myDialog = document.querySelector("#myDialog"); // 获取对话框标签
  3.  
    btn.addEventListener("click",function (e) {
  4.  
    myDialog.show();
  5.  
    });

学新通

(2)showModal()

模态化显示对话框,对其添加open属性并且显示遮罩层同时按ESC键可以关闭对话框。

  1.  
    let btn = document.getElementById("btn");
  2.  
    let myDialog = document.querySelector("#myDialog"); // 获取对话框标签
  3.  
    btn.addEventListener("click",function (e) {
  4.  
    myDialog.showModal();
  5.  
    });

模态化<diglog> 的样式:

  1.  
    dialog:modal {
  2.  
    position: fixed;
  3.  
    inset-block-start: 0px;
  4.  
    inset-block-end: 0px;
  5.  
    max-width: calc((100% - 6px) - 2em);
  6.  
    max-height: calc((100% - 6px) - 2em);
  7.  
    user-select: text;
  8.  
    visibility: visible;
  9.  
    overflow: auto;
  10.  
    }

遮罩层是 <diglog> 的伪标签::backdrop。其默认样式为:

  1.  
    dialog::backdrop {
  2.  
    position: fixed;
  3.  
    top: 0px;
  4.  
    right: 0px;
  5.  
    bottom: 0px;
  6.  
    left: 0px;
  7.  
    background: rgba(0, 0, 0, 0.1);
  8.  
    }

因此,修改遮罩层就修改::backdrop的样式。

注意几个细节:

  1. 模态化<dialog> 标签的样式是通过 dialog:modal 控制,区别于普通状态的 <dialog>

  2. 模态化<dialog> 标签和遮罩层,都是固定定位的。

  3. 模态化<dialog> 标签是通过设置 margin:auto 实现的水平居中

    垂直居中模态化<dialog> 标签,可以使用以下样式。

  1.  
    .myDialog{
  2.  
    top:50%;
  3.  
    transform: translateY(-50%);
  4.  
    }

(3)close()

关闭对话框,删除其open属性,同时将close方法参数保留至dialog.returnValue属性上。

如,以下代码会在第二次显示对话框的时候,输出“abc”。

  1.  
    let btn = document.getElementById("btn");
  2.  
    let btn2 = document.getElementById("btn2");
  3.  
    let myDialog = document.querySelector("#myDialog"); // 获取对话框标签
  4.  
    btn.addEventListener("click",function (e) {
  5.  
    myDialog.show();
  6.  
    console.info(myDialog.returnValue);
  7.  
    });
  8.  
    btn2.addEventListener("click",function (e) {
  9.  
    myDialog.close("abc");
  10.  
    });

利用该方法,可以给对话框添加自定义的“关闭”按钮。

  1.  
    <dialog class="myDialog" id="myDialog">
  2.  
    <div class="myDialogClose" onclick="this.parentNode.close()">关闭</div>
  3.  
    <h1>这个是对话框的内容</h1>
  4.  
    <p>
  5.  
    这是一个简单的对话框
  6.  
    </p>
  7.  
    </dialog>
  1.  
    .myDialogClose{
  2.  
    width: 40px;
  3.  
    height: 40px;
  4.  
    background: #f90;
  5.  
    color: #fff;
  6.  
    line-height: 40px;
  7.  
    font-size: 12px;
  8.  
    text-align: center;
  9.  
    position: absolute;
  10.  
    right:-20px;
  11.  
    top:-20px;
  12.  
    cursor: pointer;
  13.  
    }

学新通

3. 对话框事件

(1)close 事件

当对话框关闭时触发。

  1.  
    myDialog.addEventListener("close",function(e){
  2.  
    console.info(e.target); // 输出对话框标签
  3.  
    });

(2)cancel 事件

当按下ESC关闭模态对话框时触发,同时也会触发 close 事件。

  1.  
    myDialog.addEventListener("close",function(e){
  2.  
    console.info(e.target);
  3.  
    });
  4.  
    myDialog.addEventListener("cancel",function(e){
  5.  
    console.info("esc");
  6.  
    });

学新通

 注意顺序:先 cancel 事件,后 close 事件。

四、应用

1. 点击 dialog 关闭对话框

有时候,我们需要点击遮罩层(也属于<dialog> 标签的一部分)就要关闭对话框。

但是,点击对话框的内容,也在点击<dialog> 标签。

因此,要判断点击对象的 nodeName 是否是 dialog,是,就说明点击了遮罩层,关闭对话框;不是,就是点击了<dialog> 标签里的内容,不需要关闭对话框。

为了保证最佳点击效果,强烈建议对话框的内容用一个div单独包裹,而不是把内容直接堆在<dialog> 标签里。

  1.  
    <button type="button" id="btn">点击显示对话框</button>
  2.  
    <button type="button" id="btn2">点击删除对话框</button>
  3.  
    <dialog class="myDialog" id="myDialog">
  4.  
    <div class="myDialogClose" id="closeDiv">关闭</div>
  5.  
    <!-- 对话框内容 -->
  6.  
    <div class="dialogContent">
  7.  
    <h1>这个是对话框的内容</h1>
  8.  
    <p>
  9.  
    这是一个简单的对话框
  10.  
    </p>
  11.  
    </div>
  12.  
    <!-- 对话框内容 end -->
  13.  
    </dialog>
  1.  
    myDialog.addEventListener("click",function(e){
  2.  
    if(e.target.nodeName.toLowerCase() == "dialog"){
  3.  
    myDialog.close();
  4.  
    }
  5.  
    });

可以约定一个属性closeByMask,若标签上存在该属性,则可以进行点击遮罩层进行关闭:

  1.  
    <dialog closeByMask></dialog>
  2.  
    <dialog closeByMask></dialog>

然后添加以下脚本即可:

  1.  
    document.querySelectorAll("dialog[closeByMask]").forEach(dialog => {
  2.  
    dialog.addEventListener("click",function(e){
  3.  
    if(e.target.nodeName.toLowerCase() == "dialog") {
  4.  
    this.close();
  5.  
    }
  6.  
    }
  7.  
    });

这样页面中所有的模态化对话框,点击遮罩层都可以关闭。

2. dialog 跟表单结合

可以在 dialog 标签里添加表单,增加按钮,实现数据传递等。

  1.  
    <dialog class="myDialog" id="myDialog">
  2.  
    <div class="myDialogClose" id="closeDiv">关闭</div>
  3.  
    <!-- 对话框内容 -->
  4.  
    <div class="dialogContent">
  5.  
    <h1>这个是对话框的内容</h1>
  6.  
    <p>
  7.  
    这是一个简单的对话框
  8.  
    </p>
  9.  
    <div class="form">
  10.  
    <form method="dialog">
  11.  
    <button type="submit">确定</button>
  12.  
    <button type="button">取消</button>
  13.  
    </form>
  14.  
    </div>
  15.  
    </div>
  16.  
    <!-- 对话框内容 end -->
  17.  
    </dialog>
学新通

学新通

注意:

  1. <form> 标签添加属性 method = "dialog",当点击submit 按钮的时候就会关闭对话框。

  2. 如果,有多个 submit 按钮,可以给按钮添加 value 属性。在 close 事件里,利用returnValue 属性判断点击了哪个 submit按钮。从而可以选择执行不同的代码。

  3. 但是在执行完代码后,记得清空 returnValue 的值,否则会一直保留在 myDialog上。

  1.  
    <dialog class="myDialog" id="myDialog">
  2.  
    <div class="myDialogClose" id="closeDiv">关闭</div>
  3.  
    <!-- 对话框内容 -->
  4.  
    <div class="dialogContent">
  5.  
    <h1>这个是对话框的内容</h1>
  6.  
    <p>
  7.  
    这是一个简单的对话框
  8.  
    </p>
  9.  
    <div class="form">
  10.  
    <form method="dialog">
  11.  
    <button type="submit" value="ok">确定</button>
  12.  
    <button type="submit" value="no">取消</button>
  13.  
    </form>
  14.  
    </div>
  15.  
    </div>
  16.  
    <!-- 对话框内容 end -->
  17.  
    </dialog>
学新通
  1.  
    myDialog.addEventListener("close",function(e){
  2.  
    console.info("close");
  3.  
    let rV = myDialog.returnValue;
  4.  
    console.info( rV );
  5.  
    if(rV =="ok"){
  6.  
    console.info("你点了确定");
  7.  
    }else if(rV =="no"){
  8.  
    console.info("你点了取消");
  9.  
    }else{
  10.  
    console.info("其它操作");
  11.  
    }
  12.  
    myDialog.returnValue = ""; // 清空该值,否则会一直保留到对话框上。
  13.  
    });

3. 隐藏显示添加动画

默认,<dialog> 标签的显示与隐藏是通过 display:block/none; 进行操作的。意味着,<dialog> 标签默认不能进行透明度渐隐变化。

因此,要修改为 opacity 属性来实现渐隐变化。

但是,隐藏的时候 opacity:0 ,用户仍然可以点击<dialog> 标签。所以,还要结合 visibility:hidden; 属性来让用户不能点击透明度为 0 的对话框标签。

  1.  
    dialog {
  2.  
    display: block;
  3.  
    opacity: 0;
  4.  
    visibility: hidden;
  5.  
    transition: all 0.2s;
  6.  
    }
  7.  
    dialog[open] {
  8.  
    display: block;
  9.  
    opacity: 1;
  10.  
    visibility: visible;
  11.  
    }

兼容性

目前主流浏览器都支持 <diglog> 标签,可以放心使用。

学新通

本篇文章来至:学新通

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通
  • 本文地址: https://www.swvq.com/boutique/detail/tanhcikkfj
  • 联系方式: luke.wu#vfv.cc
系列文章
更多 icon
同类精品
更多 icon
我要评论
我的头像
精彩评论
继续加载