One action after another on the same selector (jquery)

jquery selector
jquery ::after click event
jquery find
jquery ::after selector
jquery parent
jquery closest
jquery append
jquery each

I don't know how to figure this out. I got a selector, with 2 actions :

1) If I click I want to the 1st action to be ran. 2) If the 1st have been clicked, the second click on the object should run the 2nd action. 3) If the 2nd have been click, go back to step 1).

I'm new into Jquery. Is it clear enough ?

  // 1st action
  $('.menu').click(function(){
    $(".dropleft").css("bottom","0vh");
    $(this).css("transform","rotate(90deg)");
  });
  // 2nd action
  $('.menu').click(function() {
    $(".dropleft").css("bottom","");
    $(this).css("transform","");
  });

You can pass an IIFE returning a function that will maintain a toggle to the click handler:

// 1st action
$('.menu').click((function(toggleValue){
  return function(e){
      if(toggleValue){//first action
        $(".dropleft").css("bottom","0vh");
        $(this).css("transform","rotate(90deg)");      
      }else{//second action
        $(".dropleft").css("bottom","");
        $(this).css("transform","");      
      }
      toggleValue = !toggleValue;//toggle
  }
})(true)/** IIFE */);

As for Karl's comment; you could set a user defined attribute on the element if you have multiple .menu elements:

// 1st action
$('.menu').click(function(e){
  toggleValue=e.target.getAttribute("data-toggle");
  if(toggleValue!=="toggle"){//first action
    $(".dropleft").css("bottom","0vh");
    $(this).css("transform","rotate(90deg)");
    e.target.setAttribute("data-toggle","toggle");
  }else{//second action
    $(".dropleft").css("bottom","");
    $(this).css("transform","");      
    e.target.setAttribute("data-toggle","next");
  }
  toggleValue = !toggleValue;//toggle
});

.one(), Description: Attach a handler to an event for the elements. A selector string to filter the descendants of the selected elements that trigger After the code is executed, a click on the element with ID foo will display the In other words, explicitly calling .off() from within a regularly-bound handler has exactly the same effect. I would like to apply that height function to more than just that specific ID in one line of jQuery. Is there a way to chain elements together and apply that height function once for multiple elements? Basically, I want to apply that height function to 3 or 4 other DIVs but I would rather not have 3 or 4 more lines of jQuery to accomplish this.

I'd suggest using CSS classes and jQuery's toggleClass function. Less complex and more maintainable.

CSS:

.bottom { bottom: "0vh" }
.rotate { transform: rotate(90deg) }

JS:

$('.menu').click(function() {
   $(".dropleft").toggleClass("bottom");
   $(this).toggleClass("rotate");
});

Multiple Selector (“selector1, selector2, selectorN”), selector2: Another valid selector. selectorN: As many more valid selectors as you like. You can specify any number of selectors to combine into a single result. If selector is omitted or is null, the event handler is referred to as direct or directly-bound. The handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element. When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles

Use a single event handler, with a flag stored using .data():

$('.menu')
  .click(function() {
    var $menu = $(this);
    var active = $menu.data('active');
    var $dropleft = $menu.siblings(".dropleft");

    if (active) {
      $dropleft.css("color", "");
      $menu.css("transform", "");
    } else {
      $dropleft.css("color", "red");
      $menu.css("transform", "rotate(90deg)");
    }

    $menu.data('active', !active);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <button class="menu">Menu1</button>

  <div class="dropleft">dropLeft1</div>
</div>

<div>
  <button class="menu">Menu2</button>

  <div class="dropleft">dropLeft2</div>
</div>

.after(), insertAfter() methods perform the same task. The major difference is in the An element in the DOM can also be selected and inserted after another element:  Calling one jQuery function only after another function has run Sometimes it may be nessessary to force one jQuery function to run only after another has finished. To do this you need to use the jQuery deferred method. Here is a simple example of how to do it:

You can check on some css property

 $('.menu').click(function(){
    const transform = $(this).css("transform");
    if (transform) {
      $(".dropleft").css("bottom","");
      $(this).css("transform","");
    } else {
       $(".dropleft").css("bottom","0vh");
      $(this).css("transform","rotate(90deg)");
    }
  });

.nextAll(), Description: Get all following siblings of each element in the set of matched The method optionally accepts a selector expression of the same type that we If we had supplied one, the elements would be tested for a match before they were included. jQuery in Action by Bear Bibeault, Yehuda Katz, and Aurelio De Rosa​  .one( events [, data ], handler )Returns: jQuery. Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type. A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.

You're setting 2 functions to execute when you click in menu class.

You should just create one function and control what should execute.

Here is an example:

var control = false;

$('.menu').click(function() {
  if (control = !control) {
    $(".dropleft").css("bottom", "0");
    $(this).css("transform", "rotate(90deg)");
  } else {
	  $(".dropleft").css("bottom", "");
    $(this).css("transform", "");
  }
});
.menu {
  width: 100px;
  height: 50px;
  background: green;
}

.dropleft {
  width: 100px;
  height: 50px;
  position: absolue;
  left: 0;
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
  menu
</div>

next( [selector, Description: Get the immediately following sibling of each element in the set of The method optionally accepts a selector expression of the same type that we If we had supplied one, the element would be tested for a match before it was included. jQuery in Action by Bear Bibeault, Yehuda Katz, and Aurelio De Rosa​  Books. Learning jQuery Fourth Edition Karl Swedberg and Jonathan Chaffer jQuery in Action Bear Bibeault, Yehuda Katz, and Aurelio De Rosa jQuery Succinctly Cody Lindley

.insertAfter(), The .after() and .insertAfter() methods perform the same task. The major difference is in We can also select an element on the page and insert it after another:  Attribute Contains Word Selector [name~=”value”] Selects elements that have the specified attribute with a value containing a given word, delimited by spaces. Attribute Ends With Selector [name$=”value”] Selects elements that have the specified attribute with a value ending exactly with a given string.

.siblings(), The method optionally accepts a selector expression of the same type that we can pass However, if the original collection contains more than one element, they might be Find the unique siblings of all yellow li elements in the 3 lists (​including other jQuery in Action by Bear Bibeault, Yehuda Katz, and Aurelio De Rosa  Important: If there is more than one target element, however, cloned copies of the inserted element will be created for each target except for the last one. Passing a Function. As of jQuery 1.4, .after() supports passing a function that returns the elements to insert.

Event Handler, Description: Attach an event handler function for one or more events to the selected elements. A selector string to filter the descendants of the selected elements that trigger the event. (Event handlers bound to an element are called in the same order that they were bound.) Click any paragraph to add another after it. after() - Create content with HTML, jQuery and DOM Insert content with the after() method. Insert content using a function How to use a function to insert content after selected elements.

Comments
  • Down-voting is not a nice way of saying welcome to a new user!
  • Would that work if there are multiple .menu?
  • @Karl-AndréGagnon Good point, no it won't each .menu needs it's own. You could do $('.menu').each to add a listener to each .menu updated answer
  • Still, I like the IIFE way. The .each would bother me, but for a single element, that's a nice way to do it. By the way, you should use .data instead of setting an invalid HTML attribute! It would allow you to have a true boolean as well! Just a little tip.
  • The first solution worked perfect. Thanks a lot.
  • @Karl-AndréGagnon Thanks for the tip, changed the answer to use data-... attribute names i thought the spec was any attribute with something- was a custom attribute but seems to be anything data-* is (for html 5)