thomasmalley
thomasmalley

Reputation: 60

jQuery toggle between two ID's

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

Answers (5)

Mehul Koradiya
Mehul Koradiya

Reputation: 129

change script

 $(document).on('click','#red',function() {
    $('#red').attr("id", "green");
  });

  $(document).on('click','#green',function() {
    $('#green').attr("id", "red");
  });

Upvotes: 0

Shubham Baranwal
Shubham Baranwal

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

Ankit Agarwal
Ankit Agarwal

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

Nick Parsons
Nick Parsons

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

Rory McCrossan
Rory McCrossan

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

Related Questions