react頁面引導組件, 支持語音播報

頁面引導在用戶第一次訪問網站能過提供很好的提示, 下面介紹基於react寫的一個頁面引導的組件. 演示地址html

效果圖node

Guide組件的實現

能夠把<Guide/>設計成一個容器組件, 由於咱們不知道要引導的內容是什麼, 經過容器組件的this.props.children渲染內容react

class Guide extends Component {
    render () {
        return (
            <div className="guide-container" ref={e => this.guide = e}> {this.props.children} </div>
        )
    }
}
複製代碼

如何獲取哪些是要引導的dom? 能夠經過dom的自定義屬性, 再經過querySelectorAll獲取ios

// example
<Guide >
    <header data-step="1" data-tip='Welcome to use react-guide'>React Guide</header>
</Guide>
// 獲取要引導的dom
this.guide.querySelectorAll('[data-step]')
複製代碼

<Guide/>組件還須要有: 遮罩層、提示框、內容區、語音功能, 4個部分.git

遮罩層

遮罩層經過fixed佈局,加個透明度就行了, 經過外面傳來的visible控制顯示github

class Guide extends Component {
    render () {
        return (
            <div className="guide-container" ref={e => this.guide = e}> {this.props.children} {this.props.visible&&<div className="guide-shadow" ref={e => this.shadow = e}s.onClickShadow.bind(this)} key='guide-shadow'></div>} </div>
        )
    }
}
複製代碼

提示框

提示框應該再遮罩層之上, 它的z-index大於遮罩層的.提示框還要考慮頁面空餘空間,肯定擺放位置,以下圖的4個位置, 1, 4 位置放不下, 因此能夠放2, 3.npm

再添加上resize事件監聽, 在頁面縮放時,也能從新佈局axios

window.addEventListener('resize', this.onRezieWindow.bind(this), false)
複製代碼

內容區

首先肯定要顯示內容區的位置, 經過目標domoffsertLeftoffsetTopheightwidth, 獲取內容區的位置api

const nodeList = getListFromLike(this.guide.querySelectorAll('[data-step]'))  // 獲取全部要引導dom
nodeList.sort((a, b) => {
  return Number(a.getAttribute('data-step'))- Number(b.getAttribute('data-step'))
})  // 按照step的大小進行排序
let dots = nodeList.map(node => {
  let height = node.clientHeight || node.offsetHeight
  let width = node.clientWidth || node.offsetWidth
  return {
    left: node.offsetLeft, 
    top: node.offsetTop,
    height,
    width,
    tip: node.getAttribute('data-tip'),
    step: node.getAttribute('data-step'),
    fRight: node.offsetLeft + width,
    fBottom: node.offsetTop + height
  }
})
複製代碼

內容區也在遮罩層之上.激活content時只要給原dom添加上z-indexdom

node.style.setProperty('position', 'relative');
node.style.setProperty('z-index', '999996', 'important');
複製代碼

當頁面存在滾動條時, 還要頁面的滾動到要引導區域, 經過scrollTo(x, y)實現

window.scrollTo(dLeft - 100, dTop - 100)
複製代碼

語音功能

語音功能能夠用HTML5audio標籤

<audio ref={e => this.audio = e} src={this.state.audioUrl} type="audio/mpeg"></audio>}
複製代碼

再結合百度的ttsAPI

function text2Voice(tip, lan){
  let obj = {
    lan,
    ie: 'UTF-8',
    spd: '4',
    per: 4,
    text: tip  // tip就是dom上data-tip的屬性值
  }
  return 'http://tts.baidu.com/text2audio' + axiosObj(obj)
}
複製代碼

audio標籤的src指向text2Voice(tip, lan)的結果

經過audioapi控制中止、播放

this.audio.autoplay = true // 自動播放
this.audio.pause()  // 暫停
this.audio.addEventListener('timeupdate', () => {
    ...  // 監聽何時結束
}, false)
複製代碼

說明

源碼及api➡️github, 歡迎star,感謝.

安裝

能夠經過npm安裝

$ npm install react-guide
複製代碼

API

下面是react-guideapi

Property Description Type Default
visible Whether the guide is visible or not boolean false
audio Whether a voice reads of tip of the guide or not boolean true
lan The voice of language, 'en' or 'zh' string en
bullet Whether bullets (.) button is visible on middle of the guide or not boolean false
num Whether num icon is visible on top left of the guide or not boolean false
onCancel Specify a function that will be called when a user clicks shadow, skip button on bottom left function(e) -
onOk Specify a function that will be called when all steps have done and click the done button function(e) -
data-step Number of steps for guides, only use in dom string -
data-tip Every step you want to show tip, only use in dom string -

例子

一個例子

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Guide from 'react-guide'
class App extends Component {
  constructor () {
    super()
    this.state = {
      visible: false
    }
  }
  handleStart() {
    this.setState({
      visible: true
    })
  }
  handleCancel() {
    this.setState({
      visible: false
    })
  }
  render() {
    return (
      <div> <Guide visible={this.state.visible} onCancel={this.handleCancel.bind(this)} > <h1 data-step="1" data-tip='Hello World'>Step1</h1> <div data-step="3" data-tip='Welcome to use react-guide'>Step3</div> <h4 data-step="2" data-tip='react-guide is very easy' >Step2</h4> <div><span data-step="4" data-tip='Let start'>Step4</span></div> </Guide> <button onClick={this.handleStart.bind(this)}>start</button> </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root')); 複製代碼
相關文章
相關標籤/搜索