wingmeng / front-end-quiz

前端小测试答题收集
0 stars 0 forks source link

DOM基础测试37:<dialog> 元素 #29

Open wingmeng opened 5 years ago

wingmeng commented 5 years ago

题目:

image


我的回答:

第 1 题:

const dialog = document.createElement('dialog');
document.body.appendChild(dialog);

第 2 题:

// 方法1:
dialog.open = true;  // 或其他为“真值”的基本类型,如 1,"abc" 等

// 方法2:
dialog.show();

// 方法3:
dialog.showModal();

第 3 题:

const btn = document.createElement('button');

btn.innerText = 'close';
btn.addEventListener('click', () => {
  // 方法1:
  dialog.open = false;  // 或其他“非真”的基本类型,如 0、null 等

  // 方法2:
  dialog.close();
});
dialog.appendChild(btn);

第 4 题:

// 用 showModal 方法即可让打开的 dialog 自带遮罩,在 CSS 里可通过 ::backdrop 设置遮罩层样式
dialog.showModal();

第 5 题:

思路:如果是 showModal() 方法打开的 dialog,则其覆盖层级默认是置顶的;而通过 show() 方法或 open 属性打开的 dialog,其覆盖层级遵循“后来居上”原则,所以需要手动调整其 z-index 值来使其覆盖层级置顶。

(function(dialogElm) {
  if (!dialogElm) return;

  const proto = dialogElm.prototype;
  const oldShow = proto.show;
  const dialogBaseLevel = 100;  // 对话框弹层的基准层级(根据项目zIndex规范合理设置)
  const getMaxZIndex = () => {
    const dialogs = document.querySelectorAll('dialog[open]');
    const maxZIndex = Math.max.apply(null, [...dialogs].map(it =>
      it.style.zIndex || Number(window.getComputedStyle(it).zIndex) || dialogBaseLevel
    ));

    return maxZIndex;
  };
  const setMaxZIndex = el => el.style.zIndex = getMaxZIndex() + 1;

  // 重写 show 方法
  proto.show = function() {
    setMaxZIndex(this);
    oldShow.call(this);
  };

  // "劫持" open 属性
  Object.defineProperty(proto, 'open', {
    set: function(value) {
      const isOpen = Boolean(isNaN(value) ? value : Number(value));
      this[isOpen ? 'show' : 'close']();
    }
  });
})(window.HTMLDialogElement);

测试 Demo