Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery preventing nextAll() to reverse order of menu

When menuitem gets clicked its siblings float to the right.

I use jQuery's nextAll() for this.

My problem is, that the order of the floated siblings is reversed and i want them to stay in their initial order.

My question is: Is there a jQuery method capable of doing this? Otherwise, how could i create my intended behaviour of the menu-items floating right in the correct ordering?

I tried using:

  • '.backAll()',
  • 'Array.prototype.reverse',
  • '$('.menu').nextAll().toArray();' and calling .reverse() on that.

I do understand, that the float does exactly what it should, but i can't grasp when and how i should reorder my menu-items to place them "correctly" (how i want them to).

Do i need to create an array through which i iterate to reoder those menu-items grabbed with .nextAll() or do i have to call the float:right at another time?

Please also see this JSfiddel for an example. Clicking a div floats its siblings to the right and reverses the order, which i don't want to happen.

If you could include a small explanation of what behaviour i'm obviously missing / not understanding and pointing me towards it, i would really appreciate that too.

Thank you.

$('.menu').on('click', function() {
  $(this).nextAll().css('float', 'right');
});
.menu {
  float: left;
  height: 60px;
  width: 60px;
  border: 1px solid #000;
  text-align: center;
  vertical-align: middle;
  line-height: 60px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
  <div class='menu'>A
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>B
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>C
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>D
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
</div>

Edit for the accepted answer: I added the correct answer by @UncaughtTypeError and modified the fiddle, which helped me understand better what happened and removed the else-fork, which was unneeded for showcasing the desired behaviour. JSfiddle by @UncaughtTypeError

Edit 2: @UncaughtTypeError reworked his example from his comment and added it as an separate answer. Please see below for the more indepth explanation.

like image 505
HeiFa Avatar asked Jan 01 '26 10:01

HeiFa


2 Answers

Key Functions Applied:

  1. .prependTo(): https://api.jquery.com/prependto/
  2. .nextAll(): https://api.jquery.com/nextAll/
  3. .appendTo(): https://api.jquery.com/appendto/
  4. .prevAll(): https://api.jquery.com/prevAll/

The Code Snippet embedded below demonstrates the above functions applied to shift elements right, and then restore them to initial states when clicked on again.

$('.menu').on('click', function() {
  if (!jQuery(this).parent().hasClass('align-right')) {
    if ($('.align-right').length == 0) {
      $('<div class="align-right"></div>').prependTo('.container');
      $(this).nextAll().prependTo('.align-right');
    } else {
      $(this).nextAll().prependTo('.align-right');
    }
  } else if (jQuery(this).parent().hasClass('align-right')) {
    jQuery(this).prevAll().appendTo('.container');
    if (jQuery(this).prevAll().length == 0) {
      jQuery(this).appendTo('.container');
    }
  }
});
.menu {
  float: left;
  position: relative;
  height: 60px;
  width: 60px;
  border: 1px solid #000;
  text-align: center;
  vertical-align: middle;
  line-height: 60px;
}

.align-right {
  float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
  <div class='menu'>A
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>B
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>C
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
  <div class='menu'>D
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
    <div class='submenu'></div>
  </div>
</div>

jSFiddle: https://jsfiddle.net/b4wywp30/8/

like image 70
UncaughtTypeError Avatar answered Jan 02 '26 23:01

UncaughtTypeError


I updated your jQuery to wrap the siblings with an span with a class of right. Then floated that container right - fiddle

jQuery

$('.menu').on('click', function(){
    $('.menu').unwrap();
    $(this).nextAll().wrapAll('<span class="right">');
 });

CSS

.container {
  width: 100%;
}
span.right {
  float:right;
}
like image 37
Jim-miraidev Avatar answered Jan 02 '26 23:01

Jim-miraidev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!