页面分步引导组件Driver.js

Driver.js是一款轻量级且功能丰富的JavaScript引擎,用于创建页面元素的分步引导介绍和高亮显示,支持所有主流浏览器。通过简单的API,即可实现元素高亮、弹出框和分步引导介绍等功能。

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

Driver.js是一个轻量级(约4kb gzip),并且无任何依赖,但功能强大的JavaScript引擎。Driver.js可以提高用户对页面的关注度,,也可以创建强大的分步引导介绍功能,号召性用语组件,焦点移位器等。更重要的是Driver.js支持所有的主流浏览器。

1、Driver.js安装,可以使用script标签引入,也可以使用npm安装,import引入。
a、在html文件中用script标签引入driver.min.css文件和driver.min.js文件

 <script src="/dist/driver.min.js"></script>

b、使用npm install driver.js,然后在文件中import导入。这样就可以很好的和Vue结合一起使用了。

npm install driver.js
import Driver from 'driver.js';
import 'driver.js/dist/driver.min.css';

2、Driver.js基本用法。
a、单个节点高亮显示

const driver = new Driver();
driver.highlight('#element');

b、高亮和弹出框

const driver = new Driver();
driver.highlight({
element: '#element',
popover: {
title: '弹窗标题',//也可以使用HTML标签
description: '弹窗内容',//也可以使用HTML标签
position: 'bottom',//位置,可选值: left, left-center, left-bottom, top, top-center, top-right, right, right-center, right-bottom, bottom, bottom-center, bottom-right, mid-center
offset: 20,//位移大小
}
});

c、设置分步引导介绍功能

const driver = new Driver();
// 设置介绍的步骤
driver.defineSteps([
{
element: '#first-element-introduction',
popover: {
className: 'first-step-popover-class',
title: 'Title on Popover',
description: 'Body of the popover',
position: 'left'
}
},
{
element: '#second-element-introduction',
popover: {
title: 'Title on Popover',
description: 'Body of the popover',
position: 'top'
}
},
{
element: '#third-element-introduction',
popover: {
title: 'Title on Popover',
description: 'Body of the popover',
position: 'right'
}
},
]);
// 开始分步引导介绍
driver.start();

以上是雷雪松对Driver.js的讲解。是不是很简单,很炫酷?赶紧用起来吧,让你的用户在使用你的产品时,更快更好的上手吧!

执行下面语句后,设备操作到启动应用后,到点击同意文本元素后报错,执行语句如下: class Super_Douyin_0001: name = '抖音录制短视频-Super_Douyin_0001' def setup(self): package = "com.ss.android.ugc.aweme" activity = "com.ss.android.ugc.aweme.splash.SplashActivity" self.super = SuperappUtils(package, activity) self.driver = self.super.driver self.super.gohome() self.super.activate_app() def teststeps(self): STEP(1, '抖音录制短视频') self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, f'new UiSelector().text("同意")').click() 报错信息如下: [HTTP] --> POST /wd/hub/session/1b13b4e2-f956-4b99-97fa-7ecea17e57cd/element [HTTP] {"using":"-android uiautomator","value":"new UiSelector().text(\"同意\")"} [W3C (1b13b4e2)] Calling AppiumDriver.findElement() with args: ["-android uiautomator","new UiSelector().text(\"同意\")","1b13b4e2-f956-4b99-97fa-7ecea17e57cd"] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, css selector, -android uiautomator [BaseDriver] Waiting up to 0 ms for condition [WD Proxy] Matched '/element' to command name 'findElement' [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8202/wd/hub/session/c2419d85-af4b-4231-87c8-b1c10d2c0c85/element] with body: {"strategy":"-android uiautomator","selector":"new UiSelector().text(\"同意\")","context":"","multiple":false} [WD Proxy] socket hang up [W3C (1b13b4e2)] Encountered internal error running command: UnknownError: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to the remote server. Original error: socket hang up [W3C (1b13b4e2)] at UIA2Proxy.command (C:\Program Files\Appium\resources\app\node_modules\appium\node_modules\appium-base-driver\lib\jsonwp-proxy\proxy.js:274:13) [W3C (1b13b4e2)] at runMicrotasks () [W3C (1b13b4e2)] at processTicksAndRejections (internal/process/task_queues.js:85:5) [HTTP] <-- POST /wd/hub/session/1b13b4e2-f956-4b99-97fa-7ecea17e57cd/element 500 34 ms - 669
最新发布
07-23
import { _decorator, Component, Node, director, resources, instantiate, Vec3, math } from 'cc'; import { GameData } from './GameData'; import { A_guagouyidong } from './A_guagouyidong'; import { B_pengzhuangDefenxitong } from './B_pengzhuangDefenxitong'; import { ditu } from './C_ditu'; import { A_HUAHUAweizhi } from './A_HUAHUAweizhi'; import { zizhuandaishangwawa2 } from './zizhuandaishangwawa2'; import { fuhuoUI } from './fuhuoUI'; import { GameOverUI } from './GameOverUI'; const { ccclass, property } = _decorator; @ccclass('AA_GameManager') export class GameManager extends Component { @property(Node) clawNode: Node = null; // 爪子节点 @property(Node) collisionSystemNode: Node = null; // 碰撞系统节点 @property(Node) mapNode: Node = null; // 地图节点 @property(Node) flowerSpawnerNode: Node = null; // 花朵生成器节点 @property(Node) rotationComponentNode: Node = null; // 旋转组件节点 @property(Node) cameraFollowNode: Node = null; // 相机跟随节点 @property(Node) reviveUINode: Node = null; // 复活UI节点 @property(Node) gameOverUINode: Node = null; // 游戏结束UI节点 private isGameActive: boolean = false; private currentLevel: number = 1; onLoad() { this.initializeGame(); } /** * 初始化游戏 */ private initializeGame() { // 重置游戏数据 GameData.reset(); // 获取或初始化组件 if (!this.clawNode) this.clawNode = this.node.getChildByName('Claw'); if (!this.collisionSystemNode) this.collisionSystemNode = this.node.getChildByName('CollisionSystem'); if (!this.mapNode) this.mapNode = this.node.getChildByName('Map'); if (!this.flowerSpawnerNode) this.flowerSpawnerNode = this.node.getChildByName('FlowerSpawner'); if (!this.rotationComponentNode) this.rotationComponentNode = this.node.getChildByName('RotationComponent'); if (!this.cameraFollowNode) this.cameraFollowNode = this.node.getChildByName('CameraFollow'); if (!this.reviveUINode) this.reviveUINode = this.node.getChildByName('ReviveUI'); if (!this.gameOverUINode) this.gameOverUINode = this.node.getChildByName('GameOverUI'); // 初始化游戏状态 this.isGameActive = true; } /** * 开始游戏 */ public startGame() { if (!this.isGameActive) { this.isGameActive = true; // 重置所有游戏组件 this.resetGameComponents(); // 初始化UI if (this.reviveUINode) { const reviveUI = this.reviveUINode.getComponent(fuhuoUI); if (reviveUI) reviveUI.hide(); } if (this.gameOverUINode) { const gameOverUI = this.gameOverUINode.getComponent(GameOverUI); if (gameOverUI) gameOverUI.hide(); } // 开始游戏循环 this.scheduleOnce(() => { this.enableGameComponents(true); }, 0.1); } } /** * 重置游戏 */ public resetGame() { this.isGameActive = false; this.resetGameComponents(); GameData.reset(); // 延迟一点时间确保所有销毁操作完成 this.scheduleOnce(() => { this.startGame(); }, 0.2); } /** * 重置游戏组件 */ private resetGameComponents() { // 重置爪子 if (this.clawNode) { const clawMovement = this.clawNode.getComponent(A_guagouyidong); if (clawMovement) { clawMovement.stopMovement(); clawMovement.isFirstClick = true; } } // 重置碰撞系统 if (this.collisionSystemNode) { const collisionSystem = this.collisionSystemNode.getComponent(B_pengzhuangDefenxitong); if (collisionSystem) { collisionSystem.stopAllMovements(); } } // 重置地图 if (this.mapNode) { const mapComponent = this.mapNode.getComponent(ditu); if (mapComponent) { mapComponent.generateMap(); } } // 重置花朵生成器 if (this.flowerSpawnerNode) { const flowerSpawner = this.flowerSpawnerNode.getComponent(A_HUAHUAweizhi); if (flowerSpawner) { flowerSpawner.showFlowers(); } } // 重置旋转组件 if (this.rotationComponentNode) { const rotationComponent = this.rotationComponentNode.getComponent(zizhuandaishangwawa2); if (rotationComponent && rotationComponent.enabled) { rotationComponent.enabled = false; this.scheduleOnce(() => { rotationComponent.enabled = true; }, 0.2); } } } /** * 启用或禁用游戏组件 * @param enable 是否启用 */ private enableGameComponents(enable: boolean) { // 启用/禁用爪子移动 if (this.clawNode) { const clawMovement = this.clawNode.getComponent(A_guagouyidong); if (clawMovement) { if (enable) { clawMovement.resumeMovement(); } else { clawMovement.stopMovement(); } } } // 启用/禁用旋转组件 if (this.rotationComponentNode) { const rotationComponent = this.rotationComponentNode.getComponent(zizhuandaishangwawa2); if (rotationComponent) { rotationComponent.enabled = enable; } } // 启用/禁用碰撞系统 if (this.collisionSystemNode) { const collisionSystem = this.collisionSystemNode.getComponent(B_pengzhuangDefenxitong); if (collisionSystem) { // 碰撞系统本身会根据游戏状态处理 } } } /** * 游戏结束 * @param isSuccess 是否成功 */ public gameOver(isSuccess: boolean) { this.isGameActive = false; this.enableGameComponents(false); // 显示游戏结束UI if (this.gameOverUINode) { const gameOverUI = this.gameOverUINode.getComponent(GameOverUI); if (gameOverUI) { gameOverUI.show(GameData.getScore()); } } } /** * 返回主页 */ public goToHome() { // 这里可以添加返回主页的逻辑 // 例如加载主页场景 director.loadScene('HomeScene'); } /** * 下一关 */ public nextLevel() { this.currentLevel++; // 这里可以添加加载下一关的逻辑 // 例如重新初始化游戏或加载新场景 this.resetGame(); } /** * 暂停游戏 */ public pauseGame() { if (this.isGameActive) { this.isGameActive = false; this.enableGameComponents(false); } } /** * 恢复游戏 */ public resumeGame() { if (!this.isGameActive) { this.isGameActive = true; this.enableGameComponents(true); } } }。import { _decorator, Button, Component, director, resources } from 'cc'; import { GameManager } from './AA_GameManager'; const { ccclass, property } = _decorator; @ccclass('F_fanhuizhuye') export class F_fanhuizhuye extends Component { @property(GameManager) gameManager: GameManager = null; // 绑定 GameManager 节点 onLoad() { // 获取按钮组件并绑定点击事件 const button = this.node.getComponent(Button); if (button) { button.node.on(Button.EventType.CLICK, this.onClick, this); } } private onClick() { if (this.gameManager) { // 重置游戏 this.gameManager.resetGame(); } // 加载主页场景 director.loadScene('kaishiUI'); } onDestroy() { // 移除事件监听 const button = this.node.getComponent(Button); if (button) { button.node.off(Button.EventType.CLICK, this.onClick, this); } } } 。添加返回主页功能后,控制台出现 [PreviewInEditor] Cannot read property 'off' of null和 [Scene] Failed to set an indexed property on 'GamepadList': Indexed property setter is not supported.的错误,同时编辑器预览可以正常运行,返回主页后再正常进入游戏没问题(虽然控制台还是出现上面的两个错误提示),但是当用游览器预览和扫一扫二维码预览时,每单点击这个返回主页按钮就会出现错误了,出现这 [Browser Preview]Cannot read properties of null (reading 'off')/nTypeError: Cannot read properties of null (reading 'off')的错误,请问哪里出问题了,哪里需要修改。 [PreviewInEditor] Cannot read property 'off' of null TypeError: Cannot read property 'off' of null at huohuianniu.onDestroy (file:///C:/Users/Yao~~Yao/jiawawa/temp/programming/packer-driver/targets/editor/chunks/76/7658393ce2997f59351556cdfc5d77c033e6eac4.js:131:25) at eval (eval at tryCatchFunctor_EDITOR (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js), <anonymous>:4:10) at NodeActivator.eval (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:53508:42) at huohuianniu._onPreDestroy (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:51932:44) at huohuianniu._destroyImmediate (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:155559:119) at Node._onPreDestroyBase (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:57820:22) at Node.eval (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:53596:38) at Node._destroyImmediate (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:155559:119) at Node._onPreDestroyBase (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:57811:25) at Node.eval (C:\ProgramData\cocos\editors\Creator\3.8.1\resources\resources\3d\engine\bin\.cache\dev\editor\bundled\index.js:53596:38)显示的错误时这些
06-12
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值