Discovering the most recently selected element in jQuery

Currently reading a jQuery tutorial from the Head First series and practicing with an example where I need to identify the last selected element.

In Chapter 2, there is a task involving four images on a page. When a user clicks on any of these images, they receive a random discount message that appears below the image. To make it more visually appealing, I incorporated the slideUp() function which was introduced in Chapter 1 of the same book.

So far, when a user clicks on an image, the discount message slides down beneath it revealing the offer. If another image is clicked, the previous message slides back up and a new one displays below the newly selected image. Below is a simplified version of my code.

$('.jumpDiv').click(function () {
                $('.jumpDiv').children('.discountDiv').slideUp();
     $('.jumpDiv p').remove();
     var discount = Math.floor((Math.random() * 5) + 5);
     var msg = '<p>Your discount is ' + discount + '%</p>';
     $(this).children('.discountDiv').append(msg);
     $(this).children('.discountDiv').slideDown();
});
.jumpDiv{
    float:left;
}
#main{
    border:1px solid;
    height:500px;
    width:auto;
    background-color: grey;
}
 #main .jumpDiv{
    border-right: 1px solid;
    border-bottom: 1px solid;
    height:245px;
    width:245px;
    font-size:20px;
}
#main .jumpDiv>div{
    text-align:center;
    background-color:#fee;
    cursor: pointer;
    
}
.discountDiv{
    text-align: center;
    display:none;
    border:1px solid;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<body>
<div id="main">
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
        </div>
        <script
  src="https://code.jquery.com/jquery-3.2.1.js"
  integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
  crossorigin="anonymous"></script>
</body>

The issue I'm facing revolves around preventing the discount message div from sliding up and down multiple times if the same image is repeatedly clicked. Is there a way to detect the last clicked element and modify the behavior such that the message updates without unnecessary animations?

Answer №1

To avoid redundant actions, you must keep track of the reference to the lastClicked entity and compare it with the next clicked value. If they are the same, no action should be taken. Review the code snippet below for implementation details.

var lastClicked = null;
$('.jumpDiv').click(function () {
     if(lastClicked === this) {
         /*Don't do anything*/
         return;
     }

     $('.jumpDiv').children('.discountDiv').slideUp();
     $('.jumpDiv p').remove();
     var discount = Math.floor((Math.random() * 5) + 5);
     var msg = '<p>Your discount is ' + discount + '%</p>';
     $(this).children('.discountDiv').append(msg);
     $(this).children('.discountDiv').slideDown();
    
     lastClicked = this;
});
.jumpDiv{
    float:left;
}
#main{
    border:1px solid;
    height:500px;
    width:auto;
    background-color: grey;
}
 #main .jumpDiv{
    border-right: 1px solid;
    border-bottom: 1px solid;
    height:245px;
    width:245px;
    font-size:20px;
}
#main .jumpDiv>div{
    text-align:center;
    background-color:#fee;
    cursor: pointer;
    
}
.discountDiv{
    text-align: center;
    display:none;
    border:1px solid;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<body>
<div id="main">
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
        </div>
        <script
  src="https://code.jquery.com/jquery-3.2.1.js"
  integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
  crossorigin="anonymous"></script>
</body>

Answer №2

To simplify the code, you can use slideUp() on the visible .discountDiv, but only if the clicked element doesn't already have a visible discount. The jQuery selector :visible can help with this check. Additionally, instead of appending, you can set the HTML content each time to avoid the need to remove the <p> elements.

$('.jumpDiv').click(function () {
  var jumpDiv = $(this);
  var discountDiv = jumpDiv.children('.discountDiv');

  var discount = Math.floor((Math.random() * 5) + 5);
  var msg = '<p>Your discount is ' + discount + '%</p>';
  discountDiv.html(msg);

  if(!discountDiv.is(':visible')){
    $('.discountDiv:visible').slideUp();
  }
  discountDiv.slideDown();     
});

Demo

$('.jumpDiv').click(function() {
  var jumpDiv = $(this);
  var discountDiv = jumpDiv.children('.discountDiv');
  var discount = Math.floor((Math.random() * 5) + 5);
  var msg = '<p>Your discount is ' + discount + '%</p>';
  discountDiv.html(msg);
  if (!discountDiv.is(':visible')) {
    $('.discountDiv:visible').slideUp();
  }
  discountDiv.slideDown();
});
.jumpDiv {
  float: left;
}

#main {
  border: 1px solid;
  height: 500px;
  width: auto;
  background-color: grey;
}

#main .jumpDiv {
  border-right: 1px solid;
  border-bottom: 1px solid;
  height: 245px;
  width: 245px;
  font-size: 20px;
}

#main .jumpDiv>div {
  text-align: center;
  background-color: #fee;
  cursor: pointer;
}

.discountDiv {
  text-align: center;
  display: none;
  border: 1px solid;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<body>
  <div id="main">
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
</body>

Answer №3

I utilized a class to determine which element is currently open. Then, I checked if the one we are going to close is different from the one we want to open, and only closed it if they are not the same.

$('.jumpDiv').click(function() {
  var activeDiscount = $('.discountDiv.active');
  if (activeDiscount.closest('.jumpDiv')[0] != $(this)[0]) {
    activeDiscount.removeClass('active').slideUp();
  }
  $('.jumpDiv p').remove();
  var discount = Math.floor((Math.random() * 5) + 5);
  var msg = '<p>Your discount is ' + discount + '%</p>';
  $(this).children('.discountDiv').append(msg);
  $(this).children('.discountDiv').slideDown().addClass('active');
});
.jumpDiv {
  float: left;
}

#main {
  border: 1px solid;
  height: 500px;
  width: auto;
  background-color: grey;
}

#main .jumpDiv {
  border-right: 1px solid;
  border-bottom: 1px solid;
  height: 245px;
  width: 245px;
  font-size: 20px;
}

#main .jumpDiv>div {
  text-align: center;
  background-color: #fee;
  cursor: pointer;
}

.discountDiv {
  text-align: center;
  display: none;
  border: 1px solid;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<body>
  <div id="main">
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
    <div class="jumpDiv">
      <div> Click Here</div>
      <div class="discountDiv">

      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
</body>

Answer №4

To enhance the active tab, consider adding a specific class and then verifying if it is currently open or closed.

View the example on jsFiddle: https://jsfiddle.net/bf1tmxsw/

Answer №5

If you want to compare the DOM objects and detect when the same element is clicked twice, check out this example in action:

var previousTarget=null;
$('.jumpDiv').click(function () {
    previousTarget=this;
    if(this===previousTarget) {
        $('.jumpDiv p').remove();
        var discount = Math.floor((Math.random() * 5) + 5);
        var msg = '<p>Your discount is ' + discount + '%</p>';
        $(this).children('.discountDiv').append(msg);
        $(this).children('.discountDiv').slideDown();
    }
    else {
       $('.jumpDiv').children('.discountDiv').slideUp();
    }
    return false;
});
.jumpDiv{
    float:left;
}
#main{
    border:1px solid;
    height:500px;
    width:auto;
    background-color: grey;
}
 #main .jumpDiv{
    border-right: 1px solid;
    border-bottom: 1px solid;
    height:245px;
    width:245px;
    font-size:20px;
}
#main .jumpDiv>div{
    text-align:center;
    background-color:#fee;
    cursor: pointer;
    
}
.discountDiv{
    text-align: center;
    display:none;
    border:1px solid;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<body>
<div id="main">
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
            <div class="jumpDiv">
                <div> Click Here</div>
                <div class="discountDiv">

                </div>
            </div>
        </div>
        <script
  src="https://code.jquery.com/jquery-3.2.1.js"
  integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
  crossorigin="anonymous"></script>
</body>

Answer №6

To verify the current event trigger, use the code snippet below:

$('.jumpDiv').click(function () {
     var discount = Math.floor((Math.random() * 5) + 5);
     var msg = '<p>Your discount is ' + discount + '%</p>';
     $(this).children('.discountDiv').append(msg);

     if($(this).children('.discountDiv').css('display') === 'none'){
         $('.jumpDiv').children('.discountDiv').slideUp();
         $('.jumpDiv p').remove();
         $(this).children('.discountDiv').slideDown();
     }
});

Answer №7

I have created a JSFiddle example that is extremely user-friendly.

If you want to learn more about .on() or .html(), check out the links provided.

In order to save the ID of the last clicked item, consider using Cookies or localStorage for this purpose.

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

Can you provide a basic illustration of how routes are implemented in AngularJS?

After searching through numerous examples of using Routes with Angular, I have unfortunately not been able to find a working solution. Even the example provided in the official guide did not work properly (clicking on it resulted in a wrong URL that did no ...

Using Ajax and jQuery to Retrieve the Value of a Single Tag Instead of an Entire Page

Let's say I have a webpage named page.html: <!doctype html> <html> <head> <meta charset="utf-8"> <title>Page</title> </head> <body> <h1>Hello World!!</h1> </body> </html> Now ...

Developing a JavaScript library that utilizes flow type annotations and provides access to various data types

I am currently developing a library intended for use by third parties. I have opted to utilize flowtype as the typing system for specific reasons within my organization. This library presents React components with annotations. The library itself is annota ...

By utilizing the window.history.back() function, it takes me four clicks to navigate back one page

I find it peculiar that my back button is using the JS method window.history.back() to return to the previous page. However, I have noticed a strange behavior with this button. When I click on it before the entire document loads, it functions as expected a ...

Using Express middleware in a TypeScript Express application

I'm currently converting the backend of an ExpressJS application to Typescript. While working on the auth.routes.ts file, I encountered an issue with the middleware (authMiddleware). It seems like there might be a typing error, as the same code in the ...

I'm curious about the reason behind the error message stating "Navbar is defined but never used" popping up while working with Vue

After importing the Navbar component from Navbar.vue, I attempted to include it in my app.vue. However, upon doing so, I encountered an error stating 'Navbar' is defined but never used. As a newcomer to Vue, I am unsure of why this issue is occur ...

One way to determine whether .ajax is using Get or POST is to check the type parameter

I have a query: $.ajax({ url: "http://twitter.com/status/user_timeline/treason.json?count=10&callback=?", success: function (data, textStatus, jqXHR) { }, error: function (jqXHR, textStatus, errorThrown ...

Issue with Angular 6 Animation not showing up

Looking to incorporate an animation spinner into my Angular app Found this spinner example: https://codepen.io/z-/pen/OPzNLz spinner.component.html import { Component, OnInit } from '@angular/core'; @Component({ selecto ...

Tips for broadcasting the blob

I am currently working on a radio system project that involves streaming live audio from a microphone to the user in real-time. However, I am new to using node.js and unsure of how to achieve this. Can anyone provide guidance on how to stream the audio fro ...

Encircling a particular group of cells with a border

I have completed the component with a table layout. My current challenge is figuring out how to surround a range of selected cells with a border, similar to the first cell in the group shown below: https://i.stack.imgur.com/5Euht.png I attempted using d ...

Enhance the performance of page loading and implement a consistent spinner feature to ensure smooth transitions for users in Next.js version 13

I am currently working on a project using Next.js 13, and I am encountering issues with slow loading times and an unstable spinner when navigating between pages. Specifically, when transitioning from the home page to the /example page, the experience is n ...

What is the process for extracting information from a middleware within a Next.js framework?

I have been working on developing an authentication system using JWT in Next.js. In order to achieve this, I created a middleware that can validate the JWT token and establish an authentication process as shown below: export default function middleware(req ...

When attempting to click the submit button, the action of submitting a form using jQuery/AJAX is not functioning as expected

When attempting to submit a form using jquery/AJAX, my function does not get called when clicking on the submit button. The structure of my website is as follows: CarMenu.php <html lang="en"> <html> <head> <meta charset="ISO-8859- ...

Error: JSX elements that are next to each other must be contained within a parent tag

I am trying to display articles on a page using ReactJS, but I encountered an issue where I need to wrap enclosing tags. It seems like React doesn't accept identical tags next to each other. How can I effectively show tabular data? render() { r ...

Preventing the JSF form from automatically scrolling to the top of the screen following an AJAX request

Is there a way to prevent the JSF form from moving to the top of the screen after an AJAX call? I have searched for solutions, but the answers seem outdated or not specific to JSF. Is there a simple technique in JSF that can stop the form from jumping back ...

Delivering compressed files in a React server

Having some trouble serving a gzip compression of my bundle.js file in React. Have tried reducing the size with uglify and dedupe, but only saw a small decrease from 2.9mb to 2.6mb. Using the compression plugin now outputs a gzip file, however, still servi ...

What techniques can be used to ensure that an ASMX web service sends JSON data to the client in response to an HTTP GET

Trying to integrate the official jQuery autocomplete plugin with an ASMX web service in an ASP.NET 3.5 Web Forms application has been challenging. The autocomplete plugin requires HTTP GET calls with specific query string parameters, but I'm strugglin ...

Having trouble with Postgres not establishing a connection with Heroku

My website is hosted on Heroku, but I keep encountering the same error message: 2018-05-06T19:28:52.212104+00:00 app[web.1]:AssertionError [ERR_ASSERTION]: false == true 2018-05-06T19:28:52.212106+00:00 app[web.1]:at Object.exports.connect (_tls_wrap.js:1 ...

Discovering the import path of Node modules in ReactAlgorithm for determining the import path of

Software Development In my current project, I am utilizing Typescript along with React. To enhance the application, I integrated react-bootstrap-date-picker by executing yarn install react-bootstrap-date-picker. Unfortunately, there is no clear instruct ...

How can you prioritize one CSS file over another?

To avoid repetition, I wish to have all the classes, tags, and ids from css.css take precedence over bootstrap.min.css, without duplicating any from bootstrap.min.css. <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/css.css ...