简体   繁体   中英

on.Click event not firing on a simple code

The click event fires with 'addEventListener'. The script is placed after all the code inside the body tag. What is that I am missing

Fiddle link - https://jsfiddle.net/3280bw2L/3/

<body>
        <nav>
            <div class="container"><a class="logo">Timer</a>
            <div class="icon"><a href="" id="bar" type="button"><i class="fas fa-bars"></i></a></div>
                    <ul class="menu" id="menu">
                        <li><a href="">Home</a></li>
                        <li><a href="">About</a></li>
                        <li><a href="">Services</a></li>
                        <li><a href="">Pages</a></li>
                        <li><a href="">Contact</a></li>
                    </ul>
            </div>
        </nav>
    <script type="text/javascript" src="JS/script.js"></script>
    </body>
    </html>

    var x = document.getElementById("bar");
    var y = document.getElementById("menu");

    document.getElementById("bar").onClick = function (){
        alert("working");
    }

    x.addEventListener("click", function() {
        alert("works");
    });

There is no text inside the a that you've attached the listener to, so there's nothing on the page that the user could click on that would result in a click event being dispatched to that a . Another problem is that its container, the .icon , has display: none , so it couldn't be clicked on anyway.

Remove the display: none , and put some text inside the a . (you'll also want to preventDefault to prevent redirection)

https://jsfiddle.net/3280bw2L/11/

 var x = document.getElementById("bar"); var y = document.getElementById("menu"); document.querySelector("#bar").onclick = function (e){ alert("working"); e.preventDefault(); } 
 /*Navbar*/ .container{ margin: 0 7% 0 7% } .icon{ float: right; color: #444473; } nav{ width: 100%; background: white; height: 60px; padding-top: 30px; box-shadow: 2px 2px 4px rgba(0, 0, 0, .050); } nav .logo{ display: inline-block; font-family: 'Gloria Hallelujah', cursive; font-size: 2em; color: #10C0D6; } .menu{ display: inline-block; float: right; } .menu li{ list-style: none; display: inline-block; margin-right: 20px; } .menu li a{ text-decoration: none; color: #444473; text-transform: uppercase; font-family: roboto; font-weight: 500; font-size: 0.9em; } /*Media queries*/ @media only screen and (max-width: 768px){ .menu{ display: none; } .icon{ display: block; } .menu.responsive{ display: block; width: 100%; } } 
  <nav> <div class="container"><a class="logo">Timer</a> <div class="icon"><a href="" id="bar" type="button"><i class="fas fa-bars">text</i></a></div> <ul class="menu" id="menu"> <li><a href="">Home</a></li> <li><a href="">About</a></li> <li><a href="">Services</a></li> <li><a href="">Pages</a></li> <li><a href="">Contact</a></li> </ul> </div> </nav> 

You should be adding an event listener to your element to make it work for click events

document.getElementById("bar").addEventListener('click',function (){
    alert("working");
});

You were close. I couldn't get your JSFiddle to run correctly, so I setup a quick Codepen (link: https://codepen.io/DaneTheory/pen/XEwpwe ). Feel free to refer to it for a look at the working example of the code posted below along with additional comments.

First, Here's your code after a bit of refactoring to help better exlain what's going on:

HTML

<body>
  <nav>
    <div class="container">
      <a class="logo">Timer</a>
      <div class="icon">
        <a href="#" id="bar" type="button" onclick="foobar()">
          <i class="fas fa-bars"></i>
        </a>
    </div>

    <ul class="menu" id="menu">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Services</a></li>
      <li><a href="#">Pages</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </div>
</nav>

JavaScript

var Demo = function() {
  var x = document.getElementById("bar")
  x.addEventListener("click", function() {
    console.log('Exmaple 1: Function Expression')
  })
}

Demo()


// foobar() will run as expected while the code block below it is 
// commented out. Uncomment the click event snippet and see foobar() no 
// longer is called. Instead, precendence is given to the global 
// .onclick event handler.

function foobar() {
  console.log('Example 2: Inline function')
}

// document.getElementById("bar").onclick = function(event) {  
//    console.log('Example 3: Global Click Event Handler')
// }

Solution/Explanation

The quick answer, your .onClick function was written incorrectly. Changing it to .onclick resolves your issue and fires the click event as expected.

However, it's important to understand more than just proper syntax when dealing with events in JavaScript. Without over complicating things and for the sake of brevity, there are three common approaches taken to defining click events in JavaScript.

  1. Defining the click event within a function expression , other wise known as a closure . This provides a clean, easily reusable means by which to encapsulate code.

     var Demo = function() { var x = document.getElementById("bar") x.addEventListener("click", function() { console.log('Exmaple 1: Function Expression') }) } 

The code snippet above demonstrates one way to go about encapsulating your click event within a function expression. To run the function expression, simply invoke the method as you would any other function:

Demo()  

I mention this methodology first, only to demonstrate different approach to structuring your codebase. This more functional approach is not anything new, and is a cornerstone "best practice". It's simpler to debug issues like you ran into having your code cleanly separated. It's always very easy to continue scaling your code base using this methodology versus the more inline approach you originally took.

  1. Defining the click event as an inline function . This is similar to your original approach with a few caveats and can be demonstrated by adding onclick="foobar()" directly within the HTML (hence the name inline function ) of your Button Icon. The inline function declared in the HTML will fire a function with the corresponding name. So, adding onclick="foobar()" to your Button Icon, then writing the following:

     function foobar() { console.log('Example 2: Inline function') } 

Will produce a correctly executed click event from which to work with. The downside to this approach is having your JS methods declared directly within your HTML.

  1. Defining the click event using native Global Event Handler API syntax. This example most closely matches your original attempt. Here's the code for a quick ref:

     document.getElementById("bar").onclick = function(event) { console.log('Example 3: Global Click Event Handler') } 

.onclick is a native event handler, and as such takes precedence in order of execution. Using this approach, as demonstrated in the provided codepen, while execute first before the inline function discussed in example 2. It will also keep the inline function mentioned in example 2 from ever firing at all. Using native Web API's in your codebase is more often than not a good choice, seeing as they are events native to the browser itself. For more detail, checkout: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick
Notice, however, in the Codepen how our function expression example still gets invoked regardless of the Web API's event order precedence. This demonstrates another reason why using a more modular approach in your codebase is a good idea.

As a final note, anytime you intend to use HREF's that don't have a corresponding URL always provide a # rather than a blank space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM