Jquery 动态生成内容上的跳房子巡演步骤

Jquery 动态生成内容上的跳房子巡演步骤,jquery,hopscotch,Jquery,Hopscotch,我在我的应用程序中实现了几个旅行 到目前为止,我已经成功地进行了很多巡回演出,没有任何问题,但今天,我面临着一个远未解决的挑战 我的问题是:如何让巡演步骤目标处理动态生成的内容 以下是HTML: <div class="pacote-destino-quartos-wrapper"> <div class="pacote-destino-quartos-internal-wrapper"> <h4>Todos os Destinos&l

我在我的应用程序中实现了几个旅行

到目前为止,我已经成功地进行了很多巡回演出,没有任何问题,但今天,我面临着一个远未解决的挑战

我的问题是:如何让巡演步骤目标处理动态生成的内容

以下是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>
第一步可行,但第二步不行


我做错了什么以及如何修复它?

我正在使用的一个破解方法是每个步骤上的
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"
},
这似乎满足了我目前的需求,尽管很明显,它不能保证根据您加载的内容工作


如果有人有更优雅的解决方案,我洗耳恭听

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

我等待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
函数检查下一步要瞄准的元素是否存在,并再次开始巡更


当然,如果您更经常需要此功能,请将其提取为一个通用函数,以保持代码简洁明了。

我到处寻找此问题的解决方案,而这篇文章是最接近但不太确定的解决方案,因此它是:

{ // 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那里借了一些代码。他的解决方案是可行的(虽然不适用于引导程序),但在任何情况下,它都会在加载下一步并返回到正确的步骤时生成一个flick

我强烈建议不要使用延迟,它可能在您当地的环境中起作用,但推测客户加载所需的时间是极其危险的


希望它能帮助别人

我无法得到任何人的建议,问题似乎是动态生成内容的
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。一种方法是在巡演中加入一些占位符步骤,然后从“真正的”第一步开始(恶心!)。我们真正需要的是一种在步骤选项中指定步骤编号的方法。

我解决了这个问题,方法是让步骤的目标成为getter,这样当它到达步骤本身时,它会向dom查询目标

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

我试着从第一个静态元素调用从dinamically创建的。。。不起作用延迟解决方案对我也起作用。。。但正如你所说,这绝对是一种“胡闹”!我认为传递给
startTour
this
应该是
window.hopscotch.getCurrTour()
。我对这个答案投了赞成票,因为这是我一直在寻找的答案,但即使在我改变了开始巡演的路线之后,这个答案对我来说也不太管用。我似乎无法从onNext函数中调用
startTour
开始第二步。如果我获取了对它外部的tour对象的引用,然后将其传递到
startTour
,我可以这样做。我的tour位于一个更大的结构中,当前的tour保存在一个变量中。您可以将tour对象保存在变量
onStart:function(){window.lastTour=window.hopsocch.getCurrTour();}
中,然后从interval函数中访问该变量。
{ get target() { return document.querySelector('#your-step-target'); }