9

我在我的应用程序中实施了几个Hopscotch之旅。

到目前为止,我已经成功地进行了多次巡回演出,但今天,我面临着一个我无法解决的挑战。

我的问题是:如何获得一个游览步骤目标来处理动态生成的内容?

这是HTML:

<div class="pacote-destino-quartos-wrapper">
    <div class="pacote-destino-quartos-internal-wrapper">
        <h4>Todos os Destinos</h4>
        <div class="dynamic_nested_form_wrapper quartos_external_wrapper" data-destino="todos">
            <span class="add-child-link-wrapper">
                <a href="javascript:void(0)" class="add_child btn btn-info" data-association="quartos">
                    <i class="icon-plus icon-white"></i>
                </a>
            </span>
        </div>
    </div>
</div>

每当我单击链接时,它都会动态创建一个包含许多元素的 div;其中之一是一个 div 类,名为.quarto-config-wrapper.

如果我试图让我的 Hopscotch 之旅进入这个元素,它就行不通;我猜动态创建的元素在 DOM 中不可用于操作。

这是我的跳房子步骤代码:

{
    title: "Adicionar um novo quarto",
    content: "content here",
    target: $('.add-child-link-wrapper')[0],
    placement: "left",
    width: 500,
    yOffset: -15,
    nextOnTargetClick: true,
    showNextButton: false
},
{
    title: "Menu de configuração do quarto",
    content: "content here",
    target: $('.quarto-config-wrapper')[0],
    placement: "left",
    width: 700,
    yOffset: -15,
    nextOnTargetClick: true,
    showNextButton: false,
    delay: 1200
}

第一步有效,但第二步无效。

我做错了什么,我该如何解决?

4

6 回答 6

8

我到处寻找解决这个问题的方法,这篇文章是最接近但不是很确定的解决方案,所以这里是:

{ // This is the previous step
    element: "#idElement",
    title: "The Title",
    content: "The Content",
    onNext: function(tour) {
            tour.end();
            var checkExist = setInterval(function() {
                // This is the element from the next step. 
                $element = $('#idElementFromNextStep'); 

                if ($element.is(':visible')) {
                    clearInterval(checkExist);
                    tour.start(true); // True is to force the tour to start
                    tour.goTo(1); // The number is your next index (remember its base 0)
                }
            }, 100);
    },
    multipage: true, // Required
    orphan: true // Recommended
},{ // This is the step that was not working
    element: "#idElementFromNextStep",
    title: "Title of the step",
    content: "Details of the step",
    orphan: true,
}

所以这基本上是在下一个被触发时停止游览,等待元素被添加到 DOM,然后通过其索引从正确的步骤重新开始游览。

我从@Luksurious 借了一些代码。他的解决方案很有效(尽管不适用于 Bootstrap Tour),但无论如何它在加载下一步并返回正确的步骤时都会生成一个轻弹。

我强烈建议不要使用延迟,它似乎适用于您的本地环境,但推测客户端加载需要多长时间非常危险。

希望它可以帮助别人!

于 2015-03-08T00:22:19.040 回答
3

我正在使用的一种解决方法是delay每一步的字段。那是:

{
  title: "+Log",
  content: "Lipsum",
  target: "#log_activity_nav",
  placement: "left",
  nextOnTargetClick: true


},

{

  title: "Phone",
  content: "The bottom section is where each individual log and detail lives, sorted by importance.",
  target: "#activity_log_activity_log_brokers_attributes_0_contact_attributes_phone", // this target is part of an element that is dynamically generated
  delay: 2000, // wait 2 seconds for this element to load
  placement: "top"
},

这似乎满足了我现在的需求,但显然它不能保证根据你加载的内容而工作。

如果有人有更优雅的解决方案,我会全力以赴!

于 2014-04-07T16:09:58.903 回答
2

我等待 AJAX 调用的方法如下:

{
  title: "Title",
  content: "Content",
  target: '.triggerAjax',
  placement: 'bottom',
  onNext: function() {
    $('.triggerAjax').click();

    var checkExist = setInterval(function() {
      $element = $('.dynamicallyLoaded');

      if ($element.is(':visible')) {
        clearInterval(checkExist);

        window.hopscotch.startTour(window.hopscotch.getCurrTour(), window.hopscotch.getCurrStepNum());
      }
    }, 100);
  },
  multipage: true
},

使用multipage告诉跳房子不要继续。然后该onNext函数检查我们接下来要定位的元素是否存在并再次开始游览。

当然,如果您更频繁地需要它,请将其提取为通用函数,以保持代码简洁明了。

于 2014-07-16T13:48:12.947 回答
1

另一种解决方案(如果您显示的模式是另一页,则效果非常好)是从多页浏览示例中借用。本质上,在弹出模式的页面上,您将开始游览。但是,在模态实际加载的页面上(或作为动态生成内容的一部分),您可以执行类似 的操作if (hopscotch.getState() == 'intro_tour:1') { hopscotch.startTour() },这实际上将继续由加载器页面启动的游览。使用此方法的 YMMV,具体取决于您的模态负载。

于 2014-04-15T19:38:25.167 回答
1

我通过将步骤的目标设置为 getter 解决了这个问题,因此它在到达步骤本身时查询目标的 dom

{ get target() { return document.querySelector('#your-step-target'); }
于 2019-01-31T14:17:23.473 回答
0

我无法得到任何人的建议,问题似乎是target动态生成内容的属性是在游览开始时计算的(当它还没有出现在页面上时)。

对我有用的是将一个游览嵌套在另一个游览中。这是我经过测试和工作的代码:

var tourP1 = {
  id: "tutp1",
  steps: [
    {
      title: "Step 1",
      content: "Lorem ipsum dolor.",
      target: "header",
      placement: "bottom"
    },
    {
      title: "Step 2",
      content: "Lorem ipsum dolor.",
      target: document.querySelector('#content'),
      placement: "top",
      multipage: true,
      onNext: function() {
        // Trigger dynamic content
        $('.someElement').trigger('click');
        // Wait for your target to become visible
        var checkExist = setInterval(function() {
          $element = $('.someElement').find('.myElement');
          if ($element.is(':visible')) {
            clearInterval(checkExist);
            // End this tour
            hopscotch.endTour(true);
            // Define the next tour
            var tourP2 = {
              id: "tutp2",
              steps: [
                {
                  title: "Step 3",
                  content: "Lorem ipsum dolor.",
                  target: $('.someElement').find('.myElement')[0],
                  placement: "bottom"
                }
              ]
            }
            // Start the nested tour
            hopscotch.startTour(tourP2);
          }
        }, 100);
      }
    },
    // This is needed for the onNext function in the previous step to work
    {
      title: "",
      target: "",
      placement: ""
    }
  ]
};

这里需要注意的一点是,当嵌套游览开始时,步数会返回到 1。一个技巧是用一些占位符步骤填充游览,然后从“真正的”第一步开始(糟糕!)。我们真正需要的是一种在步骤选项中指定步骤编号的方法。

于 2016-07-27T08:27:18.733 回答