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 explain the significance of triple brackets (e.g. {{{ content }}}) in the context of Javascript/Typescript?

As I delve into the code of a fresh project in which I hope to contribute, I have come across numerous methods defined with triple brackets, like so: deinitialize() {{{ this.destroyed = true; $(window).off("resize", this.resize as () => void); ...

Selenium - Tips for entering text in a dynamically generated text field using Javascript!

I'm fairly new to the world of web scraping and browser automation, so any guidance would be greatly appreciated! Using Python's Selenium package, my objective is: Navigate to Login using the provided username & password Complete my order thr ...

The Cross-Origin Request has been blocked due to the Same Origin Policy prohibiting access to the remote resource. The reason for this is that the CORS preflight response was unsuccessful

SERVERSIDE // Establishing Headers app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE"); res.header("Access-Control-Allow-Headers ...

Exploring node.js: How to extract elements from a path

I have an array of individuals as shown below: individuals = ['personA', 'personB', 'personC']; I am looking to create a dynamic way to showcase each individual's page based on the URL. For instance, localhost:3000/indi ...

Output a message to the Java console once my Selenium-created Javascript callback is triggered

My journey with Javascript has led me to mastering callback functions and grasping the concept of 'functional programming'. However, as a newcomer to the language, I struggle to test my syntax within my IntelliJ IDE. Specifically, I am working on ...

Struggling with the development of a crossfading image gallery using jQuery's .animate() function while ensuring compatibility with IE8

Seeking assistance in creating a crossfading image gallery using jQuery and the .animate() function. I'm struggling to solve the issue of smooth fadeIn for the next image while maintaining compatibility with IE8. https://jsfiddle.net/Vimpil/fqhc1e9m/ ...

Having difficulty showcasing API call results in a Vue.js component

I am currently experimenting with Vue.js in an attempt to showcase results from a Wikipedia API call within a component using the v-for directive. However, I seem to be encountering some backend issues that I cannot pinpoint. To access the jsFiddle link, ...

Changing the color of placeholder text in MUI 5 TextField

Looking to customize the text color and placeholder text color in my MUI TextField component to be green https://i.sstatic.net/NZmsi.png The documentation doesn't provide clear instructions, so I attempted a solution that didn't work: <TextF ...

Tips on displaying a confirmation box when the page is refreshed or closed

I need to implement a confirmation box for users who try to close the window without saving the content of a textarea within a form. Here is the code I currently have: var myEvent = window.attachEvent || window.addEventListener; var chkevent = window.att ...

Clones are made sortable instead of arranging them in a specific order

I have a list that can be sorted with some customizations. However, I am facing an issue where the items in the list get duplicated every time I try to sort them. When I pull one item to sort it, another copy gets added automatically. I am struggling to u ...

sending numerous ajax requests and they all seem to be returning identical results

When firing multiple ajax requests using the setinterval() function, I noticed that both requests are bringing back the same information from another page. Here is the JavaScript code: function views() { setInterval(function(){var xmllhttp //alert ...

Enable automatic indentation for wrapped text

I'm still learning the ropes here, but I'm looking to have text automatically indent when it's wrapped. Instead of this: Peter piper picked a peck of pickled peppers. It should look like this: Peter piper picked a peck of pickled pepp ...

Storing the outcome of a connection in a variable using Node.js

I am facing an issue with saving a function return in a const so that I can utilize the information outside of the function scope. Below is a snippet of code to better explain my problem: const express = require('express') const app = express() ...

Several jquery functions fail to operate as expected

After spending the entire day attempting to troubleshoot my code, I am still unable to figure out why it's not functioning properly. I have several jQuery functions, but when I try to combine them, one of them fails to work. Here is the current state ...

Ways to distinguish between two div elements that have scroll bars and those that do not

I created a div with CSS styling. .comment-list { margin: 20px 0; max-height: 100px; min-height: 100px; overflow-y: scroll; width: 100%; background-color:#000; } Here is the HTML code for the div: <div class="comment-list"> </div> When the ...

Issue encountered in Wicket Ajax Error Log: ERROR: The listener for the "click" event cannot be bound to the "AjaxCheckBox" element as it is not present in the Document Object Model (DOM)

When running my program, I am trying to dynamically add Panels to the main page and utilize "setVisible(boolean)" functionality. However, I am encountering an error: ERROR: Cannot bind a listener for event "click" on element "institutCheck7" because the ...

Unable to navigate through images on Bootstrap Carousel using previous and next buttons

Despite following tutorials and examining the HTML code on bootstrap, I'm facing issues while trying to create a carousel. I believed that everything was done correctly, but when I click on the next button, nothing happens. <!DOCTYPE html> < ...

What could be the reason for this JSON being considered "invalid"?

Despite passing validation on jsonlint, both Firefox and Chrome are rejecting this JSON: { "messages": [ { "subject": "One" }, { "subject": "Two" }, { "subject": "Three" ...

Disregard the sorting of rows in the MUI Datagrid

Any advice on excluding the "TOTAL" row from sorting in MUI library? onSortModelChange={(test, neww) => { neww.api.state.sorting.sortedRows = [14881337, 2, 3] neww.api.setState({...neww.api.state}) } } Review ...

Guide on passing the set[State] function to a trigger component that is not a descendent

Take a look at this diagram. ChildComponentB contains a state called stateX. In ChildComponentA, when a certain event occurs, it should modify the stateX in ChildComponentB. If ChildComponentA is a child component of ChildComponentB, passing the setStateX ...