Onclick Event How to Capture Clicking Button Again to Do Another Action

Introduction to events

  • Previous
  • Overview: Building blocks
  • Next

Events are deportment or occurrences that happen in the organisation y'all are programming, which the arrangement tells you about so your code tin react to them.

For example, if the user clicks a push on a webpage, you might want to react to that activeness past displaying an information box. In this article, we discuss some important concepts surrounding events, and wait at how they work in browsers. This won't exist an exhaustive report; just what y'all need to know at this stage.

A series of fortunate events

Every bit mentioned above, events are actions or occurrences that happen in the system yous are programming — the organisation produces (or "fires") a bespeak of some kind when an upshot occurs, and provides a mechanism by which an action can be automatically taken (that is, some lawmaking running) when the event occurs. For example, in an airport, when the runway is articulate for take off, a signal is communicated to the pilot. Equally a result, the aeroplane tin safely take off.

Image displaying signal for plane to take-off

In the example of the Web, events are fired within the browser window, and tend to exist fastened to a specific detail that resides in information technology. This might be a single element, a gear up of elements, the HTML document loaded in the current tab, or the entire browser window. There are many different types of events that can occur.

For example:

  • The user selects a certain element or hovers the cursor over a certain element.
  • The user chooses a key on the keyboard.
  • The user resizes or closes the browser window.
  • A web page finishes loading.
  • A form is submitted.
  • A video is played, paused, or finishes.
  • An error occurs.

You can get together from this (and from glancing at the MDN event reference) that there are a lot of events that can be fired.

To react to an event, yous attach an event handler to it. This is a block of code (commonly a JavaScript function that yous equally a programmer create) that runs when the event fires. When such a block of code is defined to run in response to an event, we say we are registering an event handler. Note: Event handlers are sometimes called outcome listeners — they are pretty much interchangeable for our purposes, although strictly speaking, they piece of work together. The listener listens out for the event happening, and the handler is the lawmaking that is run in response to it happening.

Notation: Web events are non function of the cadre JavaScript linguistic communication — they are defined as part of the APIs built into the browser.

A uncomplicated example

Let's expect at a simple example of what we hateful here. In the following example, nosotros have a single <push>, which when pressed, makes the background change to a random color:

                                                                            <push                    >                  Change color                                          </button                    >                                                

The JavaScript looks like so:

                                  const                  btn                  =                  document.                  querySelector                  (                  'button'                  )                  ;                  part                  random                  (                  number                  )                  {                  return                  Math.                  floor                  (Math.                  random                  (                  )                  *                  (number+                  1                  )                  )                  ;                  }                  btn.                  addEventListener                  (                  'click'                  ,                  (                  )                  =>                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  document.torso.style.backgroundColor                  =                  rndCol;                  }                  )                  ;                              

In this code, we store a reference to the <button> chemical element inside a constant called btn, using the Document.querySelector() part.

We also define a office that returns a random number.

The third part of the code is where we define and register the event handler. The <push> element has an consequence called 'click' that fires when the user clicks the button. Objects that can fire events accept an addEventListener() method, that takes at least 2 arguments: the name of the event and a function to handle the event. So we call the button's addEventListener() method, passing in:

  • the string 'click', to indicate that nosotros desire to listen to the click effect
  • a function to call when the event happens. In our case the function generates a random RGB color and sets the page <body> background-color equal to that color.

The example output is equally follows. Attempt clicking the button:

Information technology's not simply web pages

Events are non unique to JavaScript — most programming languages take some kind of event model, and the manner the model works often differs from JavaScript's way. In fact, the event model in JavaScript for spider web pages differs from the upshot model for JavaScript as it is used in other environments.

For instance, Node.js is a very popular JavaScript runtime that enables developers to employ JavaScript to build network and server-side applications. The Node.js result model relies on listeners to listen for events and emitters to emit events periodically — information technology doesn't audio that different, only the code is quite different, making use of functions like on() to register an result listener, and once() to register an event listener that unregisters later it has run one time. The HTTP connect issue docs provide a skillful example.

You can besides utilise JavaScript to build cross-browser add-ons — browser functionality enhancements — using a applied science called WebExtensions. The event model is similar to the spider web events model, but a bit different — event listeners properties are camel-cased (such every bit onMessage rather than onmessage), and need to exist combined with the addListener function. See the runtime.onMessage page for an example.

Yous don't need to empathise anything well-nigh other such environments at this phase in your learning; we merely wanted to make it clear that events can differ in unlike programming environments.

Using addEventListener()

The recommended mechanism for adding event handlers in web pages is the addEventListener() method:

                                  const                  btn                  =                  document.                  querySelector                  (                  'button'                  )                  ;                  office                  random                  (                  number                  )                  {                  return                  Math.                  flooring                  (Math.                  random                  (                  )                  *                  (number+                  one                  )                  )                  ;                  }                  btn.                  addEventListener                  (                  'click'                  ,                  (                  )                  =>                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  document.body.manner.backgroundColor                  =                  rndCol;                  }                  )                  ;                              

Inside the addEventListener() function, we specify two parameters: the proper name of the upshot nosotros want to register this handler for, and the code that comprises the handler function we desire to run in response to it.

It is fine to make the handler function a separate named part, like this:

                                  const                  btn                  =                  certificate.                  querySelector                  (                  'button'                  )                  ;                  part                  random                  (                  number                  )                  {                  return                  Math.                  floor                  (Math.                  random                  (                  )                  *                  (number+                  1                  )                  )                  ;                  }                  role                  changeBackground                  (                  )                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  document.body.fashion.backgroundColor                  =                  rndCol;                  }                  btn.                  addEventListener                  (                  'click'                  ,                  changeBackground)                  ;                              

Listening for other events

There are many unlike events that tin can be fired by a button element. Allow's experiment.

First, make a local copy of random-color-addeventlistener.html, and open it in your browser. Information technology's just a copy of the simple random colour example we've played with already. Now attempt changing click to the following unlike values in turn, and observing the results in the instance:

  • focus and blur — The color changes when the push button is focused and unfocused; try pressing the tab to focus on the button and printing the tab once more to focus abroad from the button. These are often used to display data about filling in form fields when they are focused, or displaying an error bulletin if a form field is filled with an incorrect value.
  • dblclick — The color changes only when the button is double-clicked.
  • mouseover and mouseout — The color changes when the mouse pointer hovers over the push button, or when the pointer moves off the button, respectively.

Some events, such as click, are bachelor on nearly any chemical element. Others are more specific and only useful in certain situations: for case, the play upshot is only available on some elements, such as <video>.

Removing listeners

If yous've added an event handler using addEventListener(), yous can remove it once more using the removeEventListener() method. For example, this would remove the changeBackground() event handler:

                btn.                  removeEventListener                  (                  'click'                  ,                  changeBackground)                  ;                              

Issue handlers can also exist removed by passing an AbortSignal to addEventListener() and and then later calling arrest() on the controller owning the AbortSignal. For example, to add together an event handler that we can remove with an AbortSignal:

                                  const                  controller                  =                  new                  AbortController                  (                  )                  ;                  btn.                  addEventListener                  (                  'click'                  ,                  (                  )                  =>                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  certificate.torso.style.backgroundColor                  =                  rndCol;                  }                  ,                  {                  signal                  :                  controller.signal                  }                  )                  ;                  // pass an AbortSignal to this handler                              

Then the event handler created by the code above can be removed like this:

                controller.                  abort                  (                  )                  ;                  // removes whatsoever/all result handlers associated with this controller                              

For uncomplicated, small programs, cleaning upward old, unused event handlers isn't necessary, but for larger, more than complex programs, it can amend efficiency. Besides, the power to remove event handlers allows you to have the same button performing unlike actions in different circumstances: all you have to do is add or remove handlers.

Adding multiple listeners for a single result

By making more i telephone call to addEventListener(), providing different handlers, y'all tin have multiple handlers for a single event:

                myElement.                  addEventListener                  (                  'click'                  ,                  functionA)                  ;                  myElement.                  addEventListener                  (                  'click'                  ,                  functionB)                  ;                              

Both functions would at present run when the element is clicked.

Larn more

At that place are other powerful features and options bachelor with addEventListener().

These are a little out of telescopic for this article, but if you want to read them, visit the addEventListener() and removeEventListener() reference pages.

Other effect listener mechanisms

We recommend that you use addEventListener() to register event handlers. It'south the most powerful method and scales best with more circuitous programs. However, there are 2 other ways of registering upshot handlers that y'all might run across: event handler properties and inline event handlers.

Event handler properties

Objects (such as buttons) that can fire events also usually have properties whose name is on followed by the name of the effect. For example, elements accept a property onclick. This is called an event handler property. To heed for the event, you tin assign the handler part to the property.

For example, we could rewrite the random-color example like this:

                                  const                  btn                  =                  document.                  querySelector                  (                  'button'                  )                  ;                  function                  random                  (                  number                  )                  {                  return                  Math.                  floor                  (Math.                  random                  (                  )                  *                  (number+                  ane                  )                  )                  ;                  }                  btn.                  onclick                  =                  (                  )                  =>                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  certificate.body.way.backgroundColor                  =                  rndCol;                  }                              

You can too set the handler property to a named function:

                                  const                  btn                  =                  document.                  querySelector                  (                  'button'                  )                  ;                  office                  random                  (                  number                  )                  {                  render                  Math.                  floor                  (Math.                  random                  (                  )                  *                  (number+                  1                  )                  )                  ;                  }                  office                  bgChange                  (                  )                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  document.body.style.backgroundColor                  =                  rndCol;                  }                  btn.onclick                  =                  bgChange;                              

With event handler properties, you lot tin can't add more than ane handler for a single upshot. For example, you can call addEventListener('click', handler) on an element multiple times, with different functions specified in the second argument:

                element.                  addEventListener                  (                  'click'                  ,                  function1)                  ;                  element.                  addEventListener                  (                  'click'                  ,                  function2)                  ;                              

This is impossible with event handler backdrop considering any subsequent attempts to set the property volition overwrite earlier ones:

                element.onclick                  =                  function1;                  element.onclick                  =                  function2;                              

Inline event handlers — don't use these

Yous might also meet a pattern like this in your lawmaking:

                                                                            <button                                          onclick                                              =                        "                                                  bgChange                          (                          )                                                "                                                              >                  Press me                                          </push button                    >                                                
                                  function                  bgChange                  (                  )                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  document.body.style.backgroundColor                  =                  rndCol;                  }                              

The primeval method of registering event handlers establish on the Spider web involved event handler HTML attributes (or inline result handlers) like the i shown above — the attribute value is literally the JavaScript lawmaking you want to run when the upshot occurs. The above example invokes a office defined inside a <script> chemical element on the same page, but you lot could also insert JavaScript direct inside the attribute, for example:

                                                                            <button                                          onclick                                              =                        "                                                  alert                          (                          'Hi, this is my sometime-fashioned event handler!'                          )                          ;                                                "                                                              >                  Press me                                          </button                    >                                                

You tin find HTML attribute equivalents for many of the event handler backdrop; still, you shouldn't use these — they are considered bad practise. It might seem easy to employ an issue handler attribute if y'all are doing something really quick, just they quickly become unmanageable and inefficient.

For a get-go, it is not a good idea to mix up your HTML and your JavaScript, as it becomes difficult to read. Keeping your JavaScript separate is a good do, and if it is in a separate file you tin can apply it to multiple HTML documents.

Even in a single file, inline event handlers are not a good idea. 1 push button is OK, but what if you lot had 100 buttons? You'd have to add 100 attributes to the file; information technology would quickly plow into a maintenance nightmare. With JavaScript, y'all could easily add an event handler part to all the buttons on the page no matter how many there were, using something like this:

                                  const                  buttons                  =                  document.                  querySelectorAll                  (                  'button'                  )                  ;                  for                  (                  const                  button                  of                  buttons)                  {                  push.                  addEventListener                  (                  'click'                  ,                  bgChange)                  ;                  }                              

Finally, many common server configurations will disallow inline JavaScript, as a security measure.

You should never use the HTML upshot handler attributes — those are outdated, and using them is bad practice.

Event objects

Sometimes, inside an issue handler role, you'll see a parameter specified with a proper noun such as event, evt, or e. This is called the event object, and information technology is automatically passed to issue handlers to provide actress features and information. For example, let'south rewrite our random color example again slightly:

                                  const                  btn                  =                  document.                  querySelector                  (                  'push button'                  )                  ;                  function                  random                  (                  number                  )                  {                  render                  Math.                  flooring                  (Math.                  random                  (                  )                  *                  (number+                  one                  )                  )                  ;                  }                  function                  bgChange                  (                  e                  )                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  e.target.style.backgroundColor                  =                  rndCol;                  console.                  log                  (due east)                  ;                  }                  btn.                  addEventListener                  (                  'click'                  ,                  bgChange)                  ;                              

Here y'all can see nosotros are including an consequence object, e, in the office, and in the office setting a background colour style on e.target — which is the push button itself. The target belongings of the outcome object is always a reference to the element the event occurred upon. So, in this example, we are setting a random background color on the push, not the page.

Note: Run into the Event delegation section beneath for an case where we utilise issue.target.

Notation: You lot tin use whatever name you lot like for the event object — you just demand to choose a name that you tin then apply to reference it inside the event handler function.

due east/evt/result are most commonly used past developers because they are brusque and easy to remember. Information technology's always adept to be consistent — with yourself, and with others if possible.

Most event objects accept a standard fix of properties and methods available on the event object; see the Event object reference for a full list.

Some outcome objects add extra properties that are relevant to that particular type of upshot. For example, the keydown event fires when the user presses a fundamental. Its event object is a KeyboardEvent, which is a specialized Event object with a key property that tells yous which cardinal was pressed:

                                                                            <input                    id                                          =                      "textBox"                                        type                                          =                      "text"                                        >                                                                              </input                    >                                                                              <div                    id                                          =                      "output"                                        >                                                                              </div                    >                                                
                                  const                  textBox                  =                  certificate.                  querySelector                  (                  "#textBox"                  )                  ;                  const                  output                  =                  certificate.                  querySelector                  (                  "#output"                  )                  ;                  textBox.                  addEventListener                  (                  'keydown'                  ,                  event                  =>                  output.textContent                  =                                      `                    You pressed "                                          ${event.cardinal}                                        ".                    `                                    )                  ;                              

Attempt typing into the text box and meet the output:

Preventing default behavior

Sometimes, y'all'll come across a situation where you want to forestall an event from doing what it does past default. The most mutual example is that of a web form, for example, a custom registration course. When yous fill in the details and select the submit button, the natural behavior is for the data to exist submitted to a specified page on the server for processing, and the browser to be redirected to a "success message" folio of some kind (or the same page, if another is not specified.)

The trouble comes when the user has not submitted the data correctly — every bit a developer, yous want to preclude the submission to the server and give an fault bulletin proverb what'south wrong and what needs to be done to put things right. Some browsers back up automatic form information validation features, simply since many don't, y'all are advised to not rely on those and implement your own validation checks. Let'due south look at a simple example.

Start, a simple HTML course that requires y'all to enter your offset and last name:

                                                                            <form                    >                                                                              <div                    >                                                                              <label                    for                                          =                      "fname"                                        >                  First name:                                                            </label                    >                                                                              <input                    id                                          =                      "fname"                                        blazon                                          =                      "text"                                        >                                                                              </div                    >                                                                              <div                    >                                                                              <label                    for                                          =                      "lname"                                        >                  Last name:                                                            </label                    >                                                                              <input                    id                                          =                      "lname"                                        type                                          =                      "text"                                        >                                                                              </div                    >                                                                              <div                    >                                                                              <input                    id                                          =                      "submit"                                        blazon                                          =                      "submit"                                        >                                                                              </div                    >                                                                              </form                    >                                                                              <p                    >                                                                              </p                    >                                                

Now some JavaScript — here we implement a very elementary check inside a handler for the submit consequence (the submit event is fired on a form when information technology is submitted) that tests whether the text fields are empty. If they are, we call the preventDefault() function on the event object — which stops the form submission — and and so display an error message in the paragraph below our grade to tell the user what's wrong:

                                  const                  class                  =                  document.                  querySelector                  (                  'form'                  )                  ;                  const                  fname                  =                  document.                  getElementById                  (                  'fname'                  )                  ;                  const                  lname                  =                  document.                  getElementById                  (                  'lname'                  )                  ;                  const                  para                  =                  certificate.                  querySelector                  (                  'p'                  )                  ;                  course.                  addEventListener                  (                  'submit'                  ,                  due east                  =>                  {                  if                  (fname.value                  ===                  ''                  ||                  lname.value                  ===                  ''                  )                  {                  e.                  preventDefault                  (                  )                  ;                  para.textContent                  =                  'You demand to fill in both names!'                  ;                  }                  }                  )                  ;                              

Obviously, this is pretty weak form validation — information technology wouldn't stop the user validating the class with spaces or numbers entered into the fields, for example — but it is OK for example purposes. The output is equally follows:

Event bubbling and capture

Event bubbling and capture are terms that describe phases in how the browser handles events targeted at nested elements.

Setting a listener on a parent chemical element

Consider a spider web page like this:

                                                                            <div                    id                                          =                      "container"                                        >                                                                              <push button                    >                  Click me!                                          </push button                    >                                                                              </div                    >                                                                              <pre                    id                                          =                      "output"                                        >                                                                              </pre                    >                                                

Hither the button is within some other element, a <div> element. We say that the <div> element hither is the parent of the element information technology contains. What happens if we add together a click upshot handler to the parent, then click the push?

                                  const                  output                  =                  document.                  querySelector                  (                  '#output'                  )                  ;                  function                  handleClick                  (                  eastward                  )                  {                  output.textContent                  +=                                      `                    You lot clicked on a                                                              ${due east.currentTarget.tagName}                                                              element\n                    `                                    ;                  }                  const                  container                  =                  document.                  querySelector                  (                  '#container'                  )                  ;                  container.                  addEventListener                  (                  'click'                  ,                  handleClick)                  ;                              

You'll see that the parent fires a click result when the user clicks the button:

Yous clicked on a DIV element            

This makes sense: the button is inside the <div>, so when you lot click the push you lot're also implicitly clicking the element it is inside.

Bubbling example

What happens if nosotros add result listeners to the button and the parent?

                                                                            <trunk                    >                                                                              <div                    id                                          =                      "container"                                        >                                                                              <push                    >                  Click me!                                          </button                    >                                                                              </div                    >                                                                              <pre                    id                                          =                      "output"                                        >                                                                              </pre                    >                                                                              </torso                    >                                                

Let'southward try adding click effect handlers to the push, its parent (the <div>), and the <body> element that contains both of them:

                                  const                  output                  =                  certificate.                  querySelector                  (                  '#output'                  )                  ;                  function                  handleClick                  (                  e                  )                  {                  output.textContent                  +=                                      `                    You clicked on a                                                              ${e.currentTarget.tagName}                                                              element\n                    `                                    ;                  }                  const                  container                  =                  document.                  querySelector                  (                  '#container'                  )                  ;                  const                  button                  =                  document.                  querySelector                  (                  'push button'                  )                  ;                  certificate.trunk.                  addEventListener                  (                  'click'                  ,                  handleClick)                  ;                  container.                  addEventListener                  (                  'click'                  ,                  handleClick)                  ;                  button.                  addEventListener                  (                  'click'                  ,                  handleClick)                  ;                              

You'll see that all three elements fire a click event when the user clicks the push:

You clicked on a BUTTON element Yous clicked on a DIV element You clicked on a Body chemical element            

In this example:

  • the click on the button fires first
  • followed past the click on its parent (the <div> chemical element)
  • followed by the <div> element'south parent (the <body> element).

We describe this by saying that the event bubbles upwards from the innermost chemical element that was clicked.

This beliefs tin can exist useful and can also cause unexpected problems. In the next department we'll see a problem that information technology causes, and notice the solution.

Video player case

Open up up the prove-video-box.html example in a new tab (and the source code in another tab.) Information technology is also bachelor live beneath:

This example shows and hides a <div> with a <video> chemical element inside information technology:

                                                                            <push button                    >                  Display video                                          </button                    >                                                                              <div                    form                                          =                      "hidden"                                        >                                                                              <video                    >                                                                              <source                    src                                          =                      "https://raw.githubusercontent.com/mdn/learning-area/master/javascript/edifice-blocks/events/rabbit320.mp4"                                        type                                          =                      "video/mp4"                                        >                                                                              <source                    src                                          =                      "https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.webm"                                        type                                          =                      "video/webm"                                        >                                                                              <p                    >                  Your browser doesn't back up HTML5 video. Here is a                                                            <a                    href                                          =                      "rabbit320.mp4"                                        >                  link to the video                                          </a                    >                                    instead.                                          </p                    >                                                                              </video                    >                                                                              </div                    >                                                

When the <button> is clicked, the video is displayed, by changing the form attribute on the <div> from hidden to showing (the example's CSS contains these ii classes, which position the box off the screen and on the screen, respectively):

                                  const                  btn                  =                  document.                  querySelector                  (                  'push button'                  )                  ;                  const                  videoBox                  =                  document.                  querySelector                  (                  'div'                  )                  ;                  function                  displayVideo                  (                  )                  {                  if                  (videoBox.                  getAttribute                  (                  'class'                  )                  ===                  'hidden'                  )                  {                  videoBox.                  setAttribute                  (                  'class'                  ,                  'showing'                  )                  ;                  }                  }                  btn.                  addEventListener                  (                  'click'                  ,                  displayVideo)                  ;                              

We so add together a couple more click event handlers — the first i to the <div> and the second one to the <video>:

                videoBox.                  addEventListener                  (                  'click'                  ,                  (                  )                  =>                  videoBox.                  setAttribute                  (                  'class'                  ,                  'hidden'                  )                  )                  ;                  const                  video                  =                  certificate.                  querySelector                  (                  'video'                  )                  ;                  video.                  addEventListener                  (                  'click'                  ,                  (                  )                  =>                  video.                  play                  (                  )                  )                  ;                              

Now, when the area of the <div> outside the video is selected, the box should be hidden again and when the video itself is selected, the video should start to play.

Just there's a problem — currently, when you select the video it starts to play, merely it causes the <div> to be hidden at the same fourth dimension. This is because the video is within the <div> — information technology is part of it — then selecting the video actually runs both the to a higher place event handlers.

Bubbles and capturing explained

When an upshot is fired on an element that has parent elements (in this case, the <video> has the <div> as a parent), modern browsers run three different phases — the capturing phase, the target phase, and the bubbling phase.

In the capturing phase:

  • The browser checks to meet if the chemical element'south outer-most ancestor (<html>) has a click outcome handler registered on information technology for the capturing phase, and runs it if so.
  • Then information technology moves on to the side by side element inside <html> and does the aforementioned thing, then the next ane, and then on until it reaches the straight parent of the chemical element that was actually selected.

In the target phase:

  • The browser checks to see if the target property has an event handler for the click event registered on information technology, and runs it if and so.
  • Then, if bubbles is true, information technology propagates the event to the straight parent of the selected chemical element, then the next i, and so on until it reaches the <html> chemical element. Otherwise, if bubbling is faux, it doesn't propagate the consequence to any ancestors of the target.

In the bubbling stage, the verbal opposite of the capturing phase occurs:

  • The browser checks to meet if the direct parent of the element selected has a click upshot handler registered on it for the bubbling phase, and runs it if so.
  • Then it moves on to the side by side firsthand ancestor element and does the same affair, and so the side by side ane, and then on until it reaches the <html> element.

In modern browsers, by default, all event handlers are registered for the bubbling phase. So in our electric current case, when you select the video, the event bubbles from the <video> chemical element outwards to the <html> element. Forth the mode:

  • It finds the click handler on the video element and runs it, so the video commencement starts playing.
  • Information technology then finds the click handler on the videoBox element and runs that, and then the video is hidden every bit well.

Note: All JavaScript events go through the capturing and target phases. Whether an effect enters the bubbling phase can be checked by the read-only bubbles holding.

Note: Event listeners registered for the <html> element aren't at the top of hierarchy. For example, event listeners registered for the window and certificate objects are higher in the hierarchy.

The following example demonstrates the behavior described higher up. Hover over the numbers and click on them to trigger events, and so observe the output that gets logged.

Example code: effect phases

                                                                            <div                    >                  1                                                            <div                    >                  2                                                            <div                    >                  3                                                            <div                    >                  4                                                            <div                    >                  v                                          </div                    >                                                                              </div                    >                                                                              </div                    >                                                                              </div                    >                                                                              </div                    >                                                                              <push                    id                                          =                      "clear"                                        >                  clear output                                          </button                    >                                                                              <section                    id                                          =                      "log"                                        >                                                                              </section                    >                                                
                                  p                  {                  line-height                  :                  0;                  }                  div                  {                  display                  :                  inline-block;                  padding                  :                  5px;                  groundwork                  :                  #fff;                  edge                  :                  1px solid #aaa;                  cursor                  :                  pointer;                  }                  div:hover                  {                  edge                  :                  1px solid #faa;                  groundwork                  :                  #fdd;                  }                              
                                  /*  * source 1: https://dom.spec.whatwg.org/#dom-effect-eventphase  * source 2: https://stackoverflow.com/a/4616720/15266715 */                  const                  evtPhasestr                  =                  [                  "NONE: "                  ,                  "CAPTURING_PHASE: "                  ,                  "AT_TARGET: "                  ,                  "BUBBLING_PHASE: "                  ]                  ;                  const                  logElement                  =                  document.                  getElementById                  (                  'log'                  )                  ;                  function                  log                  (                  msg                  )                  {                  logElement.innerHTML                  +=                  (                                      `                    <p>                                          ${msg}                                        </p>                    `                                    )                  ;                  }                  office                  phase                  (                  evt                  )                  {                  log                  (evtPhasestr[evt.eventPhase]                  +                  this                  .firstChild.nodeValue.                  trim                  (                  )                  )                  ;                  }                  function                  gphase                  (                  evt                  )                  {                  log                  (evtPhasestr[evt.eventPhase]                  +                  evt.currentTarget.                  toString                  (                  )                  .                  slice                  (                  8                  ,                  -                  1                  )                  )                  ;                  }                  function                  clearOutput                  (                  evt                  )                  {                  evt.                  stopPropagation                  (                  )                  ;                  logElement.innerHTML                  =                  ''                  ;                  }                  const                  divs                  =                  document.                  getElementsByTagName                  (                  'div'                  )                  ;                  for                  (                  const                  div                  of                  divs)                  {                  div.                  addEventListener                  (                  'click'                  ,                  phase,                  true                  )                  ;                  div.                  addEventListener                  (                  'click'                  ,                  phase,                  false                  )                  ;                  }                  document.                  addEventListener                  (                  'click'                  ,                  gphase,                  true                  )                  ;                  certificate.                  addEventListener                  (                  'click'                  ,                  gphase,                  false                  )                  ;                  window.                  addEventListener                  (                  'click'                  ,                  gphase,                  true                  )                  ;                  window.                  addEventListener                  (                  'click'                  ,                  gphase,                  false                  )                  ;                  const                  clearButton                  =                  certificate.                  getElementById                  (                  'clear'                  )                  ;                  clearButton.                  addEventListener                  (                  'click'                  ,                  clearOutput)                  ;                              

Fixing the trouble with stopPropagation()

As we saw in the video instance, this can exist a very annoying behavior, but there is a way to prevent it! The standard Result object has a function available on it chosen stopPropagation() which, when invoked on a handler's outcome object, makes information technology so that first handler is run but the event doesn't bubble any further up the chain, so no more than handlers will be run.

Then we tin can fix our current problem by changing the 2d handler function in the previous lawmaking block to this:

                video.                  addEventListener                  (                  'click'                  ,                  eastward                  =>                  {                  e.                  stopPropagation                  (                  )                  ;                  video.                  play                  (                  )                  ;                  }                  )                  ;                              

You tin try making a local re-create of the testify-video-box.html source code and fixing it yourself, or looking at the fixed event in show-video-box-fixed.html (also see the source code here).

Notation: Why carp with both capturing and bubbling? Well, in the bad old days when browsers were much less cross-compatible than they are now, Netscape merely used event capturing, and Internet Explorer used only event bubbling. When the W3C decided to endeavour to standardize the beliefs and reach a consensus, they concluded upwardly with this system that included both, which is the one modern browsers implemented.

Annotation: As mentioned higher up, by default all event handlers are registered in the bubbles stage, and this makes more sense most of the time. If yous really want to register an upshot in the capturing phase instead, you can do so by registering your handler using addEventListener(), and setting the optional third property to true.

Event delegation

Upshot bubbles isn't merely abrasive though: information technology can exist very useful. In item it enables a practise called result delegation. In this exercise, when nosotros want some lawmaking to run when the user interacts with any one of a large number of child elements, we set the event listener on their parent and have events that happen on them bubble up to their parent rather than having to set the event listener on every child individually.

Allow'south become back to our first example, where we fix the background color of the whole page when the user clicked a button. Suppose that instead, the folio is divided into 16 tiles, and we want to set each tile to a random color when the user clicks that tile.

Here'southward the HTML:

                                                                            <div                    id                                          =                      "container"                                        >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    form                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    course                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    course                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    course                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    course                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    class                                          =                      "tile"                                        >                                                                              </div                    >                                                                              <div                    grade                                          =                      "tile"                                        >                                                                              </div                    >                                                                              </div                    >                                                

Nosotros have a little CSS, to set up the size and position of the tiles:

                                  .tile                  {                  height                  :                  100px;                  width                  :                  25%;                  float                  :                  left;                  }                              

Now in the JavaScript, we could add a click event handler for every tile. But a much simpler and more efficient option is to set the click event handler on the parent, and rely on consequence bubbling to ensure that the handler is executed when the user clicks on a tile:

                                  function                  random                  (                  number                  )                  {                  return                  Math.                  floor                  (Math.                  random                  (                  )                  *number)                  ;                  }                  function                  bgChange                  (                  )                  {                  const                  rndCol                  =                                      `                    rgb(                                          ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        ,                                                              ${                      random                      (                      255                      )                      }                                        )                    `                                    ;                  return                  rndCol;                  }                  const                  container                  =                  document.                  querySelector                  (                  '#container'                  )                  ;                  container.                  addEventListener                  (                  'click'                  ,                  upshot                  =>                  event.target.fashion.backgroundColor                  =                  bgChange                  (                  )                  )                  ;                              

The output is every bit follows (try clicking around on information technology):

Note: In this case we're using event.target to go the element that was the target of the event (that is, the innermost element). If we wanted to access the element that fired this event (in this example the container) we could utilize effect.currentTarget.

Test your skills!

You've reached the end of this article, but can y'all retrieve the virtually important data? To verify you lot've retained this information before yous move on — run across Test your skills: Events.

Conclusion

You should now know all y'all need to know most web events at this early stage. As mentioned, events are not really part of the core JavaScript — they are defined in browser Web APIs.

Likewise, information technology is of import to understand that the unlike contexts in which JavaScript is used take dissimilar event models — from Web APIs to other areas such as browser WebExtensions and Node.js (server-side JavaScript). Nosotros are not expecting you to empathize all of these areas now, only it certainly helps to understand the basics of events as you forge ahead with learning spider web development.

If there is annihilation you didn't empathize, feel complimentary to read through the commodity once more, or contact us to inquire for help.

See also

In this module

  • Making decisions in your code — conditionals
  • Looping code
  • Functions — reusable blocks of code
  • Build your ain function
  • Function return values
  • Introduction to events
  • Image gallery

smithpurry1980.blogspot.com

Source: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events

0 Response to "Onclick Event How to Capture Clicking Button Again to Do Another Action"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel