Try   HackMD

driver.js 學習筆記

tags: 111年 學習 driver.js 111年實習自學

簡介

driver.js是一個開源工具,主要目的是為了進行「聚焦」、「引導」。大多用在指引新進來網頁的使用者,讓他們可以step by step進行作業。

優點:

  • 輕量簡單:只有約4KB大小
  • 動畫流暢
  • 用戶操作友好:可以使用鍵盤操作
  • 幾乎支持所有瀏覽器

名詞小整理:

  • stage:包住元素的東西
  • overlay:讓空白處變暗的遮罩
  • popover:旁邊彈出的解說小視窗

前情提要(?

在實習期間碰巧要使用driver.js,要放在公司已經做好的OAM上面,因為專案有點大,自己也沒完全弄懂。有碰到新套件的機會就寫一篇小筆記這樣。

安裝

使用npm安裝:

npm install driver.js --save

在後面加入 save 就會直接放進package.json跟package-lock.json,不必再做其他事。

也可以使用CDN:

<script src="https://unpkg.com/driver.js/dist/driver.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/driver.js/dist/driver.min.css">

使用

driver官方網站
driver官方GitHub

new Driver 常用部份

const driver = new Driver({
    className: 'class-name',  //要用的class
    animate: true,  //動畫
    opacity: 0.75,  //後面空白處不透明度(0表示只彈出不會覆蓋)
    padding: 10, 
    stageBackground: '#ffffff',  //覆蓋突出元素的顏色
    allowClose: true,  //點擊空白處是否關閉
    overlayClickNext: false,  //點擊空白處是否移至下一步
    showButtons: false,  //是否顯示控制按鈕
    keyboardControl: true,  //是否允許鍵盤控制(esc關閉,箭頭鍵移動)
    
    //按鈕文本
    prevBtnText: "prev",  //上一步按鈕
    nextBtnText: "next",  //下一步按鈕
    doneBtnText: "done",  //最後一步的完成按鈕
    closeBtnText: "Close",  //關閉按鈕
    
    //事件(Event)
    onHighlightStarted: Element => {},  //在元素即將顯示時調用
    onHighlighted: Element => {},  //在元素完全顯示時調用
    onDeselected: Element => {},  //在取消選擇元素時調用
    onReset: Element => {},  //全部清除時調用
    onNext: Element => {},  //在轉到下一步時調用
    onPrevious: Element => {},  //在轉到上一步時調用
})

這些可以放在 new Driver 中,也可以放在跟element、popover同一層的地方。
需要注意的是,單個highlight跟步驟能取用的事件並不相同。

小DEMO

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>driver.js DEMO</title> <!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- driver.js --> <script src="https://unpkg.com/driver.js/dist/driver.min.js"></script> <link rel="stylesheet" href="https://unpkg.com/driver.js/dist/driver.min.css"> </head> <body> <script> function theDriver(){ const driver = new Driver({ prevBtnText: "prev", nextBtnText: "next", doneBtnText: "Done", closeBtnText: "close", allowClose: false, animate: true, opacity: 0.75, }); const steps = [ { element: "#first-driver-step", popover:{ title: "TITLE", description: "第一步", position: "bottom" } }, { element: "#second-driver-step", popover:{ title: "TITLE", description: "第二步", position: "right" } }, { element: "#third-driver-step", popover:{ title: "TITLE", description: "第三步", position: "bottom" } }, ]; driver.defineSteps(steps); driver.start(); } </script> <div id="first-driver-step" style="width: 200px; height: 100px; background-color: red">123</div> <div id="second-driver-step" style="width: 300px; height: 50px; background-color: blue">456</div> <div id="third-driver-step" style="width: 100px; height: 100px; background-color: yellow">789</div> <button onclick="theDriver()">再一次導覽</button> <script> $(document).ready(function() { theDriver(); }) </script> </body> </html>

記得!
driver.start();
driver.start();
driver.start();

忘記加括號的我在那糾結了半小時

錯誤紀錄

V There are no steps defined to iterate

代表抓不到id,要去檢查看看是不是id打錯字或是忘記放上來。

V 下一步會展開Menu,但stage沒有跟著展開

如下面「其他作法」中的「延遲」,讓它有一點時間展開再抓element。

V 跳轉頁面後overlay沒有展開

跳轉頁面後的頁面呼叫driver時進行setTimeout()延遲。延遲多久要自己試。

V stage覆蓋在element上面,且element無法點擊

google之後有查到不少GitHub問題,很多人都有遇到,套件作者似乎也沒有提出解決方法。

  1. animate: false
    這是最多人提到的方式,也是套件作者自己提過的。
    但是從開發者工具(F12)可以發現,事實上,只是overlay的<div>消失,z-index莫名失效的問題其實還是沒有修正,因此理所當然的element依舊無法點擊。

  2. 直接從css改
    ​​​​#driver-page-overlay{
    ​​​​    display: none;  /* 關掉overlay(遮罩) */
    ​​​​    /* 如果只是從new Driver那邊把opacity調成0,不把display調none,就會讓元素變得無法點擊。 */
    ​​​​}
    ​​​​#driver-highlighted-element-stage{
    ​​​​    background: transparent !important;  /* stage highlight的部份透明,就可以看見element了 */
    ​​​​    outline: 5000px solid rgba(0, 0, 0, .75);  /* 不要用overlay,而是用「邊框」做出遮罩效果取代*/
    ​​​​    pointer-events: none;  /* 使得在最上層的stage可以穿透 */
    ​​​​}
    
    我是在使用v-modal出現問題,因而發現driver.js會跟v-modal打架,driver.js會把彈出視窗整個拉到下層,連v-modal自己的遮罩都能蓋過v-modal,因此還會需要把v-modal的背景遮罩給關掉。
    ​​​​//onHighlighted裡面
    ​​​​document.getElementById("create_modal___BV_modal_outer_").style.setProperty("z-index", "auto", "important");
    ​​​​document.getElementById("create_modal___BV_modal_backdrop_").style.setProperty("display", "none", "important");
    
    ​​​​//最後一步的onNext裡面
    ​​​​//把遮罩用回來
    ​​​​document.getElementById("create_modal___BV_modal_backdrop_").style.setProperty("display", "block", "important");
    

其他做法

延遲

const driver = new Driver({
    //省略
})

const steps = [
    {
        element: "#first-driver-step",
        popover:{
            title: "TITLE",
            description: "...",
            position: "top"
        },
        onNext: () => {
            driver.preventMove();  //先讓下一步的動作停止
            
            //設定時間,在0.1秒跑完後再去往下一步
            setTimeout(() => {
                driver.moveNext();
            }, 100);
        }
    },
     //下述省略
];

driver.defineSteps(steps);
driver.start();

Vue

要放入driver.js,需要先確認是否在client(客戶)端進行,否則import或require都會導致500(TimerunError),或者Windows is not defined,即使直接在vue檔裡面import也會有一樣的錯誤結果。

var Driver = null;
if(process.client){
  require('driver.js/dist/driver.min.css');
  Driver = require('driver.js');
}

之後再做像是Vue.prototype.$Driver = Driver;這類動作。

接下來就可以在Vue檔裡面const driver = new this.$Driver({ //省略 })了!


參考資料