前端小功能:新手引导高亮

前端小功能:新手引导高亮

其实就是一个遮罩层加一个弹窗,只不过比一般弹窗稍微复杂一点的是,遮罩层之上除了弹窗之外,还有需要高亮引导的元素区域,并且弹窗的位置也并不是固定的,而是跟随高亮引导区域进行定位。

border实现:

这种实现方法只用到了一个额外元素,使用 toprightbottomleft 四个元素分别使用一个元素的四条边(border)来代替,相比于正常元素的border来说,这个元素的border-width会比较大,以至于可以填充满除了 新功能区域 之外页面剩余的区域,再将 border-color设置为正常遮罩层的背景色,border就伪装好了。

直接使用代码:

/* eslint-disable valid-jsdoc */
export function HighlightBoot() {
  this.clientHeight =
    document.documentElement.clientHeight || document.body.clientHeight;
  this.clientWidth =
    document.documentElement.clientWidth || document.body.clientHeight;
  /**
   *
   * @param id 高亮DOM
   */
  this.openBoot = ({ id = '' }) => {
    const domId = document.getElementById(id);
    if (!domId) {
      throw new Error('id 选择标识无效');
    }
    const element = document.documentElement;
    const { top: initTop, height: initHeight } = domId.getBoundingClientRect();
    // 是否在可视区域
    const customHeight = 70; // 出现底部导航栏时需要减去高度
    if (initHeight + initTop > this.clientHeight - customHeight) {
      const scrollHeight =
        initHeight + initTop - (this.clientHeight - customHeight);
      element.scrollTop = scrollHeight;
    }
    // 关闭页面滚动
    element.style.overflow = 'hidden';
    // 重新计算位置
    const domMockId = document.getElementById(id);
    const { top, left, width, height } = domMockId.getBoundingClientRect();

    // 创建高亮mock蒙版
    const domMock = document.createElement('div');
    domMock.setAttribute(
      'style',
      `position: fixed;
      top:0;
      left:0;
      border:1px solid rgba(0,0,0,0.5);
      z-index: 99999;
      border-top-width: ${top}px;
      border-right-width: ${this.clientWidth - left - width}px;
      border-bottom-width: ${this.clientHeight - height - top}px;
      border-left-width: ${left}px;
      width: ${width}px;
      height: ${height}px; `
    );
    element.appendChild(domMock);

    const closeMock = document.createElement('div');
    closeMock.innerText = '×';
    closeMock.setAttribute(
      'style',
      `position: absolute;
      top: -30px;
      cursor: pointer;
      left: ${width}px;
      font-size: 14px;
      color: #fff;
      z-index: 2;
      text-align: center;
      line-height: 30px;
      border-radius: 50%;
      border: 1px solid #fff;
      width: 30px;
      height: 30px; `
    );
    domMock.appendChild(closeMock);

    closeMock.addEventListener('click', () => {
      element.removeChild(domMock);
      element.style.overflow = 'auto';
    });
  };
}

export default HighlightBoot;

直接上对象了,扩展自定义的配置就靠自己去处理了。

const boot = new HighlightBoot();
boot.openBoot({ id: 'notice-tip' });

注意:当页面异步加载,页面结构会改变元素位置的时候,需要在页面更新完成后再调用。

 

 

没有终点,没有彼岸,坚持就好,愿岁月如初

posted @ 2021-10-14 11:39  smallbore  阅读(1033)  评论(0编辑  收藏  举报
回顶部