# driver.js 學習筆記
###### tags: `111年` `學習` `driver.js` `111年實習自學`
## 簡介
driver.js是一個開源工具,主要目的是為了進行「聚焦」、「引導」。大多用在指引新進來網頁的使用者,讓他們可以step by step進行作業。
優點:
* 輕量簡單:只有約4KB大小
* 動畫流暢
* 用戶操作友好:可以使用鍵盤操作
* 幾乎支持所有瀏覽器
名詞小整理:
* stage:包住元素的東西
* overlay:讓空白處變暗的遮罩
* popover:旁邊彈出的解說小視窗
## 前情提要(?
在實習期間碰巧要使用driver.js,要放在公司已經做好的OAM上面,因為專案有點大,自己也沒完全弄懂。有碰到新套件的機會就寫一篇小筆記這樣。
## 安裝
使用npm安裝:
```shell
npm install driver.js --save
```
在後面加入 --save 就會直接放進package.json跟package-lock.json,不必再做其他事。
也可以使用CDN:
```html!
<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官方網站](https://kamranahmed.info/driver.js/)
[driver官方GitHub](https://github.com/kamranahmedse/driver.js)
### new Driver 常用部份
```javascript
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
```htmlmixed=
<!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<font color="red">()</font>;
driver.start<font color="red">()</font>;
driver.start<font color="red">()</font>;
忘記加括號的我在那糾結了半小時...
<br>
## 錯誤紀錄
### 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依舊無法點擊。
<br>
2. **直接從css改**
```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的背景遮罩給關掉。
```javascript
//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");
```
<br>
## 其他做法
### 延遲
```javascript
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也會有一樣的錯誤結果。
```javascript
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({ //省略 })```了!
<br>
## 參考資料
* https://kamranahmed.info/driver.js/
* https://github.com/kamranahmedse/driver.js
* https://zhuanlan.zhihu.com/p/544404499
* https://blog.csdn.net/weixin_43637720/article/details/114936155
* https://juejin.cn/post/6886242924687228942
* https://www.jianshu.com/p/9bf381344fce
<!-- {%hackmd BJrTq20hE %} -->