接上级领导命令, 需要为开发的网站添加一个操作引导功能,让用户进入网站后可以大概了解如何操作.
实现该功能使用intro.js插件及asp.net core中组件(由于.net core中 @html.renderaction已经移除)来完成.
一. 首先是创建components
1. 在views/shared/components(没有请新建)目录下创建”IntroJs”目录
2. 创建ViewModel实体类
public class IntroJsViewModel
{
/// <summary>
/// 区域名
/// </summary>
public string Area { get; set; }
/// <summary>
/// 控制器名
/// </summary>
public string Controller { get; set; }
/// <summary>
/// 页面名
/// </summary>
public string Action { get; set; }
/// <summary>
/// 步骤列表
/// </summary>
public IntroStep[] Steps { get; set; }
}
public class IntroStep
{
/// <summary>
/// 唯一选择器
/// </summary>
public string Element { get; set; }
/// <summary>
/// 步骤序号 1 ,2 ,3 ,4
/// </summary>
public int Step { get; set; }
/// <summary>
/// 提示文本, 可以为html
/// </summary>
public string Intro { get; set; }
/// <summary>
/// 位置, left right top 可为空
/// </summary>
public string Position { get; set; }
}
{
/// <summary>
/// 区域名
/// </summary>
public string Area { get; set; }
/// <summary>
/// 控制器名
/// </summary>
public string Controller { get; set; }
/// <summary>
/// 页面名
/// </summary>
public string Action { get; set; }
/// <summary>
/// 步骤列表
/// </summary>
public IntroStep[] Steps { get; set; }
}
public class IntroStep
{
/// <summary>
/// 唯一选择器
/// </summary>
public string Element { get; set; }
/// <summary>
/// 步骤序号 1 ,2 ,3 ,4
/// </summary>
public int Step { get; set; }
/// <summary>
/// 提示文本, 可以为html
/// </summary>
public string Intro { get; set; }
/// <summary>
/// 位置, left right top 可为空
/// </summary>
public string Position { get; set; }
}
3. 创建ViewComponent类
public class IntroJsViewComponent: ViewComponent
{
public IntroJsViewComponent()
{
}
public IViewComponentResult Invoke()
{
var routes = RouteData.Routers[0];
var area = RouteData.Values["Area"] as string;
area = string.IsNullOrWhiteSpace(area) ? "" : area.ToLower();
var controller = RouteData.Values["Controller"].ToString().ToLower();
var action = RouteData.Values["Action"].ToString().ToLower();
StringBuilder sb = new StringBuilder();
string line = string.Empty;
string filepath = System.IO.Directory.GetCurrentDirectory() + "/IntroSettings.json";
if (File.Exists(filepath))
{
using (StreamReader sr = new StreamReader(filepath))
{
while ((line = sr.ReadLine()) != null)
{
sb.Append(line);
}
}
var stepList = JsonConvert.DeserializeObject<List<IntroJsViewModel>>(sb.ToString());
var step = stepList.FirstOrDefault(x =>
x.Area.ToLower() == area && x.Controller.ToLower() == controller && x.Action.ToLower() == action);
step = step == null ? new IntroJsViewModel{ Steps = new IntroStep[0]}: step;
return View(step);
}
return View(new IntroJsViewModel { Steps = new IntroStep[0] });
}
}
{
public IntroJsViewComponent()
{
}
public IViewComponentResult Invoke()
{
var routes = RouteData.Routers[0];
var area = RouteData.Values["Area"] as string;
area = string.IsNullOrWhiteSpace(area) ? "" : area.ToLower();
var controller = RouteData.Values["Controller"].ToString().ToLower();
var action = RouteData.Values["Action"].ToString().ToLower();
StringBuilder sb = new StringBuilder();
string line = string.Empty;
string filepath = System.IO.Directory.GetCurrentDirectory() + "/IntroSettings.json";
if (File.Exists(filepath))
{
using (StreamReader sr = new StreamReader(filepath))
{
while ((line = sr.ReadLine()) != null)
{
sb.Append(line);
}
}
var stepList = JsonConvert.DeserializeObject<List<IntroJsViewModel>>(sb.ToString());
var step = stepList.FirstOrDefault(x =>
x.Area.ToLower() == area && x.Controller.ToLower() == controller && x.Action.ToLower() == action);
step = step == null ? new IntroJsViewModel{ Steps = new IntroStep[0]}: step;
return View(step);
}
return View(new IntroJsViewModel { Steps = new IntroStep[0] });
}
}
4. 添加默认的Default.cshtml视图文件
文件代码如下:
@using WebProject.Views.Shared.Components.IntroJs
@model IntroJsViewModel
@{
}
<script type="text/javascript" src="~/Scripts/introjs/intro.min.js"></script>
<script>
var showIntro = true;
var steps = [];
$(function () {
@{
foreach (var item in Model.Steps)
{
<text>steps.push({ element: '@item.Element', intro: '@item.Intro', position: '@item.Position' });</text>
}
}
if (showIntro) {
introJs().setOptions({
prevLabel: "上一步",
nextLabel: "下一步",
skipLabel: "跳过",
doneLabel: "完成",
showProgress: true, //显示进度条
steps:steps
}).start();
}
});
</script>
@model IntroJsViewModel
@{
}
<script type="text/javascript" src="~/Scripts/introjs/intro.min.js"></script>
<script>
var showIntro = true;
var steps = [];
$(function () {
@{
foreach (var item in Model.Steps)
{
<text>steps.push({ element: '@item.Element', intro: '@item.Intro', position: '@item.Position' });</text>
}
}
if (showIntro) {
introJs().setOptions({
prevLabel: "上一步",
nextLabel: "下一步",
skipLabel: "跳过",
doneLabel: "完成",
showProgress: true, //显示进度条
steps:steps
}).start();
}
});
</script>
二. 在需要添加引导的页面引用该组件
一般在母版页底部进行引用.
@await Component.InvokeAsync("IntroJs")
三. 添加配置文件
在项目根目录添加”IntroSettings.json”配置文件
area和controller及action用来确定页面(可以多个)
steps节点下的element为该页面下的dom选择器,如ID等, 请务必保证唯一,否则将影响效果
step为该提示的步骤, 从数字1开始
intro为引导的文字说明
position为文字说明在该dom元素的哪个方向. left,right,top, bottom
[
{
"Area": "FormStat",
"Controller": "WKEntryYear",
"Action": "Index",
"Steps": [
{
"Element": "#divContent",
"Step": 1,
"Intro": "这里是头部......",
"Position": ""
},
{
"Element": "#btnSearch",
"Step": 2,
"Intro": "搜索内容 ",
"Position": ""
}
]
}
]
{
"Area": "FormStat",
"Controller": "WKEntryYear",
"Action": "Index",
"Steps": [
{
"Element": "#divContent",
"Step": 1,
"Intro": "这里是头部......",
"Position": ""
},
{
"Element": "#btnSearch",
"Step": 2,
"Intro": "搜索内容 ",
"Position": ""
}
]
}
]
五. 效果图