Nicole McCoy
Nicole McCoy

Reputation: 358

Jquery event will not fire

I'm creating a simple hover "map." Basically hover over a marker and a popup with details is revealed. Anyways, It's mostly working fine except I want to add a close button. Right now the user can click outside the popup and close it out, but I need to add a close button in the corner. However, my closing event will not fire. For the time being I'm just trying to set it up where the user clicks anywhere in the content popup and it closes. Once I have that working I'll apply it to a styled div in the container. Here's a sample of my HTML:

<div id="container">
<div id="truck"><img src="eVie.png" width="637" height="280" alt="Evie" /></div>
<div class="marker a">
<div class="content a inactive"><img src="solarpanel.jpg" width="240" height="205" alt="Solar Panels" />
  <h2>Solar Panels</h2>
  <p>Here Comes The Sun: These solar panels capture light and heat from the sun to power exhibits when I’m out visiting around town.</p>
 </div>
 </div>
 <div class="marker b">
 <div class="content b inactive"><img src="tailpipe.jpg" width="240" height="205" alt="Tailpipe Area" />
  <h2>Tailpipe Area</h2>
  <p>No tailpipe, no fumes. That’s how I roll.</p>
 </div>
 </div>
 <div class="marker c">
 <div class="content c inactive"><img src="plug.jpg" width="240" height="205" alt="Plug" />
  <h2>Plug</h2>
  <p>Not An Ordinary Plug: Big trucks need more energy. To get all the energy I need, I have to have a bigger plug and a special outlet!</p>
 </div>
 </div>
 </div>

And here's my jQuery. All of it works fine except the content.active click function. WHY? I'm stumped on this!

$(document).ready(function(){

    $(".marker").hover(
        function(){
            $(this).children(".content.inactive").addClass("show");  
            $(this).children(".content.inactive").animate({width: 155}, "fast");     
        }
        ,
        function(){
            $(this).children(".content.inactive").animate({width: 5, height: 23}, "fast");
            $(this).children(".content.inactive").removeClass("show");       
        }
    );

    $(".content.inactive").click(
        function(){
            $(this).removeClass("inactive");
            $(this).addClass("active");  
            $(this).animate({width: 435, height: 205}, "fast"); 
            $(".inactive").addClass("disabled");
            $(".disabled").removeClass("inactive"); 
            $(".disabled").parent().addClass("dim");
            $("#truck img").addClass("dim");
        }
    );

    $(".content.active").click(
        function(){
            $(this).removeClass("active");
            $(this).removeClass("show");
            $(this).addClass("inactive");    
            $(this).animate({width: 5, height: 23}, "fast");
            $(".disabled").addClass("inactive");
            $(".disabled").parent().removeClass("dim");
            $(".inactive").removeClass("disabled");
            $("#truck img").removeClass("dim");
        }
    );

    $(".content").click(function(){ return false; });
    $(document).on("click", function() { 
        $(".content").animate({width: 5, height: 23}, "fast");
        $(".disabled").addClass("inactive");
        $(".inactive").removeClass("disabled"); 
        $(".inactive").parent().removeClass("dim");
        $("#truck img").removeClass("dim"); 
        $(".active").addClass("inactive");
        $(".show").removeClass("show");
        $(".active").removeClass("active"); 
    });
});

Here's the link to the site: http://stlenergy.org/evie/

Any help would be GREATLY appreciated. I'm sure my logic is not right or I'm missing something painfully obvious. Thanks!

Upvotes: 1

Views: 247

Answers (3)

mowwwalker
mowwwalker

Reputation: 17392

Use this:

function inactiveClick(){
            $(this).removeClass("inactive");
            $(this).addClass("active");  
            $(this).animate({width: 435, height: 205}, "fast"); 
            $(".inactive").addClass("disabled");
            $(".disabled").removeClass("inactive"); 
            $(".disabled").parent().addClass("dim");
            $("#truck img").addClass("dim");
        $(this).unbind('click'); // added this
        $(this).click(activeClick); // added this
        return false; // added this
}
function activeClick(){
            $(this).removeClass("active");
            $(this).removeClass("show");
            $(this).addClass("inactive");    
            $(this).animate({width: 5, height: 23}, "fast");
            $(".disabled").addClass("inactive");
            $(".disabled").parent().removeClass("dim");
            $(".inactive").removeClass("disabled");
            $("#truck img").removeClass("dim");
        $(this).unbind('click'); // added this
        $(this).click(inactiveClick); // added this
        return false; // added this
}
$(document).ready(function(){

    $(".marker").hover(
        function(){
            $(this).children(".content.inactive").addClass("show");  
            $(this).children(".content.inactive").animate({width: 155}, "fast");     
        }
        ,
        function(){
            $(this).children(".content.inactive").animate({width: 5, height: 23}, "fast");
            $(this).children(".content.inactive").removeClass("show");       
        }
    );

    $(".content.inactive").click(
        inactiveClick
    );

    $(".content.active").click(
        activeClick
    );
    //$(".content").click(function(){ return false; }); // removed so I can unbind the elements
    $(document).on("click", function() { 
        $(".content").animate({width: 5, height: 23}, "fast");
        $(".disabled").addClass("inactive");
        $(".inactive").removeClass("disabled"); 
        $(".inactive").parent().removeClass("dim");
        $("#truck img").removeClass("dim"); 
        $(".active").addClass("inactive");
        $(".show").removeClass("show");
        $(".active").removeClass("active"); 
    });
});

The problem, as mentioned by Shark, is that your elements don't have the active class until they are clicked, so they are never bound a click event.

I did the following:

  • Divided the inactive and active clicks into their own functions
  • Added return false to the two functions
  • Unbound the elements at the end of the click functions
  • Bound the new click events to the elements at the end of the click functions

edit: I didn't know it at the time, but jQuery has a .on() method which is perfect for your situation:

$(document).ready(function(){

    $(".marker").hover(
        function(){
            $(this).children(".content.inactive").addClass("show");  
            $(this).children(".content.inactive").animate({width: 155}, "fast");     
        }
        ,
        function(){
            $(this).children(".content.inactive").animate({width: 5, height: 23}, "fast");
            $(this).children(".content.inactive").removeClass("show");       
        }
    );

    $('body').on('click',".content.inactive",function(){
        $(this).removeClass("inactive");
            $(this).addClass("active");  
            $(this).animate({width: 435, height: 205}, "fast"); 
            $(".inactive").addClass("disabled");
            $(".disabled").removeClass("inactive"); 
            $(".disabled").parent().addClass("dim");
            $("#truck img").addClass("dim");
        }
    );

    $('body').on('click',".content.active",function(){
        $(this).removeClass("active");
            $(this).removeClass("show");
            $(this).addClass("inactive");    
            $(this).animate({width: 5, height: 23}, "fast");
            $(".disabled").addClass("inactive");
            $(".disabled").parent().removeClass("dim");
            $(".inactive").removeClass("disabled");
            $("#truck img").removeClass("dim");
    });
    $(".content").click(function(){ return false; }); // removed so I can unbind the elements
    $(document).on("click", function() { 
        $(".content").animate({width: 5, height: 23}, "fast");
        $(".disabled").addClass("inactive");
        $(".inactive").removeClass("disabled"); 
        $(".inactive").parent().removeClass("dim");
        $("#truck img").removeClass("dim"); 
        $(".active").addClass("inactive");
        $(".show").removeClass("show");
        $(".active").removeClass("active"); 
    });
});

Upvotes: 1

patrickmcgraw
patrickmcgraw

Reputation: 2495

I just looked at your site. I think you could get what you want with your existing code if you remove the click handler for .content.active and .content and add return false; to the end of the .content.inactive handler. By not returning false for the click on the active content the click event will bubble up to the document handler and that should close your open dialogs. This will have the added benefit of keeping your dialog closing code all in one place.

Upvotes: 0

user596075
user596075

Reputation:

I believe this is because at the time your listeners are declared, there is going to be no wrapped set that contains the classes content and active. So that click() listener isn't going to be assigned to any elements.

You would be able to do something like:

$(".content").click( 
function(){ 
    var inactiveObjects = $(this).hasClass("inactive"); 
    inactiveObjects.removeClass("inactive");
    inactiveObjects.addClass("active");   
    inactiveObjects.animate({width: 435, height: 205}, "fast");  
    $(".inactive").addClass("disabled"); 
    $(".disabled").removeClass("inactive");  
    $(".disabled").parent().addClass("dim"); 
    $("#truck img").addClass("dim");

    var activeObjects = $(this).hasClass("active"); 
    activeObjects.removeClass("active");
    activeObjects.removeClass("show"); 
    activeObjects.addClass("inactive");     
    activeObjects.animate({width: 5, height: 23}, "fast"); 
    $(".disabled").addClass("inactive"); 
    $(".disabled").parent().removeClass("dim"); 
    $(".inactive").removeClass("disabled"); 
    $("#truck img").removeClass("dim");  
} 
); 

Upvotes: 1

Related Questions