我在我的应用中实现了几个hopscotch tours。
到目前为止,我已经设法进行了很多旅行,没有任何问题,但是今天,我面临的挑战我无法解决。
我的问题是:我如何获得巡回步骤目标以动态生成的内容工作?
这是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中无法进行操作。
这是我的hopscotch步骤代码:
{
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
}
第一步有效,但第二步行不通。
我在做什么错,我该如何修复?
我在整个地方搜索了该问题的解决方案,而这篇文章是最接近但不是完全确定的解决方案的文章,因此在这里进行:
{ // 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借了一些代码。他的解决方案是一种作品(尽管不是为了引导旅行),但无论如何,它在加载下一步并返回正确的方案时会产生轻弹。
我强烈建议不要使用延迟,它似乎在您的本地环境上起作用,但是推测客户加载需要多长时间是非常危险的。
希望它能帮助别人!
我正在使用的一个黑子是每个步骤上的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"
},
这似乎已经满足了我现在的需求,尽管显然不能根据您的加载来工作。
如果有人有更优雅的解决方案,我全都是耳朵!
我要等待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
告诉HopsCotch不要继续。然后onNext
函数检查我们要定位下一个元素是否存在并再次启动游览。
当然,如果您需要更频繁地将其提取为一般函数,以保持代码清洁和简短。
另一个解决方案(如果您显示的模式是另一个页面,它确实可以很好地工作)是从多页巡回演出示例中借用。从本质上讲,在页面上弹出模式是您可以开始巡回演出的地方。但是,在页面上,模态实际上加载了(或作为动态生成的内容的一部分),您可以执行诸如if (hopscotch.getState() == 'intro_tour:1') { hopscotch.startTour() }
之类的操作,从本质上讲,它可以继续由Loader页面启动。YMMV使用此方法,具体取决于您的模态负载。
我通过将步骤的目标成为一个getter解决了这个问题,因此当目标到达步骤本身
{ get target() { return document.querySelector('#your-step-target'); }
我无法让任何人的建议工作,问题似乎是在巡回演出开始时计算了动态生成的内容的 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。一个黑客将是用一些占位持有人的步骤来访问巡回演出,然后从"真实"的第一步开始(Yuck!)。我们真正需要的是一种在步骤选项中指定步骤号的方法。