Connecting event listeners to offspring elements, the main element, and the entire document

My request is as follows: I have multiple boxes displayed on a webpage, each containing clickable divs and text. When a user clicks on a clickable div, an alert should appear confirming the click. Clicking on the text itself should not trigger any action. However, here's where it becomes more complex.

Upon clicking on a box, it should acquire the class open. If a user clicks anywhere outside of a box or its children, the class open should be removed. Clicking on a clickable div within the box should not affect the box's class.

If a user clicks on another box, the original box should retain the open class while the new box also acquires this class. Clicking on the header, body, or anything else besides the boxes should remove the open class. Remember that clicking on a clickable div should display an appropriate alert.

It seems like there are many event targeting scenarios involved here, so I'm curious if you have a good solution for this.

To demonstrate, please ensure that when a box has the open class, its background turns green. Clicking on elements such as the header or body should revert the box back to its original steelblue color. If a user clicks on a clickable child div, the box's background should turn green and an alert should pop up.

Below is some sample code:

$(document).on("click", function(e) {
  //is there somthing like:
  // if `this` is not the box or children of box remove the
  // class `open` from box. this way if they click on header or body I could remove 
  //the `open` class from box
  if (e.target == this) {
    $(".box").removeClass("open")
  } else if ($(e.target).hasClass("box")) {
    $(e.target).addClass("open")
  }
  if ($(e.target).hasClass("test1")) {
    alert("test1")
  }
  if ($(e.target).hasClass("test2")) {
    alert("test2 clicked")
  }
  if ($(".box").hasClass("open")) {
    $(this).css("background", "green")
  }
})
.box {
  margin: 4em 5em;
  background: steelblue;
  width: 15em;
  height: 8em;
  padding: .1em;
}
.clicker {
  width: 5em;
  background: lightgreen;
  padding: .2em;
  cursor: pointer;
}
.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3em;
  background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="header">header</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test2 clicker">Test click 2</p>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test clicker">Test click 2</p>
</div>

Answer №1

Maybe just adjusting the conditions could solve the issue like so:

$(document).on("click", function(e) {
  // Perhaps something like this:
  // If `this` is not the box or any of its children, remove the
  // class `open` from the box. This way, clicking on the header or body should remove
  // the `open` class from the box

  var $target = $(e.target);

  var $clicker = $target.closest('.clicker');
  if ($clicker.length) {
    if ($clicker.hasClass("test")) {
      $('#clicked').html("test")
    } else if ($clicker.hasClass("test1")) {
      $('#clicked').html("test1")
    } else if ($clicker.hasClass("test2")) {
      $('#clicked').html("test2")
    }
  }

  var $box = $target.closest('.box');
  if ($box.length) {
    $box.addClass('open');
  } else {
    $('.box.open').removeClass('open');
  }
})
.box {
  margin: 4em 5em;
  background: steelblue;
  width: 15em;
  height: 8em;
  padding: .1em;
}
.box.open {
  background-color: lightgrey;
}
.clicker {
  width: 5em;
  background: lightgreen;
  padding: .2em;
  cursor: pointer;
}
.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3em;
  background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">header:
  <div id="clicked"></div>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test2 clicker">Test click 2</p>
</div>
<div class="box">
  <p>this is the box</p>
  <p class="test1 clicker">Test click</p>
  <p class="test clicker">Test click 2</p>
</div>

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

The issue of conflicting checkboxes and types plugins in jstree

Working on constructing a tree with the jstree JavaScript library and incorporating two jstree plugins: checkbox plugin types plugin Below is a snippet of code for reference: var mydata=[ id: "1", parent: "#", text: "node1", }, { id: "2", parent: " ...

WebpackError: The global object "document" could not be found

I am encountering an issue with my website build using gatsby.js and bulma. While building the site, I receive the following error message: WebpackError: document is not defined The only instance where I use document is for the navbar-burger toggle code ...

Switch out multiline text with javascript

Could someone assist me with this question? I am attempting to locate and replace specific code within a JavaScript file. The code is included in an AJAX response that contains a significant amount of HTML code. After retrieving the AJAX response, I stor ...

Adjust the size of the image obtained from the JSON data

I am currently working on parsing JSON data which includes an image field that I want to adjust to a specific size. Despite my many attempts at tweaking the code, I seem to have lost track of why it is not functioning as desired. JSON var items=[]; ...

When attempting to assign a variable in my ngModel, what issue could be causing a problem?

I am facing an issue while trying to implement ngModel in my code. The code is not executing properly and an error is being displayed. Below is the code snippet: contact-form.component.html: <div class="container"> <form> <div class ...

Step-by-step guide on achieving 100% height for a child element within a parent using Flexbox

Currently facing an issue where trying to make a child element take up 100% of the remaining height of its parent container causes the child's height to go beyond the boundaries of the parent. HTML .container { height: 340px; /* background-i ...

Eliminating every row in a dynamic table except for the initial row

Is it possible to utilize jQuery to eliminate all rows from a dynamic table similar to the one below: HTML CODE: <table id="myTable" border="1"> <th style="width:100px;">Barangays</th> <th style="width:140px;">Lat</th&g ...

Struggling with properly locating a string within an array

I have been attempting to search an array for a specific string using a For loop, iterating through each index of the array based on its length. The expected behavior is that if the string is found, it should display that string (which in this scenario is ...

Black textures with images sourced from the same domain - Cross-origin

Despite trying numerous solutions and tips to resolve the cross-origin issue, I still can't seem to fix it. There are no errors, the images are hosted on the same domain as the webgl test, but the textures appear black. Occasionally when I refresh rep ...

Struggling to transfer information between POST and GET requests in Node/Express

Just diving into node/express, currently developing a weather application that receives location data from a form submission <form method="POST" action="/"> <input id="input" type="text" name="city" placeholder="Search by city or zip code" /> ...

Secure your messages with PHP encryption and decrypt them with JavaScript

I am looking for a way to encrypt a message using PHP and then decrypt it using JavaScript on the client side. I tried using Blowfish with mcrypt, but encountered an issue where PHP was outputting non-alphanumeric characters while JavaScript was only displ ...

Initializing a table with data will only function properly when a breakpoint is set

Using the bootstrap-table library, I initialize a table with data fetched via ajax request. var arr = []; var getRows = function () { $.ajax({ type: "GET", url: hostUrl, contentType: "app ...

How can I trigger a PHP function from within an HTML onClick() event?

While I have come across a response on stackoverflow regarding form submission, my query pertains to a different implementation. I am in need of calling a function that registers a variable in $_SESSION[], and then redirects to another page (html/php). I ...

A method for positioning each pair of <li> elements side by side

My goal is to arrange every pair of li elements next to each other (e.g. 0-9, A-B, C-D, ...). Currently, they are aligned one by one. <ul> <li class="alphabetRow"><a href="#" id="alpha_1" class="alphabet active" >0-9</a></li ...

Is it possible to utilize various providers in Next-Auth while still maintaining the same email address?

I am currently developing a Next.js application using NextAuth. At the moment, I have implemented login functionality with Google, credentials, and GitHub. However, I encountered an issue where if a user logs in with Google using the email "[email pro ...

Error: JSON key data not present in rendering

Here is a JSON string I am working with: {"{\"nodeName\":\"abc\"}":[{"url":"abc","status":true},{"url":"abc","status":true}]," {\"nodeName\":\"pqr\"}":[{"url":"abc","status":true},{"url":"abc","status":true}]} ...

What is the optimal number of parameters in JavaScript?

After stumbling upon a question on StackOverflow discussing the number of parameters in JavaScript functions (How many parameters are too many?), I started pondering if there is a real limitation on how many parameters a JS function can have. test(65536 ...

The Cross-Origin Resource Sharing request using the PUT method has been denied due to restrictions set by the

I am currently using CORS requests to communicate between my client and server located on different domains. I have configured my Apache HTTP server to use SSL in the following manner: // Utilizing AJAX withCredentials=true (sending cookies, allowing SSL ...

Here is a unique version: "A guide on centering a carousel item in jquery upon being clicked."

Does anyone know how to center the item I click in a carousel? I've searched high and low for a solution but couldn't find a clear answer. Can someone please assist me with this? This is what I have tried so far: http://jsfiddle.net/sp9Jv/ Here ...

Exploring the art of JSON interpretation within Highcharts

Below is an example snippet that utilizes static data: Highcharts.chart("container", { title: { text: "Highcharts pie chart" }, xAxis: { categories: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Ju ...