J.R
J.R

Reputation: 11

jQuery doesn't recognise that the class changed, although the Browser does

I have been trying out to create a Dropdown-menu with jQuery. I have 3 Sub-folders with 3 sub-sub-folders each (correct me if this is the wrong term). Depending on wether the Sub-folder is collapsed (Sub-subs invisible) or expanded (Sub-subs visible) there´s a little arrow pointing downwards when expanded and to the right when collapsed. I´m a Newbie and don´t want to use many external scripts, so I remove the Subshown_arrow Class and add the Subhidden_arrow Class when clicked (or the other way).

<a href="#"> <img id="arrow" class="Subshown_arrow" /> Sub-forum 1 </a>
            <li class="sub-sub"> <a href="#"> Sub-sub-forum 1 <li>
            <li class="sub-sub"> <a href="#"> Sub-sub-forum 2 <li>
            <li class="sub-sub"> <a href="#"> Sub-sub-forum 3 <li>

I removed the scr here ^, normally it´s there.

var main = function() {


$(".Subshown_arrow").click(function() {
    alert("Subshown_arrow clicked!");
    $(this).removeClass("Subshown_arrow").addClass("Subhidden_arrow");
});

$(".Subhidden_arrow").click(function() {
    alert("Subhidden_arrow clicked!");
    $(this).removeClass("Subhidden_arrow").addClass("Subshown_arrow");
});
};

$(document).ready(main);

However, when I click the Arrow for the first time, it rotates as expected. But when I click it another time, jQuery reacts as if it was clicked for the first time. The alerts print out "Subshown_arrow clicked!" every time.

But when I tried it out in the Browser and used Chrome´s built-in tools to view the Code, the Class changed. That means that changing the Class works, but my jQuery script ignores it.

What have i done wrong? Or is there a better way to do it?

Upvotes: 0

Views: 91

Answers (5)

nammalvar 2.0
nammalvar 2.0

Reputation: 111

Better way

var main = function() {

$("#arrow").click(function() {
$(this).toggleClass("Subshown_arrow").toggleClass("Subhidden_arrow"); 
});

};

$(document).ready(main);

Upvotes: 0

Me.Name
Me.Name

Reputation: 12544

As mentioned the problem is that the click is bound on document load, at which time there are no elements with a class subhidden_arrow. This can indeed be solved by using a parent elements click and a filter on the class using (on). However, the original bound click event can also be reused to toggle the classes:

$(".Subshown_arrow").click(function() {
    $(this).toggleClass("Subshown_arrow").toggleClass("Subhidden_arrow");
});

The click is bound to the element on load and reacts on both 'states', regardless of which class it holds then.

An example Fiddle with a slight alteration to make the containing anchor react to the click event.

Upvotes: 0

Jai
Jai

Reputation: 74738

You are using an img without any src and if you have more images then i would mention to not to use same ids.

So, what you can do is give a common class name to the element:

 <img class="arrow Subshown_arrow" />
 <!----------^^^^^-------like this one---->

Now you can use the class arrow to bind the click event and you can use toggleClass() method to change the classes:

$(".arrow").click(function() {
    $(this).toggleClass("Subshown_arrow Subhidden_arrow");
});

Upvotes: 0

Ashkan Mobayen Khiabani
Ashkan Mobayen Khiabani

Reputation: 34160

If you use .on it will work when classes changes as new handler will be assigned to it. but when you use .click it is assigend to the object that had the matching class at first and although the class has changed but still the old handler is assigned to it.

var main = function() {


$("body").on("click",".Subshown_arrow",function() {
    alert("Subshown_arrow clicked!");
    $(this).removeClass("Subshown_arrow").addClass("Subhidden_arrow");
});

$("body").on("click","Subhidden_arrow",function() {
    alert("Subhidden_arrow clicked!");
    $(this).removeClass("Subhidden_arrow").addClass("Subshown_arrow");
});
};

Upvotes: 0

Christopher
Christopher

Reputation: 86

Your problem has already been solved thousands of times, you are binding to .Subhidden_arrow and .Subshown_arrow classes when the first doesn't exist yet. You need to bind the events differently:

$('body').on('click', '.Subhidden_arrow', function ( e ) {});

This will work also on dynamically created (changed) elements.

Upvotes: 2

Related Questions