Assigning the style of the parent element based on the child element

Currently, I am attempting to develop a customized dropdown field and here is the code I have come up with:

const list = document.querySelector('.list');
const listItems = list.getElementsByTagName('p');

document.querySelector('#category').onclick = function() {
  // I can display the .list DOM element
  list.style.display = 'block';
}

Array.from(listItems)
  .forEach(function(listItem) {
    listItem.onclick = function() {

      // Struggling to hide the .list DOM element
      list.style.display = 'none';

      // The value of .listItem is being outputted
      console.log(listItem.getAttribute('value'));
    }
  }
);
<div class="dropdown" id="category" name="category">
  <div class="trigger">
    <p class="selected-category">Category</p>
  </div>
  <div class="list">
    <p value="">None</p>
    <p value="1">harum inventore</p>
    <p value="2">dolorem voluptatem</p>
    <p value="3">dolores consectetur</p>
    <p value="4">velit culpa</p>
    <p value="5">beatae nulla</p>
  </div>
</div>

My challenge lies in switching the display attribute of the list from block to none. Despite my efforts, this task seems unachievable even after attempting it from two different segments in the code.

Being relatively new to JavaScript prompts me to seek assistance. I believe I may have missed something crucial or taken an incorrect route, although I tried multiple remedies without success. Therefore, I apologize for any inconvenience caused in advance.

Answer №1

It seems like your code was functioning correctly, but the issue arose because both the parent and child elements had click event listeners attached to them. As a result, you were toggling the visibility of the list repeatedly.

If you're interested in learning more about event bubbling, check out this resource: https://javascript.info/bubbling-and-capturing

const list = document.querySelector('.list');
const listItems = list.getElementsByTagName('p');

// Overlapping event listener 1
document.querySelector('#category').onclick = function() {
  list.style.display = 'block';
}

Array.from(listItems)
  .forEach(function(listItem) {
    // Overlapping event listener 2
    listItem.onclick = function(event) {
      // To prevent the double event issue, stop it from bubbling up
      event.stopImmediatePropagation();
      list.style.display = 'none';
      console.log(listItem.getAttribute('data-value'));
    }
  }
);
<div class="dropdown" id="category" name="category">
  <div class="trigger">
    <p class="selected-category">Category</p>
  </div>
  <div class="list">
    <p data-value="">None</p>
    <p data-value="1">harum inventore</p>
    <p data-value="2">dolorem voluptatem</p>
    <p data-value="3">dolores consectetur</p>
    <p data-value="4">velit culpa</p>
    <p data-value="5">beatae nulla</p>
  </div>
</div>

Answer №2

Whenever you click on a child element of the parent #category, the event listener attached to the parent element is triggered. To stop the click event from propagating up to the parent, you can use the stopPropagation() method within the child elements' event listener.

Additionally, as noted by @connexo in the comments, <p> elements do not possess a value attribute. It seems like you may be referring to a <ul> element with <li> children instead.


To see an illustration of the above concept in action, review and execute the following Code Snippet:

const list = document.querySelector('.list');
  const listItems = document.querySelectorAll('.list li');

  document.querySelector('#category').onclick = function() {
    list.style.display = 'block';                     // Display the .list DOM element
  }

  Array.from(listItems)
    .forEach(function(listItem) {
      listItem.onclick = function(e) {
          e.stopPropagation(); // Prevents parent's event listener from being executed
        list.style.display = 'none';                  // Hide the .list DOM element
      }
    }
  );
  
.list {display: none; list-style: none;}
<div class="dropdown" id="category" name="category">
    <div class="trigger">
      <p class="selected-category">Category</p>
    </div>
    <ul class="list">
      <li>None</li>
      <li>harum inventore</li>
      <li>dolorem voluptatem</li>
      <li>dolores consectetur</li>
      <li>velit culpa</li>
      <li>beatae nulla</li>
    </ul>
  </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

Switch the dropdown selection depending on the checkbox status

I'm currently facing a bit of confusion with my project. I am constrained by an existing framework and need to come up with a workaround. To simplify, I am tasked with populating a dropdown list based on the selected checkboxes. I have managed to get ...

Struggling to align a div in the middle using react and tailwindcss

Struggling to center a div in React with Tailwind, no matter what method I try. Here is my code: "use client"; import Image from "next/image"; import React from "react"; const LoginPage = () => { return ( <div cla ...

Overruled fashion

Here is the HTML code from my custom page: <div class="notes quotes-notification member-savings f-left"> <h2>My Notifications</h2> <ul> <li><b>I need to make some changes in the HTML, different from other pages you have ...

Subclass Pseudoclass in JavaFX is a powerful feature that

I wanted to create two different styles of buttons in one css file. To achieve this, I added a class to the second button using: close.getStyleClass().add("close-button"); Now, I can reference this button in the css by: .button.close-button However, I ...

Learn how to efficiently redirect users without losing any valuable data after they sign up using localStorage

I am currently facing an issue with my sign up form. Whenever a user creates an account, I use localStorage to save the form values. However, if the user is redirected to another page after hitting the submit button, only the last user's data is saved ...

What is the best way to compare an attribute value with a JSON value in JavaScript?

I have a JSON string that looks like this: { "DocID": "NA2", "DocType": "Phase1.1 - Visa Documents (This section is applicable for HK work location only)", "DocSubType": "New Application", "DocName": "Passport / Travel Document (Soft copy only) ...

Issue encountered while deploying on vercel: TypeError - Trying to access properties of undefined (specifically 'and')

Encountered this issue during deployment on Vercel. Npm run build did not show any errors. Configuration : "node": "18", "next": "^14.0.0", "next-transpile-modules": "^9.1.0", An error occurred d ...

The unique behavior of nested observables within an Ionic2/Angular2 application

Creating an ionic login module involves using 2 observables, with one nested inside the other. Uncertainty exists regarding whether this is the correct implementation. The process includes calling the getHTTP() method to retrieve a string. If the string i ...

tips for converting a single observable item into an observable list

Within my Angular project, there exists an observable object with the following structure: export interface FavoritesResponse { wallet: boolean; deposit: boolean; withdraw: boolean; transfer: boolean; exchange: boolean; ticket: boolean; accou ...

Load the data from amp-list after triggering an event

I am currently exploring ways to load data on my second amp-list only after the first one has a selected value. Additionally, I am struggling to display a placeholder for the second amp-list. <div class="row"> <div class="col-sm-4 position-in ...

AngularJS - Struggling to retrieve value from ng-model in controller

Having trouble using Angular's ng-model to store and pass values with ng-click? If you're receiving undefined values in your current code, here's a possible solution. Check out the HTML snippet below: HTML <ion-content> <div c ...

Testing in Jasmine: Verifying if ngModelChange triggers the function or not

While running unit tests for my Angular app, I encountered an issue with spying on a function that is called upon ngModelChange. I am testing the logic inside this function but my test fails to spy on whether it has been called or not! component.spec.js ...

What could be the reason for the css problems being caused by my flash banner?

My flash banner ad is being displayed on a website as an advertisement at the bottom of the page. Whenever the banner ad is shown, the scroll bar disappears. The following CSS code appears when the flash banner is active: body {margin: 0; padding: 0; over ...

Colorful D3.js heatmap display

Hello, I am currently working on incorporating a color scale into my heat map using the d3.schemeRdYlBu color scheme. However, I am facing challenges in getting it to work properly as it only displays black at the moment. While I have also implemented a ...

The continuous resizing of the window is triggering a loop in flexslider when the resize function is called

I am currently working on a website that utilizes the flexslider plugin. My goal is to detect when the browser window is resized, and then reinitialize the slider so that it can adjust its size and other parameters accordingly. Initially, I was able to a ...

Discover the best practices for integrating media queries using Radium within Material UI components

Having trouble applying a breakpoint to the Material UI component, Raised button. I have managed to make it work for regular divs, but not for the Material UI component. I attempted wrapping the button inside Radium import RaisedButton from 'materia ...

It appears that when importing from a shared package in lerna, the name must include "src" at the end for Typescript or Javascript files

I am currently working on a straightforward lerna project structure as shown below: Project | +-- packages | | | +-- shared | | | | | +-- src | | | | | +-- index.ts | | +-- someDir | | | +-- usesShared | ...

Transferring values from jQuery AJAX to Node.js

Is there a way to successfully pass a variable from jQuery to nodejs without getting the [object Object] response? I want to ensure that nodejs can return a string variable instead. $('.test').click(function(){ var tsId = "Hello World"; ...

unable to retrieve the latest scope value following the completion of the ajax request

I attempted to use the code below, but despite searching for answers and solutions involving $apply and $timeout, nothing seemed to work in my case. I encountered several errors along the way. JS: var app = angular.module("test",[]) app.config(function($ ...

The issue of Jquery .click event handler failing to work for class selector specifically in CHROME

Is there a way to achieve the same opacity effect on click as on mouseover? I've tried various selectors without success. Any help on this issue would be greatly appreciated. Thank you in advance! .container { position: absolute; background:url(&a ...