前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dialog 弹窗也有“花活”?针不戳~

Dialog 弹窗也有“花活”?针不戳~

作者头像
掘金安东尼
发布2023-01-10 14:06:11
5330
发布2023-01-10 14:06:11
举报

冲浪,看到一个 API HTMLDialogElement.showModal() - Web APIs | MDN

想想一直以来用 UI 框架的组件用惯了,即使自己写 Dialog,也只会老一套,用 JS + CSS display 属性来控制弹窗的显示和隐藏。

现在竟然直接有 API 方法了,纯 JS 实现。

🎉HTMLDialogElement.showModal()

赶紧码上掘金试一试,

https://code.juejin.cn/pen/7169464228376477707

掘了,一点 CSS 不带:

当然,有一点 CSS 不带的 Dialog 弹窗,相应的,也就有一点 JS 不带的纯 CSS 实现了~

🎉用 :target - CSS: Cascading Style Sheets | MDN 也能实现窗口的打开和关闭:

https://code.juejin.cn/pen/7169477440815759374

到这,还不足以说明:Dialog 弹窗也有“花活”

称得上花活的是 CSS :modal 伪类属性。

它用来检测当前的弹框,这样避免了在 JS 中管理 CSS

用法:

dialog:modal {
 scale: 2;
}

当出现弹框时,scale 赋值为 2

下面带来一个实战案例:

HTML

<div class="warning-message">
:modal isn't supported in this browser :(
</div>
<dialog>
<p>I'm a Dialog</p>
<button>Close</button>
</dialog>
<div class="actions">
<button data-modal="true">Open Modal</button>
<button data-modal="false">Open Non-modal</button>
</div>

CSS

layer demo {
  dialog[open]:not(:modal) {
    z-index: 2;
    transform-style: preserve-3d;
  }

  dialog[open]:not(:modal):before {
    content: "";
    position: fixed;
    height: 100vh;
    width: 100vw;
    top: 50%;
    left: 50%;
    background: hsl(0 0% 10% / 0.25);
    transform: translate3d(-50%, -50%, -1px);
  }
}

@layer base {
  *,
  *:after,
  *:before {
    box-sizing: border-box;
  }

  body {
    display: grid;
    place-items: center;
    min-height: 100vh;
    background: var(--gradient-3);
    font-family: "Google Sans", sans-serif, system-ui;
  }

  .actions {
    display: flex;
    gap: var(--size-4);
  }

  dialog {
    padding: var(--size-4);
    gap: var(--size-2);
    background: var(--surface-1);
  }

  dialog::backdrop {
    background: hsl(0 0% 10% / 0.5);
  }

  dialog[open] {
    display: grid;
  }

  .warning-message {
    border: var(--size-1) solid var(--yellow-4);
    padding: var(--size-4);
    background: var(--gray-0);
    position: fixed;
    top: var(--size-4);
    left: var(--size-4);
  }
  @supports (selector(:modal)) {
    .warning-message {
      display: none;
    }
  }
}

* JS

const BUTTONS = document.querySelectorAll("button");
const DIALOG = document.querySelector("dialog");

BUTTONS.forEach((BUTTON) => {
  BUTTON.addEventListener("click", (e) => {
    let modalStyle;
    switch (BUTTON.getAttribute("data-modal")) {
      case "true":
        modalStyle = "showModal";
        break;
      case "false":
        modalStyle = "show";
        break;
      default:
        modalStyle = "close";
    }
    DIALOG[modalStyle]();
  });
});

我们可以检测出非 :modal 的 dialog,为了以示区别,再加一个伪类 :before,做点不一样的样式出来。

你可以在这里测试:Is it :modal? 需要特别强调的是,它是一个比较新的属性,**浏览器兼容目前还比较差**,不过我们可以给予适当关注。

其实,这种思想是非常好的:即避免在 JS 中操作更多的样式。你可以去取值,去共享 CSS 的能力,但是不要去改值,不然样式问题就一团糟了~ 细看以上代码还有很多有趣的用法,比如:

@layer ...
@supports (selector(:modal)) {
    .warning-message {
      display: none;
    }
}

你知道它们都是干什么用的吗?

@layer - CSS: Cascading Style Sheets | MDN

@supports - CSS: Cascading Style Sheets | MDN

把代码 clone 在线运行试试,进一寸有一寸的欢喜~ OK,以上便是本篇分享,希望各位工友喜欢~ 欢迎点赞、收藏、评论 🤟 我是掘金安东尼 🤠 100 万人气前端技术博主 💥 INFP 写作人格坚持 1000 日更文 ✍ 关注我,安东尼陪你一起度过漫长编程岁月 🌏 😺我的博客:[https://tuaran.github.io](https://tuaran.github.io/) 😸公众号:掘金安东尼

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档