Event listener added for a specific class, with certain individuals within the class not impacted

I've created a grid to serve as a menu, with a top row consisting of an unordered list (ul) containing three list items (li). Each of these li elements contains another ul with four li items inside. I've added an event listener that triggers when the inner li elements with the "inner" class are clicked.
The code can be viewed at this link: http://jsfiddle.net/jimeast123/qK2Ju/2/ Clicking on the first two columns (make sure not to click on the text itself) results in the expected alert message, but clicking on the third column doesn't trigger any response. I've experimented with different numbers of columns and found that the last column never responds.

Here's my code: html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>drop down</title>
    <style>
    body {
        margin: 0;
        padding: 0;
    }
    header {
        height: 120px;
        background-color: #eef;
    }
    .top {
        background-color: #fee;
    }
    .top li {
        display: inline-block;
        width: 5.5em;
        height: 1.5em;
        border: 1px solid black;
        text-align: center;
    }
    li {
        list-style: none;
    }
    .inner {
        margin-left: -2.55em;
        display:block;
    }
    li a {
        text-decoration: none;
    }
    .inner li {
        display: block;
        text-align: center;
        background-color: #efe;
    }
    </style>

</head>
<body>
<!-- heading>h1+nav>ul.top>li*5>(a[href=#]>{menu$})>ul.inner>li*4>a[href=#]>{menu$} -->
<header>
    <nav>
        <header>
    <nav>
        <ul class="top">
            <li><a href="#">menuA</a>
                <ul class="inner" id="one">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
                </ul>
            </li>
            <li><a href="#">menuB</a>
                <ul class="inner" id="two">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
                </ul>
            </li>
            <li><a href="#">menuE</a>
                <ul class="inner" id="five">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
                </ul>
            </li>
        </ul>
    </nav>
</header>
    </nav>
</header>
<script src="dropdown.js"></script>
</body>
</html>

JavaScript:

if (document.body.addEventListener) {
    document.body.addEventListener('click', theHandler, false);
} else {
    document.body.attachEvent('onclick', theHandler); //for IE
}

function theHandler(e){
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (target.className.match(/inner/)) {
        //console.log("inner class was clicked");
        alert("inner class was clicked");
    }
}

Answer №1

It's not possible for the user to directly click on the .inner elements because clicking on them actually triggers the child objects within the .inner elements. This means you won't be able to target them using that class alone.

There are a couple of options available. If your HTML is static and not generated dynamically with JavaScript, you can directly attach event listeners to all .inner elements. The normal click event propagation will then trigger these events even when child nodes are clicked.

Alternatively, if you prefer to keep the event handler at the body level, you can use a workaround by checking if any parent in the hierarchy contains the specified class (as the target might be nested several levels deep within .inner).

function hasClass(elem, cls) {
    var str = " " + elem.className + " ";
    var testCls = " " + cls + " ";
    return(str.indexOf(testCls) != -1) ;
}

function isTargetInClass(target, cls) {
    while (target && target !== document.body) {
        if (hasClass(target, cls)) {
            return true;
        }
        target = target.parentNode;
    }
    return false;
}

function theHandler(e){
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (isTargetInClass(target, "inner")) {
        //console.log("inner class was clicked");
        alert("inner class was clicked");
    }
}

Answer №2

In my opinion, the issue lies in adding the event listener to the body element, which may not target the desired element (for example, this could explain why clicking on the text does not yield the expected result). To address this, consider replacing your current code with the following jQuery solution:

$('.inner').click(function() {
    alert('inner was clicked');
});

By implementing the above code, you will effectively attach the click handler to all elements containing the class inner.

Additionally, I recommend utilizing "Inspect Element" to verify whether the click events are occurring at the expected locations.

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

A class member is not permitted to include the 'const' keyword

Having trouble with my ts code as I try to create a constant that can be easily changed by just modifying a simple element - but keep encountering the error that says "A class member cannot have the 'const' keyword." Here's the code snippet ...

Perfect CSS Menu Hover Effect

I created my own navigation menu, and I'm struggling with one thing... How do I change the A tag color to white when hovering over the ul id "navitemul"? I've tried #lovedating#navitemul:hover #lovedating a {color:white} and other methods, but no ...

Adjusting the cell size to align with the height of another cell in the same row

Within a table row, I have two cells that contain divs and the height varies due to changing content. Is there a way for one cell to take up 100% height to match the other cell? You can see an example here. The goal is for the second cell and its div to ...

Creating sparse fieldset URL query parameters using JavaScript

Is there a way to send type-related parameters in a sparse fieldset format? I need help constructing the URL below: const page = { limit: 0, offset:10, type: { name: 's', age:'n' } } I attempted to convert the above ...

Incorporating JavaScript into a pre-existing HTML and CSS user interface

After successfully coding a chat app UI for my project site using CSS and HTML, I am now facing the challenge of adding functionality to my existing code. The issue is setting up the client server and integrating chatting functions into my current UI. Mo ...

Issues with NativeScript WebView displaying HTML file

Having trouble loading a local HTML file into a webview in my NativeScript (typescript) application. Despite using the correct path, it's not loading and instead shows an error. <WebView src="~/assets/content.html" /> An error message stati ...

Starting the download of the canvas featuring a stylish border design

I'm facing an issue where the canvas border is not showing up when I download the canvas with a border. The border appears on the screen, but it doesn't get included in the downloaded canvas. let canvas=qrRef.current.querySelector("canvas&qu ...

How to target the following sibling element (not a child) with CSS

I am working with the following HTML structure: <div class="col-sm-12"> <input id="my_id"> <div class="col-sm-1 col-3-box" style="position:absolute; margin-left:340px;"> </div> </div> How can I target and change ...

An issue has been identified where a single image is not displaying properly on Android devices, as well as IE7 and

Hey there! I recently created a Wordpress site and it seems that the Art Below logo isn't appearing in IE7, IE8, and Android for some reason. Would anyone be willing to help troubleshoot this issue? If you have fresh eyes, please take a look at the f ...

Guide: Transform Bootstrap 4 Inline Checkboxes into Stacked Format When Screen Size Is Altered

The new layout of checkboxes and radio buttons in Bootstrap 4 really caught my attention. However, I am looking for a way to switch between "stack" and "inline" based on the screen size. Although size tagging has been added for various elements, I haven&ap ...

Ways to merge various input values

I need help combining input values in my code. Below is the code I have so far: getCodeBoxElement(index) { return document.getElementById("codeBox" + index); } onKeyUpEvent(index, event) { const eventCode = event.which || event.keyCode; console.lo ...

After deploying on Vercel, Next.js' getServerSideProps function is returning undefined

I am trying to create a Netflix-inspired website using next.js. I am able to fetch movie data from TMDB using getServerSideProps(). While everything works as expected in development mode, once deployed on Vercel (re-deployed multiple times), the props I re ...

Tips for adding a cache to a basic website

After completing the development of a frontend website that includes several images, I am concerned about potential slower load times. I have not yet tackled backend coding tasks and am now looking to implement a caching system on the frontend. Are there ...

What could be the reason for the `controller.$render` method not being triggered as intended?

Check out this code snippet on plnkr.co. Within the link function of the directive, calling controller.$render() was successful. However, when attempting to override the controller.$render function, it does not execute as expected. The statement console.lo ...

What is the best method for inserting a specific value into a tuple that exists within another tuple within Python using Django?

My dictionary for Categories consists of tuples within a tuple, but I am looking to extract only the literals - the category names. from django.db import models CATEGORIES = ( ('a', 'Clothing'), ('b&ap ...

Is it possible to determine if the clipboard is accessible in Firefox?

In my upcoming JavaScript project, I am looking to determine the accessibility of the clipboard. Particularly in Firefox where specific permissions need to be granted for each site in order to use certain functions like execCommand with cut, copy or past ...

Storing the output of asynchronous promises in an array using async/await technique

I am currently working on a script to tally elements in a JSON file. However, I am encountering difficulty in saving the results of promises into an array. Below is the async function responsible for counting the elements: async function countItems(direct ...

What is the process for implementing conditions in React?

if ((newFile.type != "image/gif" ) || (newFile.type !=="image/jpg") || (newFile.type !=="image/png") (newFile.type !=="image/jpeg")) { setFileErr(true) } else if((newFile.type == "image/gif") || (newF ...

How to create a WordPress sidebar that remains fixed while scrolling

I have a WordPress website with a right sidebar that I want to make sticky while scrolling up and down. I applied some CSS styles to achieve this, and now the sidebar is sticky. However, the issue is that it keeps shifting its position from right to left. ...

What steps can I take to guarantee that the observer receives the latest value immediately upon subscribing?

In my Angular 2 and Typescript project, I am utilizing rxjs. The goal is to share a common web-resource (referred to as a "project" in the app) among multiple components. To achieve this, I implemented a service that provides an observable to be shared by ...