我正在我的应用中实施几个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
}
第一步有效,而不是第二步。有什么帮助吗?
答案 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'); }