react页面引导组件, 支持语音播报

本文介绍了如何实现一个React页面引导组件,包括遮罩层、提示框、内容区和语音功能。组件通过DOM自定义属性获取引导内容,支持在页面缩放时重新布局,并集成了语音播报功能,使用`<audio>`标签结合百度语音API,提供良好的用户体验。同时,提供了安装、API和使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

页面引导在用户第一次访问网站能过提供很好的提示, 下面介绍基于react写的一个页面引导的组件. 演示地址

效果图

Guide组件的实现

可以把<Guide/>设计成一个容器组件, 因为我们不知道要引导的内容是什么, 通过容器组件的this.props.children渲染内容

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

如何获取哪些是要引导的dom? 可以通过dom的自定义属性, 再通过querySelectorAll获取

// 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个部分.

遮罩层

遮罩层通过fixed布局,加个透明度就好了, 通过外面传来的visible控制显示

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.

再添加上resize事件监听, 在页面缩放时,也能重新布局

window.addEventListener('resize', this.onRezieWindow.bind(this), false)
复制代码

内容区

首先确定要显示内容区的位置, 通过目标domoffsertLeftoffsetTopheightwidth, 获取内容区的位置

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-index

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

PropertyDescriptionTypeDefault
visibleWhether the guide is visible or notbooleanfalse
audioWhether a voice reads of tip of the guide or notbooleantrue
lanThe voice of language, 'en' or 'zh'stringen
bulletWhether bullets (.) button is visible on middle of the guide or notbooleanfalse
numWhether num icon is visible on top left of the guide or notbooleanfalse
onCancelSpecify a function that will be called when a user clicks shadow, skip button on bottom leftfunction(e)-
onOkSpecify a function that will be called when all steps have done and click the done buttonfunction(e)-
data-stepNumber of steps for guides, only use in domstring-
data-tipEvery step you want to show tip, only use in domstring-

例子

一个例子

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'));
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值