Question

I have a script that I am using to hide and show different parts of a page. It's purpose is to step the user back and forth through the content when they click links. I need to keep all of this content on the same page, I can't break it into separate pages.

So far, when the page loads, I'm able to hide and show what I want for Step One and then append a link that will take the user to Step Two.

When Step Two shows and appends a link to go back to Step One, or go to Step Three, these links don't work. It appears that the prevent default action isn't working. When you click the links they go to he URL instead of showing step one or step three.

Why is my link to step two working and not my links to step one and step three?

stepOne.show();
    stepOneTwo.show('fast', function() {
        stepOneTwo.append( z + '<a href="#step2" style="color:white;"    id="step_2">GO TO NEXT STEP >></a></div>');
        });

            $("#step_2").click(function(e){ 
            e.preventDefault();
                 stepOne.hide(); 
                 stepOneTwo.hide(); 
                 stepTwo.toggle();
                 stepTwoTwo.show('fast', function() {
                 stepTwo.append(z + '<a href="#step1" style="color:white;" id="step_1">BACK >></a></div></br></br>' + z + '<a href="#step3" style="color:white;" id="step_3">GO TO NEXT STEP >></a></div>');
                }); 
            }); 

            $("#step_1").click(function(e){ 
            e.preventDefault();
                stepTwo.hide();
                stepTwoTwo.hide();
                stepThree.hide(); 
                stepThreeTwo.hide();
                stepThreeThree.hide();
                stepThreeFour.hide();
                stepFour.hide();
                stepFourTwo.hide();
                stepFourThree.hide();
                k.hide();
                stepOne.show();
                stepOneTwo.show('fast', function() {
                stepOneTwo.append( z + '<a href="..." style="color:white;" id="step_2">GO TO NEXT STEP >></a></div>');
                });
            });

            $("#step_3").click(function(e){ 
            e.preventDefault();
                 stepTwo.hide(); 
                 stepTwoTwo.hide(); 
                 stepThree.toggle();
                 stepThreeTwo.toggle();
                 stepThreeThree.toggle();
                 stepThreeFour.show('fast', function() {
                 stepThree.after(c + '<a href="..."       style="color:white;" id="step_2">GO BACK >></a></div> </br></br>' + c + '<a href="..." style="color:white;" id="step_6">GO TO NEXT STEP >></a></div>');                                   
                }); 
            }); 

});     
</script>
Was it helpful?

Solution

It seems you are dynamically appending steps.

At the time of event binding the element must exist in the DOM.

If you have bound an event but then for example replace the DOM element with the event, the event is removed along with the DOM element and must be re-bound.

To not having to constantly re-bind you could bind the events using event delegation.
This will bind the event indirectly to the dynamic element through a static element.

Instead of this:

$("#step_2").click(function(e){ //... });

Use either on() with delegation or delegate(), depending on your jQuery version, similar to this:

// when using jQuery 1.7 or later
$("body").on("click", "#step_2", function(e){ //... });

// or when using jQuery 1.6 or earlier -- note the reversal of event and target
$("body").delegate("#step_2", "click", function(e){ //... });

Instead of body you should use the closest static element which would be preferred.

OTHER TIPS

I think the problem is that at the time that your handler for $("#step1").click() is parsed, there is no #step1 element to bind it to - the element is created later, when #step2 is clicked.

To allow the handler to bind to an as-yet uncreated element, use on() (http://api.jquery.com/on/), binding to some nearby parent object and filtering for your link element as described in the "Direct and delegated events" section in the above link.

Assuming that your link elements are within a <div id="links"></div> (they probably aren't but you didn't give any HTML source so I'm inventing a little), you could rewrite your step 1 handler (and similarly for the others) as:

    $("#links").on("click", "#step_1", function(e){ 
        e.preventDefault();
        stepTwo.hide();
        stepTwoTwo.hide();
        stepThree.hide(); 
        stepThreeTwo.hide();
        stepThreeThree.hide();
        stepThreeFour.hide();
        stepFour.hide();
        stepFourTwo.hide();
        stepFourThree.hide();
        k.hide();
        stepOne.show();
        stepOneTwo.show('fast', function() {
            stepOneTwo.append( z + '<a href="..." style="color:white;" id="step_2">GO TO NEXT STEP >></a></div>');
        });
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top