3

我正在尝试使用 hopscotch.js 创建一个交互式游览。JavaScript 库需要 tour 才能工作的标准数据结构如下:

// Define the tour!
    var tour = {
      id: "hello-hopscotch",
      steps: [
        {
          title: "My Header",
          content: "This is the header of my page.",
          target: "header",
          placement: "right"
        },
        {
          title: "My content",
          content: "Here is where I put my content.",
          target: document.querySelector("#content p"),
          placement: "bottom"
        }
      ]
    };

将游览步骤直接放入 JavaScript 库效果很好,但理想情况下,我希望能够将所有这些细节保存在数据库中,并使用 AJAX 将数据传递给 hopscotch.js。(这样可以动态创建游览,并且content可以在不发布代码的情况下进行更改)。

除了我target使用document.querySelector()元素选择器时,一切都运行良好。

我的每个游览步骤的基本 C# 模型如下:

public class MockTourSteps
{
    public string Title { get; set; }
    public string Content { get; set; }
    public string Target { get; set; }
    public string Placement { get; set; }
}

作为Target一个字符串,我必须用双引号传递值。

这样做的问题是,当它被序列化为 JSON 时,使用 Chrome 开发者工具查看页面时会出现以下错误:

Syntax error, unrecognized expression: document.querySelector(".btn-primary")

浏览已经返回到页面的 JSON 数据,我可以看到我周围的双引号document.querySelector()导致了问题。

target当我指定targetvia时,我需要从我的中删除这些双引号,document.querySelector()但是当我target基于 HTML 标记(例如header.

有什么想法可以实现这一目标吗?

4

1 回答 1

1

在提供的示例中,您使用 javascript 对象但您将从服务器获取 JSON 的主要问题。您将需要在客户端使用某种 JSON 处理。

我认为您可以在模型中添加更多信息:

public class MockTourStep
{
    public string Title { get; set; }
    public string Content { get; set; }
    public TargetC Target { get; set; }
    public string Placement { get; set; }

    public enum TargetType
    {
        ElementName,
        QuerySelector
    }

    public class TargetC
    {
        [JsonConverter(typeof(StringEnumConverter))]
        public TargetType Type { get; set; }

        public string Value { get; set; } 
    }
}

和样本响应:

var tour = new
{
    Id = "hello-hopscotch",
    Steps = new List<MockTourStep>
    {
        new MockTourStep
        {
            Title = "My Header",
            Content = "This is the header of my page.",
            Target = new MockTourStep.TargetC
            {
                Type = MockTourStep.TargetType.ElementName,
                Value = "header"
            },
            Placement = "bottom"
        },
        new MockTourStep
        {
            Title = "My content",
            Content = "Here is where I put my content.",
            Target = new MockTourStep.TargetC
            {
                Type = MockTourStep.TargetType.QuerySelector,
                Value = "document.querySelector('#content p')"
            },
            Placement = "bottom"
        }
    }
};

然后,在客户端,您可以检查目标类型并将其设置为有效值:

$.getJSON("url", function (tour) {
    for (var i = 0; i < tour.steps.length; i++) {
        var step = tour.steps[i];

        switch (step.target.type) {
            case "ElementName":
                step.target = step.target.value;
                break;
            case "QuerySelector":
                step.target = eval(step.target.value);
                break;
            default:
                throw Error;
        }
    }

    hopscotch.startTour(tour);
});

请注意eval用于QuerySelector. 使用 ofeval很危险,因此您需要检查您为客户提供的服务。

于 2015-05-05T15:06:39.677 回答