關於標題彈出指令

MasterPoser發表於2020-10-19

簡介

寫這個目的是便於自己整理知識點, 首先我本來就對js瞭解不多,看到這部分讓我很難受。 這人一看到從上到下一個都不認識的東西就很不想看這個,雖然教程說五遍大法,但是敲過去都不知道這步是幹嘛的,說實話這部分我手看了一波勸退了一波,今天不知道是學習慾望來了還是什麼,竟然非常有耐心的看下去了。廢話就不多少了,寫這部分就是想吐槽下(難受這竟然才是基礎教程!!!!)

開始對於程式碼刨析

首先我先貼一個完整的程式碼(看看就行別被勸退!)

/* jshint esversion: 6 */
// 在 el 元素的上方顯示或隱藏一個內容為 title 的提示框
function showTitle(el, title) {
    const popover = getPopover();
    const popoverStyle = popover.style;


    if (title === undefined) {
        popoverStyle.display = 'none';
    } else {
        const elRect = el.getBoundingClientRect();
        const elComputedStyle = window.getComputedStyle(el, null);
        const rightOffset = parseInt(elComputedStyle.getPropertyValue('padding-right')) || 0;
        const topOffset = parseInt(elComputedStyle.getPropertyValue('padding-top')) || 0;

        popoverStyle.visibility = 'hidden';
        popoverStyle.display = 'block';
        popover.querySelector('.popover-content').textContent = title;
        popoverStyle.left = elRect.left - popover.offsetWidth / 2 + (el.offsetWidth - rightOffset) / 2 + 'px';
        popoverStyle.top = elRect.top - popover.offsetHeight + topOffset + 'px';
        popoverStyle.display = 'block';
        popoverStyle.visibility = 'visible';
    }
}
// 建立或者返回一個提示框
function getPopover() {
    let popover = document.querySelector('.title-popover');

    if (!popover) {
        const tpl = `
      <div class="popover title-popover top fade in" style="position:fixed;">
        <div class="arrow"></div>
        <div class="popover-content"></div>
      </div>
    `;
        const fragment = document.createRange().createContextualFragment(tpl);
        document.body.appendChild(fragment);
        popover = document.querySelector('.title-popover');
    }

    return popover;
}

export default {
    bind(el, binding, vnode) {
        // 使用 const 宣告一個只讀的常量,其值是需要監聽的事件型別列表
        const events = ['mouseenter', 'mouseleave', 'click'];
        // 宣告一個處理器,以根據不同的事件型別傳不同的引數
        const handler = (event) => {
            if (event.type === 'mouseenter') {
                // 顯示一個提示框
                showTitle(el, binding.value);
            } else {
                // 隱藏一個提示框
                showTitle();
            }
        }
        // 在 el 元素上新增事件監聽
        events.forEach((event) => {
            el.addEventListener(event, handler, false);
        })
        // 在 el 元素上新增一個屬性,以在其他鉤子進行訪問
        el.destroy = () => {
            // 移除 el 元素上的事件監聽
            events.forEach((event) => {
                el.removeEventListener(event, handler, false);
            })
            // 移除 el 元素上的 destroy
            el.destroy = null;
        }
    },
    unbind(el) {
        // 移除事件監聽和資料繫結
        el.destroy();
    }
}

看到這裡先不要慌(反正我是從上到下除了漢字其他都不認識)

看到這裡首先要理解一下觀看順序(為了方便理解,我對下面程式碼做了一點簡略處理)

export default {
    bind(el, binding, vnode) {
    // bind:只呼叫一次,指令第一次繫結到元素時呼叫,在這裡可以進行一次性的初始化設定
    //先忽略部分具體邏輯
}
  },
  unbind(el){
        el.destroy();//下面詳細介紹
  }
};

destroy方法

首先我要說下destroy()方法 這個是自己定義的
引用大佬原話

el是啥,又不是vnode,怎麼會有 destroy這個方法 el只是一個dom,dom不是vue元件,它是原生的dom節點
—pigzzz

具體邏輯如下

el.destroy = () => {
    // 移除 el 元素上的事件監聽
      events.forEach((event) => {
        el.removeEventListener(event, handler, false)
    })
    // 移除 el 元素上的 destroy  
    el.destroy = null

forEach()這裡就不用在講解了這只是一個簡單的資料遍歷中的陣列event

 // 使用 const 宣告一個只讀的常量,其值是需要監聽的事件型別列表
        const events = ['mouseenter', 'mouseleave', 'click']
        //事件型別分別是 
        //mouseenter:當滑鼠指標進入(穿過)元素時觸發
        //mouseleave : 滑鼠指標離開時觸發
        //click : 點選時觸發

[removeEventListener() 不知道這個方法的戳一下!!!!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章