Reputation: 60
Why does the following code not work? The red square becomes green but on a second click doesn't become red again.
jQuery(document).ready(function($) {
$("#red").click(function() {
$(this).attr("id", "green");
});
$("#green").click(function() {
$(this).attr("id", "red");
});
});
div {
margin: 0 auto;
width: 100px;
height: 100px;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red">
See also: https://codepen.io/thomasmalley/pen/OqWNaM
Upvotes: 1
Views: 157
Reputation: 129
change script
$(document).on('click','#red',function() {
$('#red').attr("id", "green");
});
$(document).on('click','#green',function() {
$('#green').attr("id", "red");
});
Upvotes: 0
Reputation: 2498
First, there is div
with id red
and after clicking that div it switches id to green
that is dynamically so in this case we use event-delegation. Try below code -
jQuery(document).ready(function($) {
$(".parent").on('click', '#red', function() {
$(this).attr("id", "green");
});
$(".parent").on('click', '#green', function() {
$(this).attr("id", "red");
});
});
div {
margin: 0 auto;
width: 100px;
height: 100px;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div id="red"></div>
</div>
Upvotes: 2
Reputation: 30739
Since the id is added dynamically, the code $("#green").click(function() {
when loaded will not find element with id green
so the click event is not set for that element. Thus you can add a listener on document level:
jQuery(document).ready(function($) {
$(document).on('click', 'div', function(){
var id = $(this).attr('id');
if(id === 'red'){
$(this).attr("id", "green");
} else {
$(this).attr("id", "red");
}
});
});
div {
margin: 0 auto;
width: 100px;
height: 100px;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red">
Upvotes: 1
Reputation: 50814
This is happening because when you load the page there is no element with the id green
for a click event to be added to.
Instead, you can use event delegation by using:
$(document).on('click', '#red', function() {...}
and
$(document).on('click', '#green', function() {...}
This way, your click event will be applied to the element with the id green
.
See working example below:
jQuery(document).ready(function($) {
$(document).on('click', '#red', function() {
$(this).attr("id", "green");
});
$(document).on('click', '#green', function() {
$(this).attr("id", "red");
});
});
div {
margin: 0 auto;
width: 100px;
height: 100px;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red"></div>
Upvotes: 1
Reputation: 337610
The issue is because you assign the event handler on load, before the #green
element exists.
To fix this you need to use delegated event handlers so that the element selector is evaluated when the event occurs:
jQuery(function($) {
$(document).on('click', "#red", function() {
$(this).attr("id", "green");
});
$(document).on('click', "#green", function() {
$(this).attr("id", "red");
});
});
div {
margin: 0 auto;
width: 100px;
height: 100px;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red"></div>
That being said, it's not great practice to be changing id
attributes at runtime. They should be static. A much better idea would be to toggle a class
on the element instead, which governs the styling.
jQuery(function($) {
$('#foo').click(function() {
$(this).toggleClass('green');
});
});
#foo {
margin: 0 auto;
width: 100px;
height: 100px;
background-color: red;
}
#foo.green {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="foo"></div>
Upvotes: 8