跳房子游览步骤动态生成的内容

时间:2014-03-11 14:27:06

标签: javascript jquery hopscotch

我正在我的应用中实施几个Hopscotch(https://github.com/linkedin/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。其中一个是带有一个名为.quarto-config-wrapper的类的div。

如果我试图让我的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
        }

第一步有效,而不是第二步。有什么帮助吗?

6 个答案:

答案 0 :(得分: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),但无论如何,当它加载下一步并返回正确的时,它会产生一个轻弹。

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

希望它可以帮助别人!

答案 1 :(得分:3)

我正在使用的一个hackaround是每一步的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"
},

这似乎满足了我现在的需求,但显然不能保证能够正常工作,具体取决于您的装载情况。

如果有人有更优雅的解决方案,我全都耳朵!

答案 2 :(得分: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函数检查我们想要定位的元素是否存在并再次开始游览。

当然,如果您更频繁地需要它,请将其作为一般功能提取,以保持代码清洁和简短。

答案 3 :(得分:1)

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

答案 4 :(得分: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。一个黑客将用一些占位符步骤填充游览,并从“真正的”第一步开始(哎呀!)。我们真正需要的是一种在步骤选项中指定步骤编号的方法。

答案 5 :(得分:0)

我通过使步骤的目标为吸气剂解决了这个问题,因此当目标到达步骤本身时,它会向dom查询目标

{ get target() { return document.querySelector('#your-step-target'); }