JavaScript中使用Shepherd构建用户导览的方法
无论我们尝试使 Web 应用程序多么简单,引导新用户完成第一次体验通常都是有帮助的。视觉游览可能是最简单的方法。
如果您关注过我的 Envato Tuts+ 使用 PHP 创建您的初创公司系列,那么您就会熟悉会议规划器。在观察用户安排第一次会议后,我决定最好构建某种指南。
起初,我考虑自己构建它,但后来我找到了一个开源选项,Shepherd。
在今天的教程中,我将向您介绍如何使用 Shepherd 构建可视化用户之旅。使用 Shepherd 相对简单,我将回顾一些我自己用来简化创作过程的代码。
Shepherd 是 HubSpot(一项入站营销服务)的开源产品。感谢他们提供了一个强大的库和良好的文档。
Shepherd 的工作原理
让我们看一下 Shepherd 的一个简单场景。
使用 Shepherd 将基本浏览集成到您的应用程序中非常简单。首先,您选择一个主题文件并集成其 JavaScript,如下所示:
登录后复制
您可以从 Shepherd GitHub 页面下载文件。我使用上面的 shepherd-theme-arrows.css
,但您可以从下面的任何默认值中进行选择并自定义它们:
接下来,您创建一个游览对象:
const tour = new Shepherd.Tour({
defaultStepOptions: {
classes: ‘shepherd-theme-arrows’,
scrollTo: true
}
});
登录后复制
使用 defaultStepOptions
键创建游览时,可以为所有步骤定义默认值。 classes
指的是您使用的主题定义,例如shepherd-theme-arrows
和 scrollTo
有助于在 scrollIntoView()
方法的帮助下确保所有步骤都出现在可见视口中。
然后,您可以向游览添加单独的步骤:
tour.addStep(‘example-step’, {
text: ‘This step is attached to the bottom of the .
element.’,
example-css-selector
attachTo: { element: ‘.example-css-selector’, on: ‘bottom’},
classes: ‘example-step-extra-class’,
buttons: [
{
text: ‘Next’,
action: tour.next
}
]
});
登录后复制
text
是出现在视觉之旅正文中的内容。文本可以是常规 HTML 字符串,也可以是 HTMLElement
对象。您还可以在此处提供一个回调函数,该函数将在构建步骤时执行。但是,它必须返回 HTML 字符串或 HTMLElement
对象。
attachTo
关键点指向要附加此步骤的项目的 CSS 选择器。它期望一个对象作为其值。
buttons
键允许您定义一个或多个按钮及其操作,例如。 Next
.该键接受按钮对象数组作为其值。按钮对象将具有控制按钮行为和外观的键值对。
最后,您开始游览:
tour.start();
登录后复制
Shepherd 构建于 Tether(另一个 HubSpot 开源产品)之上,它有助于将元素定位到页面上的其他元素。 Tether 确保您的步数不会溢出屏幕或被裁剪。
将 Tether 集成到您自己的应用程序中
当我开始尝试 Shepherd 时,我很快发现编写包含许多步骤的指南可能会相当冗长。这是我在自己的实现中解决的问题。
我不想使用大量需要长期维护的 JavaScript 代码来编写游览。相反,我选择创建一个数组,并根据用户是在游览的开始还是结束时以编程方式自定义按钮。
例如,我创建一个 steps[]
数组并通过填充该数组来定义游览:
const tour = new Shepherd.Tour({
defaultStepOptions: {
classes: ‘shepherd-theme-arrows’,
scrollTo: true
}
});
const steps = [];
steps.push({
attachTo: {
element: ‘.nav-tabs’,
on: ‘top’
},
title: ‘Welcome’,
text: `Allow me to show you how to plan a ${title}.
If you prefer, you can turn off this guide.`
});
steps.push({
attachTo: {
element: ‘#headingWho’,
on: ‘top’
},
title: ‘Who would you like to invite?’,
text: `You can add one person or a group of people to your ${title}.
Click the person button to add participants.
`
});
steps.push({
attachTo: {
element: ‘#invitation-url’,
on: ‘bottom’
},
title: ‘Inviting by email’,
text: ‘Alternately, you can email the meeting link to your participant(s)’
});
steps.push({
attachTo: {
element: ‘#headingWhat’,
on: ‘bottom’
},
title: ‘What is your meeting about?’,
text: `You can customize the subject of your ${title}. We’ll use it for the invitation and reminder emails.
Click the pencil button to edit the subject.
`
});
if ($(‘#headingActivity’).length > 0) {
steps.push({
attachTo: {
element: ‘#headingActivity’,
on: ‘top’
},
title: ‘What do you want to do?’,
text: ‘You can suggest one or more activity ideas. With multiple ideas, your participants can help you select their favorite.
Click the plus button to suggest activities.
‘
});
}
steps.push({
attachTo: {
element: ‘#headingWhen’,
on: ‘top’
},
title: ‘When do you want to meet?’,
text: `Suggest one or more dates and times for your ${title}. With more than one, your participants can help you choose.
Click the + button to add them.
`
});
steps.push({
attachTo: {
element: ‘#headingWhere’,
on: ‘top’
},
title: ‘Where do you want to meet?’,
text: `Suggest one or more places for your ${title}. With multiple places, your participants can help you choose.
We use Google Places to simplify adding them. Click the + button to begin.
`
});
steps.push({
attachTo: {
element: ‘.virtualThing’,
on: ‘top’
},
title: ‘Is this a virtual meeting?’,
text: `Switch between in person and virtual ${title}s such as phone calls or online conferences.`
});
steps.push({
attachTo: {
element: ‘#actionSend’,
on: ‘top’
},
title: ‘Sending invitations’,
text: `Scheduling is collaborative. After you add times and places, you can Invite participants to select their favorites. A place isn’t necessary for virtual ${title}s.`
});
steps.push({
attachTo: {
element: ‘#actionFinalize’,
on: ‘right’
},
title: ‘Finalizing the plan’,
text: `Once you choose a time and place, you can Complete the plan. We’ll email the invitations and setup reminders.`
});
steps.push({
attachTo: {
element: ‘#tourDiscussion’,
on: ‘left’
},
title: ‘Share messages with participants’,
text: ‘You can write back and forth with participants on the Messages tab.
Messages are delivered via email.
‘
});
steps.push({
attachTo: {
element: ‘.container’,
on: ‘top’
},
title: ‘Ask a question’,
text: `Need help? Ask a question and we’ll respond as quickly as we can.
If you prefer, you can turn off the guide in settings.
`
});
登录后复制
我添加到数组中的每个对象元素都包含三个关键信息:
{element: '.nav-tabs', on:'top'}
title
键中标题的文本,例如'你想什么时候见面?'
text
键对我来说,维护这个数组比为教程的每个步骤定义按钮要简单得多。但是,这意味着我在将步骤加载到游览中时需要以编程方式定义按钮。
我编写此代码是为了正确添加和响应游览按钮。每一步,它都会创建一个 buttons
数组,否则我必须手动定义该数组:
for (let i = 0; i 0) {
buttons.push({
text: ‘Back’,
classes: ‘shepherd-button-secondary’,
action: function() {
return tour.back();
}
});
}
// no next button on last step
if (i!=(steps.length-1)) {
buttons.push({
text: ‘Next’,
classes: ‘shepherd-button-primary’,
action: function() {
return tour.next();
}
});
} else {
buttons.push({
text: ‘Close’,
classes: ‘shepherd-button-primary’,
action: function() {
return tour.hide();
}
});
}
登录后复制
例如,第一步没有后退按钮,最后一步没有下一步按钮。但最后一步确实有一个关闭按钮。
然后,我的数组中的每个步骤和每个按钮数组都会添加到游览中。
tour.addStep(`step_${i}`, {
text: steps[i].text,
title: steps[i].title,
attachTo: steps[i].attachTo,
classes: ‘shepherd shepherd-open shepherd-theme-arrows shepherd-transparent-text’,
buttons: buttons,
});
}
登录后复制
使用这种方法,我不必为教程的每个步骤重复重新定义相同的按钮。它还提供了一些编程能力,可以为未来动态定制游览。
使用我选择的 PHP 编程框架 Yii,我将必要的包含文件添加到我的资源文件中。这会加载到需要游览的特定页面上。就我而言,会议安排页面:
推荐阅读
-
在Python中,将K添加到列元组列表中的最小元素
处理数据集涉及识别特定列中的最小值并通过添加常量值(K)来更新它。通过实施优化的解决方案,我们可以有效地执行此操作,这对于数据...
-
使用switch case语句编写的C程序,用于计算几何图形的面积
#includevoidmain(){intfig_code;floatside,base,length,...
-
如何使 C# 代码可重用?
要在C#中使代码可重用,请使用接口。接口定义属性、方法和事件,这些成员是接口的成员。接口只包含成员的声明。派生类负责定义成员。这通...
-
C# 中的覆盖和隐藏有什么区别?
方法隐藏在C#中也称为隐藏。父类的方法可供子类使用,无需在遮蔽中使用override关键字。子类有其自己版本的相同函数。在...
-
在Java中使用示例双倍longValue()函数
Java是一种强大的面向对象语言,可以对各种数据类型进行高度的控制和精确度。其中一种功能是doublelongValue(),...
-
如何在Java中定义JSON字段名称的命名约定?
TheFieldNamingPolicycanbeusedtodefineafewstandardnaming...
-
Servlet中的HttpSession接口
在JavaWeb开发领域,了解HttpSession接口是创建动态和响应式Web应用程序的关键。在本文中,我们将探讨...
-
使用while循环查找自然数之和的Java程序
自然数之和可以使用编程语言中的不同迭代语句来计算。迭代语句是执行一组特定代码行直到循环语句中的条件失败的语句。在本文中,我们将讨论...
-
我们可以将Java数组转换为列表吗?
我们可以使用Arrays.asList()方法轻松地将Java数组转换为List。语法publicstaticLi...
-
Java中如何在不使用任何外部库的情况下读取网页内容?
TheURLclassofthejava.netpackagerepresentsaUniformResour...