Anish Sana Anish Sana - 5 months ago 10
Javascript Question

How do I stop jQuery TourBus from creating two instances on click?

I'm using jQuery Tourbus to guide a user through my website. I want it to show up on loading the window the first time someone visits but after that it shouldn't load unless the user clicks on the information icon.

To make sure it auto loads only when the user vists the first time, I did this -

<?php
if($tourbus_verify==0) {
?>

<script type="text/javascript">
$(window).load( function() {
var tour = $('#my-tour-id').tourbus( {} );
tour.trigger('depart.tourbus');
} );
</script>

<?php
}
?>


Upon loading the page, I have a method that enters the value
1
into the database. So, if a user visits for the first time,
$tourbus_verify
will be
0
, so the tour loads when the page loads. If the user has already visited the page before, the
$tourbus_verify
will be
1
so it won't auto load.

The tour it loads is as follows -

<ol class='tourbus-legs' id='my-tour-id'>

<li data-orientation='centered' data-width='400'>
<p>Hello</p>
<a href='javascript:void(0);' class='tourbus-next'>Next</a>
</li>

<li data-el='#stuff' data-orientation='top' data-width='400'>
<p>That's awesome</p>
<a href='javascript:void(0);' class='tourbus-prev'>Previous</a>
<a href='javascript:void(0);' class='tourbus-next'>Next</a>
</li>

<li data-el='#tourbus-restart' data-orientation='left' data-width='400'>
<p>Bye</p>
<a href='javascript:void(0);' class='tourbus-stop'>End!</a>
</li>

</ol>


Everything works well so far. Now, I have an icon which upon clicking loads the tour -

<div class="row-fluid">
<span style="cursor: pointer;" id="tourbus-restart">
<i class="fa fa-info" aria-hidden="true"></i>
</span>
</div>


And at the end of the page, I have -

<script type="text/javascript">
$("#tourbus-restart").click(function(){
var tourclick = $('#my-tour-id1').tourbus( {} );
tourclick.trigger('depart.tourbus');
});
</script>


This loads the same tour as before but with a different ID -

<ol class='tourbus-legs' id='my-tour-id1'>

<li data-orientation='centered' data-width='400'>
<p>Hello</p>
<a href='javascript:void(0);' class='tourbus-next'>Next</a>
</li>

<li data-el='#stuff' data-orientation='top' data-width='400'>
<p>That's awesome</p>
<a href='javascript:void(0);' class='tourbus-prev'>Previous</a>
<a href='javascript:void(0);' class='tourbus-next'>Next</a>
</li>

<li data-el='#tourbus-restart' data-orientation='left' data-width='400'>
<p>Bye</p>
<a href='javascript:void(0);' class='tourbus-stop'>End!</a>
</li>

</ol>


For some reason, this works well once, but fires an additional instance of the tour the second time, so I end up running two tours at the same time as shown in the image below -

enter image description here

So, I have to click each
Next
twice to finish the tour. Does anyone know what could be causing this? Thanks!

Answer

I see it this way:

The line $(selector).tourbus() is to initialize the plugin and bind some functionality to the element selector. When you put it inside the click event handler, you are initializing the element only when you click. So, if you click twice, then you are initializing twice. I can only assume clicking three times would initialize the plugin three times on the element; and so forth. When you initialize again, the previous instance(s) still remain attached the element.

So, by putting the line outside the click event handler, you are ensuring that the plugin is initialized only once.