Executing a function with a click, then undoing it with a second click

My goal is to trigger an animation that involves text sliding off the screen only when the burger icon is clicked, rather than loading immediately upon refreshing the page. The desired behavior includes activating the function on the initial click and then reversing it if the icon is clicked again, with the first character ('C') re-entering the display first.


jQuery("#button").click(function() {
  jQuery(".line1").toggleClass("open1");
  jQuery(".line2").toggleClass("open2");
  jQuery(".line3").toggleClass("open3");
});

(function text_loop(i) {
  setTimeout(function() {
    if (i <= 15)
      $("#logo_text span").eq(i).addClass("slide_out");
    i++;
    text_loop(i);
  }, 100);
})(0);

#burger_container {
  background-color: #404041;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 60px;
  z-index: 101;
}

svg {
  margin: 20px auto 0 auto;
  display: block;
}

#logo_text {
  transform: rotate(-90deg);
  margin-top: 350px;
  font-size: 40px;
  color: #ffffff;
  font-weight: 700;
}

#logo_text span {
  font-weight: 400;
  position: relative;
  top: 0;
  transition: top 1s ease;
}

#logo_text span.slide_out {
  top: -60px;
  transition: top 0.5s ease;
}

.line1,
.line2,
.line3 {
  transition: all 0.3s ease;
}

.open1 {
  transform-origin: top left;
  transform: translatex(3px) translatey(-1px) rotate(45deg);
  width: 33px;
}

.open2 {
  opacity: 0;
}

.open3 {
  transform-origin: bottom left;
  transform: translatex(3px) translatey(1px) rotate(-45deg);
  width: 33px;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<div id="burger_container">
  <div>
    <svg id="button" style="height: 26px; width: 26px;">
      <g style="" fill="#f04d43">
        <rect class="line1" x="0" y="1" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line2" x="0" y="11" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line3" x="0" y="21" rx="2" ry="2" width="26px" height="4px" />
      </g>
    </svg>

    <div id="logo_text"><span>C</span><span>o</span><span>m</span><span>p</span><span>a</span><span>n</span><span>y</span>&nbsp;<span>W</span><span>o</span><span>r</span><span>k</span><span>f</span><span>o</span><span>r</span><span>c</span><span>e</span></div>
  </div>
</div>

Answer №1

execute it as a function and your setTimeout will keep going by enclosing it in curly brackets within an if statement

jQuery("#button").click(function() {
  jQuery(".line1").toggleClass("open1");
  jQuery(".line2").toggleClass("open2");
  jQuery(".line3").toggleClass("open3");
  var currentClass = $("#logo_text span").eq(0).attr('class');
  if(currentClass === undefined || currentClass == "slide_in") {
    text_loop(0, 'slide_out');
  }
  else {
    text_loop(0, 'slide_in');
  }
});

function text_loop(i, classname) {
  setTimeout(function() {
    if(i <= 15) {
      $("#logo_text span").eq(i).attr('class', classname);
      i++;
      text_loop(i, classname);
    }
  }, 100);
}
#burger_container {
  background-color: #404041;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 60px;
  z-index: 101;
}

svg {
  margin: 20px auto 0 auto;
  display: block;
}

#logo_text {
  transform: rotate(-90deg);
  margin-top: 350px;
  font-size: 40px;
  color: #ffffff;
  font-weight: 700;
}

#logo_text span {
  font-weight: 400;
  position: relative;
  top: 0;
  transition: top 1s ease;
}

#logo_text span.slide_out {
  top: -60px;
  transition: top 0.5s ease;
}

#logo_text span.slide_in {
  top: 0px;
  transition: top 0.5s ease;
}

.line1,
.line2,
.line3 {
  transition: all 0.3s ease;
}

.open1 {
  transform-origin: top left;
  transform: translatex(3px) translatey(-1px) rotate(45deg);
  width: 33px;
}

.open2 {
  opacity: 0;
}

.open3 {
  transform-origin: bottom left;
  transform: translatex(3px) translatey(1px) rotate(-45deg);
  width: 33px;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<div id="burger_container">
  <div>
    <svg id="button" style="height: 26px; width: 26px;">
      <g style="" fill="#f04d43">
        <rect class="line1" x="0" y="1" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line2" x="0" y="11" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line3" x="0" y="21" rx="2" ry="2" width="26px" height="4px" />
      </g>
    </svg>

    <div id="logo_text"><span>C</span><span>o</span><span>m</span><span>p</span><span>a</span><span>n</span>&nbsp;<span>W</span><span>o</span><span>r</span><span>k</span><span>f</span><span>o</span><span>r</span><span>c</span><span>e</span></div>
  </div>
</div>

Answer №2

I've modified the code to accommodate the desired behavior.

jQuery("#button").click(function() {

  jQuery(".line1").toggleClass("open1");
  jQuery(".line2").toggleClass("open2");
  jQuery(".line3").toggleClass("open3");

if(jQuery("#button").data("shown") == "True"){


  
  (function text_loop(i) {
  setTimeout(function() {
    if (i <= 15)
      $("#logo_text span").eq(i).removeClass("slide_in");
      $("#logo_text span").eq(i).addClass("slide_out");
    i++;
    text_loop(i);
  }, 100);
})(0);

jQuery("#button").data("shown", "False")
  }else {
  (function text_loop(i) {
  setTimeout(function() {
    if (i <= 15)
      $("#logo_text span").eq(i).removeClass("slide_out");
      $("#logo_text span").eq(i).addClass("slide_in");

    
    i++;
    text_loop(i);
  }, 100);
})(0);
jQuery("#button").data("shown", "True")
  }
  
  
});
#burger_container {
  background-color: #404041;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 60px;
  z-index: 101;
}

svg {
  margin: 20px auto 0 auto;
  display: block;
}

#logo_text {
  transform: rotate(-90deg);
  margin-top: 350px;
  font-size: 40px;
  color: #ffffff;
  font-weight: 700;
}

#logo_text span {
  font-weight: 400;
  position: relative;
  top: 0;
  transition: top 1s ease;
}

#logo_text span.slide_out {
  top: -60px;
  transition: top 0.5s ease;
}

#logo_text span.slide_in {
  top: 0px;
  transition: top 0.5s ease;
}



.line1,
.line2,
.line3 {
  transition: all 0.3s ease;
}

.open1 {
  transform-origin: top left;
  transform: translatex(3px) translatey(-1px) rotate(45deg);
  width: 33px;
}

.open2 {
  opacity: 0;
}

.open3 {
  transform-origin: bottom left;
  transform: translatex(3px) translatey(1px) rotate(-45deg);
  width: 33px;
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<div id="burger_container">
  <div>
    <svg id="button" style="height: 26px; width: 26px;" data-shown="True" >
      <g style="" fill="#f04d43">
        <rect class="line1" x="0" y="1" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line2" x="0" y="11" rx="2" ry="2" width="26px" height="4px" />
        <rect class="line3" x="0" y="21" rx="2" ry="2" width="26px" height="4px" />
      </g>
    </svg>

    <div id="logo_text"><span>C</span><span>o</span><span>m</span><span>p</span><span>a</span><span>n</span><span>y</span>&nbsp;<span>W</span><span>o</span><span>r</span><span>k</span><span>f</span><span>o</span><span>r</span><span>c</span><span>e</span></div>
  </div>
</div>

I have made modifications in the onclcik event handler and introduced a new CSS class called slide_in.

I trust that my solution will be beneficial to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing a dynamically created Stripe checkout button

Currently, I am attempting to integrate a checkout button from the Stripe Dashboard into my VueJS Project. I have a feeling that I might not be approaching this in the correct manner, so if you have any advice, I would greatly appreciate it. In order to ...

Tips for keeping components mounted despite changes in the path

How can I maintain state in React routes to prevent unmounting when switching between them? In my application, it's crucial to keep the state intact during route changes. When changing routes, the respective components mount and unmount. How can this ...

What are the steps to integrate dynamic data into chartjs?

Can you assist me in understanding how to dynamically populate Chartjs with data from a json file? Specifically, I am looking to dynamically fill the labels and data fields. Sample JSON File <<< [ { "EFICAZ_TAB_ITEM_ID":1, " ...

Troubleshooting JSON Array Index Problems

I'm having trouble reaching index 3 in the array using the javascript options on my webpage. The final question "are you satisfied with your choice?" is not showing up for me. I'm not sure what I might be missing or doing incorrectly in this sit ...

Managing headers for localhost with Access-Control-Allow-Origin

I've run into a challenge with my React app. I'm making endpoint calls to different servers and have withCredentials set to true to include a token/cookie in the requests. The issue arises when trying to make this work seamlessly on localhost. S ...

The value of an AngularJS service is not being reflected in the view

I have implemented the stateProvider in my code, and I am facing an issue with updating the breadcrumbs in the header when the state changes. Instead of creating embedded views for each state, I have a service that shares an array of breadcrumbs containing ...

The AXIOS method in Express.js is designed to return a Promise object that may contain an

I am currently learning ExpressJS and Axios I have created a folder named utils and placed the axios.js file const axios = require('axios'); loadDataPesan=async function(opts){ axios.get('localhost/getData', { params ...

Displaying a random number triggers a snackbar notification in a ReactJS application

Currently, I am utilizing the notistack package to display a snackbar on the screen. However, when calling the Snack component with enqueuesnackbar, a random number is displayed along with the snackbar. I'm looking to eliminate this random number fro ...

Exploring the synergy of Jquery function invocation within the Angular 2 framework

Attempting to implement the convForm jQuery plugin in my Angular 2 application has been a challenge for me. I managed to successfully install both jQuery and convForm into my project by making changes to the angular.json file. In the example provided in ...

To ensure the next line only runs after the line above has finished executing, remember that the function is invoked in HTML

my.component.html <button (click)="refresh()">Refresh</button> my.component.ts refresh() { let self = this; self.isRefresh = true; //1st time self.getfun().then(() => { self.isRefresh = false; ...

How to make the Bootstrap mobile navigation menu taller?

I'm having trouble adjusting the height of the collapsed mobile drop-down navigation. Right now, it's stuck at around 340px and I need it to expand to accommodate all the menu items within the collapsed nav. Despite my efforts searching on Google ...

Ways to conditionally display a component in Next.js without the issue of caching CSS styles

I'm a newcomer to Next.js and I'm still trying to wrap my head around how the caching works. Let's take a look at this simplified example: An index page that displays either Test1 or Test2 components, based on whether the current minute is ...

Adding data to each span and div using JavaScript is a simple task that can be achieved easily

What is the best way to add information to each span and div element using JavaScript? $(document).on("click",".selection-state",function(){ stateid = $(this).attr("rel"); $("#my_tooltip").html(data); } e ...

Assigning alphanumeric characters to the axis for identification purposes

review the code in index.html <!DOCTYPE html> <html> <head> <title>D3 test</title> <style> .grid .tick { stroke: lightgrey; opacity: 0.7; } .grid path { stroke-width: 0; } .ch ...

Exploring the process of assigning responses to questions within my software program

I am looking to display my question choices as radio buttons in a modal window. I have tried several solutions without success. Here is my question module: import questions from "./Data"; const QuestionModel = () => { return ( <div cl ...

Is it possible to use @ViewChild to target an element based on its class name?

The author of this article on Creating Advanced Components demonstrates selecting an element by creating a directive first: @Directive({ selector: '.tooltip-container' }) export class TooltipContainerDirective {} Then, the author uses this d ...

Establish a connection between the Discord Bot and a different channel

I need help with my Discord bot that should redirect someone to a different channel when they mention certain trigger word(s). I feel like there might be a missing line or two of code that I need to add to make it work properly. bot.on("message", messag ...

Implementation of Ionic Tabs with Hidden Back Button

Is there a way to hide the back button for a specific tab in my ionic app without affecting the rest of the page? I tried adding "hide-back-button="true" to the tab code, but it didn't work as expected. I want to achieve something like this: <ion ...

Having trouble retrieving properties from a JavaScript JSON object?

I am currently working with a JSON object that contains properties for MAKEs, MODELs, YEARs, STATEs, PLATEs, and COLORs. There are 4 instances of each property within the object: Object {MAKE1="xxx ", MODEL1='xxx', YEAR1='xxx', STATE1= ...

The collapsible hamburger navbar is unresponsive and fails to collapse

Currently, I am working on a project that requires my navigation bar to be scaled down to a hamburger menu for mobile view. I have managed to do most of it, but for some reason, the navigation is not collapsing within the hamburger bar. I have been tweakin ...