0

Want to rotate div 45 degree on each click. It works fine as expected. I have 3 '.expand-btn' class name in this page. What happens, on click it triggers on all '.expand-btn'.

I want to trigger only on this 'expand-btn'. not others.

JS:

var _rotation = 0;

$.fn.rotate = function(degrees) {
    $(this).css({'transform' : 'rotate('+ degrees +'deg)'});
};

$('.expand-btn').click(function() {
    _rotation += 45;
    $(this).rotate(_rotation);
});

HTML:

<div class="expand-btn" id="test1">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>
<div class="expand-btn" id="test2">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>
<div class="expand-btn" id="test3">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>
TDG
  • 1,294
  • 4
  • 18
  • 50
  • should work because of this context.. – guradio May 23 '17 at 03:52
  • 2
    It doesn't work because a single `_rotation` variable is being used for all 3.. – Useless Code May 23 '17 at 03:53
  • `href="javascript:void(0)"` is a very old and very [bad anti-pattern](https://stackoverflow.com/a/1293130/778975). The `javascript:` pseudo-URLs were [intended for creating bookmarklets](http://javascriptexample.net/badjs01.php) and shouldn't be used in page scripting. You might benefit from reading a blog post I wrote recently about [spotting bad JS tutorials](http://www.uselesscode.org/blog/posts/spotting-bad-javascript-tutorials/). – Useless Code May 23 '17 at 04:55

2 Answers2

2

You would need to have a distinct storage of the rotation value for each of the objects. You could e.g. use jQuery.data() for that:

$.fn.rotate = function(delta) {
   // get the current stored rotation, or 0 if none was currently stored
   var degrees = $(this).data().rotation || 0;

   // add the delta to this value
   degrees += delta;

   // store the new value with the object
   $(this).data().rotation = degrees;

   // set the transformation
   $(this).css({'transform' : 'rotate('+ degrees +'deg)'});
};

$('.expand-btn').click(function() {
    $(this).rotate(45);
});

To extend a jQuery set correctly you should iterate over the elements of the set and apply the code for each of the individually. The way $.fn.rotate is written now will set the rotation of all elements in the set based on the value of the first one.

Or parse the current transform to retrieve that actual value.

t.niese
  • 39,256
  • 9
  • 74
  • 101
0

You can add a data- attribute to the div where you can store the current angle.

HTML:

<div class="expand-btn" id="test1" data-degrees="0">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>
<div class="expand-btn" id="test2" data-degrees="0">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>
<div class="expand-btn" id="test3" data-degrees="0">
   <a href="javascript:void(0);" data-toggle="collapse">+</a>
</div>

JS:

$(document).ready(function(){
  $('.expand-btn').click(function() {
        var currentDegrees = $(this).data("degrees");
      currentDegrees += 15;
      $(this).css({'transform' : 'rotate(' + currentDegrees + 'deg)'});
      var currentDegrees = $(this).data("degrees", currentDegrees);
  });
});

Example: https://jsfiddle.net/tejsoft/dwxb1a1b/

TejSoft
  • 3,213
  • 6
  • 34
  • 58