Javascript Change Css Onclick and Chnage Back Again

Introduction to events

  • Previous
  • Overview: Building blocks
  • Adjacent

Events are deportment or occurrences that happen in the system you are programming, which the system tells you lot nigh and then your code tin can react to them.

For example, if the user clicks a push button on a webpage, you might want to react to that activeness by displaying an information box. In this article, we discuss some important concepts surrounding events, and look at how they piece of work in browsers. This won't be an exhaustive study; just what you need to know at this stage.

A serial of fortunate events

Every bit mentioned above, events are actions or occurrences that happen in the system you are programming — the system produces (or "fires") a signal of some kind when an event occurs, and provides a mechanism past which an action can exist automatically taken (that is, some lawmaking running) when the event occurs. For example, in an airdrome, when the rails is articulate for take off, a signal is communicated to the pilot. As a result, the plane can safely take off.

Image displaying signal for plane to take-off

In the instance of the Web, events are fired inside the browser window, and tend to be attached to a specific particular that resides in it. This might exist a single element, a set 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 case:

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

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

To react to an event, y'all attach an upshot handler to it. This is a block of code (usually a JavaScript role that you lot as a programmer create) that runs when the effect fires. When such a cake of code is defined to run in response to an event, we say we are registering an event handler. Annotation: Event handlers are sometimes called event listeners — they are pretty much interchangeable for our purposes, although strictly speaking, they piece of work together. The listener listens out for the effect happening, and the handler is the code that is run in response to information technology happening.

Note: Web events are non part of the core JavaScript language — they are defined as role of the APIs built into the browser.

A elementary example

Let'due south look at a simple instance of what we mean hither. In the following instance, nosotros have a unmarried <button>, which when pressed, makes the background change to a random color:

                                                                                    <button                      >                    Change color                                              </button                      >                                                      

The JavaScript looks like and then:

                                      const                    btn                    =                    document.                    querySelector                    (                    'button'                    )                    ;                    role                    random                    (                    number                    )                    {                    return                    Math.                    floor                    (Math.                    random                    (                    )                    *                    (number+                    i                    )                    )                    ;                    }                    btn.                    addEventListener                    (                    'click'                    ,                    (                    )                    =>                    {                    const                    rndCol                    =                                          `                      rgb(                                              ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            )                      `                                        ;                    document.body.way.backgroundColor                    =                    rndCol;                    }                    )                    ;                                  

In this code, we shop a reference to the <push> element inside a constant called btn, using the Document.querySelector() function.

We too ascertain 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 effect called 'click' that fires when the user clicks the push button. Objects that can fire events accept an addEventListener() method, that takes at least two arguments: the name of the event and a function to handle the event. Then we call the button's addEventListener() method, passing in:

  • the string 'click', to indicate that we want to listen to the click event
  • a function to call when the result happens. In our case the function generates a random RGB color and sets the page <body> groundwork-color equal to that colour.

The example output is as follows. Attempt clicking the push button:

It'southward non just web pages

Events are not unique to JavaScript — most programming languages have some kind of result model, and the way the model works often differs from JavaScript'due south way. In fact, the outcome model in JavaScript for web pages differs from the outcome model for JavaScript as it is used in other environments.

For case, Node.js is a very popular JavaScript runtime that enables developers to use JavaScript to build network and server-side applications. The Node.js upshot model relies on listeners to listen for events and emitters to emit events periodically — information technology doesn't sound that different, just the lawmaking is quite different, making use of functions like on() to annals an event listener, and in one case() to annals an upshot listener that unregisters after it has run once. The HTTP connect event docs provide a good instance.

You lot tin too use JavaScript to build cross-browser add together-ons — browser functionality enhancements — using a technology called WebExtensions. The event model is similar to the spider web events model, but a fleck different — event listeners' properties are camel-cased (such as onMessage rather than onmessage), and need to be combined with the addListener role. See the runtime.onMessage page for an example.

You lot don't need to empathize anything well-nigh other such environments at this stage in your learning; we merely wanted to make it clear that events can differ in different programming environments.

Using addEventListener()

The recommended machinery for calculation event handlers in web pages is the addEventListener() method:

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

Within the addEventListener() function, nosotros specify two parameters: the name of the event nosotros want to register this handler for, and the lawmaking that comprises the handler function nosotros want to run in response to information technology.

It is fine to brand the handler function a separate named part, similar this:

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

Listening for other events

There are many different events that can exist fired by a button element. Let'southward experiment.

Outset, make a local re-create of random-color-addeventlistener.html, and open up it in your browser. It's just a re-create of the uncomplicated random color example nosotros've played with already. At present endeavour irresolute click to the following different values in turn, and observing the results in the example:

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

Some events, such as click, are bachelor on nigh any element. Others are more than specific and but useful in certain situations: for instance, the play effect is only available on some elements, such every bit <video>.

Removing listeners

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

                  btn.                    removeEventListener                    (                    'click'                    ,                    changeBackground)                    ;                                  

Event handlers tin can also be removed past passing an AbortSignal to addEventListener() and then later calling abort() on the controller owning the AbortSignal. For example, to add an upshot handler that we can remove with an AbortSignal:

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

Then the event handler created by the code above tin exist removed similar this:

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

For simple, pocket-sized programs, cleaning up old, unused event handlers isn't necessary, only for larger, more complex programs, it tin can ameliorate efficiency. As well, the ability to remove event handlers allows you to take the same button performing different deportment in different circumstances: all yous take to do is add together or remove handlers.

Calculation multiple listeners for a single event

By making more than one phone call to addEventListener(), providing dissimilar handlers, y'all tin take multiple handlers for a single event:

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

Both functions would now run when the element is clicked.

Learn more

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

These are a picayune out of scope for this commodity, but if you desire to read them, visit the addEventListener() and removeEventListener() reference pages.

Other event listener mechanisms

We recommend that you use addEventListener() to register outcome handlers. It'south the most powerful method and scales best with more circuitous programs. However, in that location are two other ways of registering event handlers that you might see: event handler properties and inline issue handlers.

Event handler properties

Objects (such every bit buttons) that can burn down events also usually take properties whose name is on followed past the name of the consequence. For example, elements have a belongings onclick. This is chosen an event handler property. To heed for the event, you tin assign the handler function to the property.

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

                                      const                    btn                    =                    document.                    querySelector                    (                    'push'                    )                    ;                    function                    random                    (                    number                    )                    {                    return                    Math.                    flooring                    (Math.                    random                    (                    )                    *                    (number+                    1                    )                    )                    ;                    }                    btn.                    onclick                    =                    (                    )                    =>                    {                    const                    rndCol                    =                                          `                      rgb(                                              ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            )                      `                                        ;                    certificate.body.manner.backgroundColor                    =                    rndCol;                    }                                  

Y'all can also set the handler holding to a named office:

                                      const                    btn                    =                    certificate.                    querySelector                    (                    'push'                    )                    ;                    function                    random                    (                    number                    )                    {                    return                    Math.                    floor                    (Math.                    random                    (                    )                    *                    (number+                    1                    )                    )                    ;                    }                    function                    bgChange                    (                    )                    {                    const                    rndCol                    =                                          `                      rgb(                                              ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            )                      `                                        ;                    document.trunk.style.backgroundColor                    =                    rndCol;                    }                    btn.onclick                    =                    bgChange;                                  

With upshot handler properties, yous can't add more than one handler for a single event. For example, you lot 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 effect handler backdrop because any subsequent attempts to fix the belongings will overwrite earlier ones:

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

Inline event handlers — don't use these

Yous might also come across a blueprint similar this in your code:

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

The earliest method of registering event handlers found on the Spider web involved event handler HTML attributes (or inline upshot handlers) like the ane shown higher up — the attribute value is literally the JavaScript code yous desire to run when the event occurs. The higher up instance invokes a function divers within a <script> chemical element on the same page, but y'all could besides insert JavaScript directly within the attribute, for example:

                                                                                    <button                                              onclick                                                  =                          "                                                      alert                            (                            'Hello, this is my former-fashioned effect handler!'                            )                            ;                                                    "                                                                    >                    Press me                                              </push button                      >                                                      

Yous can find HTML attribute equivalents for many of the event handler properties; however, you shouldn't use these — they are considered bad practice. It might seem easy to apply an result handler aspect if y'all are doing something really quick, only they speedily become unmanageable and inefficient.

For a kickoff, it is not a practiced idea to mix upwardly your HTML and your JavaScript, as it becomes hard to read. Keeping your JavaScript separate is a expert exercise, and if it is in a separate file yous tin can utilize it to multiple HTML documents.

Even in a single file, inline event handlers are not a good idea. One push is OK, but what if yous had 100 buttons? You lot'd have to add together 100 attributes to the file; it would quickly turn into a maintenance nightmare. With JavaScript, you could hands add an event handler function to all the buttons on the page no thing how many there were, using something similar this:

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

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

Y'all should never use the HTML event handler attributes — those are outdated, and using them is bad practice.

Event objects

Sometimes, inside an event handler function, you lot'll encounter a parameter specified with a name such as consequence, evt, or e. This is called the event object, and it is automatically passed to result handlers to provide actress features and information. For example, allow's rewrite our random color example again slightly:

                                      const                    btn                    =                    certificate.                    querySelector                    (                    'button'                    )                    ;                    function                    random                    (                    number                    )                    {                    return                    Math.                    floor                    (Math.                    random                    (                    )                    *                    (number+                    one                    )                    )                    ;                    }                    function                    bgChange                    (                    e                    )                    {                    const                    rndCol                    =                                          `                      rgb(                                              ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            ,                                                                    ${                        random                        (                        255                        )                        }                                            )                      `                                        ;                    e.target.manner.backgroundColor                    =                    rndCol;                    panel.                    log                    (e)                    ;                    }                    btn.                    addEventListener                    (                    'click'                    ,                    bgChange)                    ;                                  

Hither y'all can meet we are including an upshot object, e, in the function, and in the function setting a groundwork color style on due east.target — which is the button itself. The target property of the event object is always a reference to the chemical element the event occurred upon. So, in this example, nosotros are setting a random groundwork color on the button, not the page.

Annotation: Run into the Event delegation section below for an case where we use outcome.target.

Annotation: You lot can employ whatever name you like for the effect object — you lot just need to choose a proper noun that you can then apply to reference it inside the event handler office.

e/evt/consequence are most commonly used by developers because they are curt and piece of cake to call up. Information technology'south ever skillful to be consequent — with yourself, and with others if possible.

Virtually event objects have a standard set of properties and methods bachelor on the event object; see the Event object reference for a total listing.

Some upshot objects add together extra properties that are relevant to that particular type of result. For instance, the keydown outcome fires when the user presses a fundamental. Its issue object is a KeyboardEvent, which is a specialized Consequence object with a key property that tells you which key was pressed:

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

Try typing into the text box and see the output:

Preventing default behavior

Sometimes, you'll come across a situation where y'all want to preclude an event from doing what it does past default. The well-nigh common instance is that of a web form, for example, a custom registration class. When you fill in the details and click the submit button, the natural behavior is for the data to be submitted to a specified page on the server for processing, and the browser to exist redirected to a "success message" page of some kind (or the same page, if some other is not specified.)

The trouble comes when the user has not submitted the data correctly — as a developer, you want to prevent the submission to the server and give an mistake message saying what's wrong and what needs to be washed to put things right. Some browsers support automatic form data validation features, but since many don't, you are advised to non rely on those and implement your ain validation checks. Let'south look at a simple example.

Showtime, a simple HTML course that requires you to enter your outset and last proper noun:

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

Now some JavaScript — here we implement a very simple cheque inside a handler for the submit event (the submit issue is fired on a form when it 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 then brandish an error message in the paragraph below our class to tell the user what'southward wrong:

                                      const                    form                    =                    document.                    querySelector                    (                    'form'                    )                    ;                    const                    fname                    =                    document.                    getElementById                    (                    'fname'                    )                    ;                    const                    lname                    =                    document.                    getElementById                    (                    'lname'                    )                    ;                    const                    para                    =                    certificate.                    querySelector                    (                    'p'                    )                    ;                    form.                    addEventListener                    (                    'submit'                    ,                    eastward                    =>                    {                    if                    (fname.value                    ===                    ''                    ||                    lname.value                    ===                    ''                    )                    {                    east.                    preventDefault                    (                    )                    ;                    para.textContent                    =                    'Yous need to fill in both names!'                    ;                    }                    }                    )                    ;                                  

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

Effect bubbling and capture

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

Setting a listener on a parent chemical element

Consider a web folio like this:

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

Here the button is within another element, a <div> element. Nosotros say that the <div> element here is the parent of the element it contains. What happens if we add a click effect handler to the parent, then click the push button?

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

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

Yous clicked on a DIV element              

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

Bubbling example

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

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

Let'due south attempt adding click result handlers to the button, its parent (the <div>), and the <torso> element that contains both of them:

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

You'll run across that all 3 elements fire a click event when the user clicks the push:

You clicked on a Push button chemical element You clicked on a DIV element You clicked on a Body element              

In this case:

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

We draw this by maxim that the consequence bubbling up from the innermost element that was clicked.

This beliefs can be useful and can as well crusade unexpected problems. In the side by side section we'll see a problem that information technology causes, and discover the solution.

Video role player example

Open the prove-video-box.html example in a new tab (and the source code in another tab.) Information technology is too available live below:

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

                                                                                    <button                      >                    Brandish video                                              </button                      >                                                                                      <div                      class                                              =                        "hidden"                                            >                                                                                      <video                      >                                                                                      <source                      src                                              =                        "https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.mp4"                                            type                                              =                        "video/mp4"                                            >                                                                                      <source                      src                                              =                        "https://raw.githubusercontent.com/mdn/learning-expanse/master/javascript/edifice-blocks/events/rabbit320.webm"                                            type                                              =                        "video/webm"                                            >                                                                                      <p                      >                    Your browser doesn't support HTML5 video. Hither 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 class attribute on the <div> from hidden to showing (the example'southward CSS contains these two classes, which position the box off the screen and on the screen, respectively):

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

Nosotros then add together a couple more click consequence handlers — the first one to the <div> and the second one to the <video>:

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

Now, when the expanse of the <div> exterior the video is clicked, the box should exist hidden again and when the video itself is clicked, the video should showtime to play.

Simply there's a problem — currently, when yous click the video it starts to play, simply it causes the <div> to be hidden at the same time. This is because the video is within the <div> — it is part of information technology — so clicking the video actually runs both the above result handlers.

Bubbling and capturing explained

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

In the capturing phase:

  • The browser checks to see if the element'due south outer-most ancestor (<html>) has a click event handler registered on it for the capturing phase, and runs it if and so.
  • And so it moves on to the side by side element within <html> and does the same matter, so the next one, then on until information technology reaches the direct parent of the element that was actually clicked.

In the target stage:

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

In the bubbling phase, the exact contrary of the capturing phase occurs:

  • The browser checks to see if the directly parent of the clicked element has a click result handler registered on it for the bubbling stage, and runs it if so.
  • Then it moves on to the next immediate ancestor element and does the same thing, and then the next one, and so on until it reaches the <html> element.

In modern browsers, past default, all event handlers are registered for the bubbling phase. So in our current example, when y'all click the video, the upshot bubbles from the <video> element outwards to the <html> element. Along the fashion:

  • It finds the click handler on the video element and runs it, and then the video beginning starts playing.
  • Information technology then finds the click handler on the videoBox chemical element and runs that, so the video is subconscious besides.

Note: All JavaScript events go through the capturing and target phases. Whether an issue enters the bubbles stage can exist checked by the read-only bubbles belongings.

Annotation: Event listeners registered for the <html> element aren't at the pinnacle of hierarchy. For case, event listeners registered for the window and document objects are higher in the hierarchy.

The following example demonstrates the beliefs described above. Hover over the numbers and click on them to trigger events, and and so find the output that gets logged.

Case code: event phases

                                                                                    <div                      >                    one                                                                  <div                      >                    ii                                                                  <div                      >                    3                                                                  <div                      >                    4                                                                  <div                      >                    five                                              </div                      >                                                                                      </div                      >                                                                                      </div                      >                                                                                      </div                      >                                                                                      </div                      >                                                                                      <button                      id                                              =                        "articulate"                                            >                    articulate output                                              </push button                      >                                                                                      <section                      id                                              =                        "log"                                            >                                                                                      </section                      >                                                      
                                      p                    {                    line-height                    :                    0;                    }                    div                    {                    display                    :                    inline-block;                    padding                    :                    5px;                    background                    :                    #fff;                    border                    :                    1px solid #aaa;                    cursor                    :                    arrow;                    }                    div:hover                    {                    border                    :                    1px solid #faa;                    groundwork                    :                    #fdd;                    }                                  
                                      /*  * source i: 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                    =                    certificate.                    getElementById                    (                    'log'                    )                    ;                    function                    log                    (                    msg                    )                    {                    logElement.innerHTML                    +=                    (                                          `                      <p>                                              ${msg}                                            </p>                      `                                        )                    ;                    }                    office                    stage                    (                    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,                    imitation                    )                    ;                    window.                    addEventListener                    (                    'click'                    ,                    gphase,                    truthful                    )                    ;                    window.                    addEventListener                    (                    'click'                    ,                    gphase,                    false                    )                    ;                    const                    clearButton                    =                    document.                    getElementById                    (                    'articulate'                    )                    ;                    clearButton.                    addEventListener                    (                    'click'                    ,                    clearOutput)                    ;                                  

Fixing the trouble with stopPropagation()

As we saw in the video instance, this can be a very abrasive behavior, but in that location is a way to prevent it! The standard Issue object has a role bachelor on it called stopPropagation() which, when invoked on a handler'south event object, makes it and then that the first handler is run but the event doesn't chimera any further up the chain, then no more handlers will be run.

And so we tin fix our current problem by changing the second handler function in the previous lawmaking block to this:

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

You can endeavor making a local copy of the testify-video-box.html source code and fixing it yourself, or looking at the stock-still result in show-video-box-fixed.html (too see the source code hither).

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

Note: Equally mentioned to a higher place, past default all event handlers are registered in the bubbling stage, and this makes more sense about of the time. If you really desire to annals an result in the capturing phase instead, you tin can do so by registering your handler using addEventListener(), and setting the optional tertiary property to true.

Issue delegation

Outcome bubbles isn't simply annoying though: it tin be very useful. In detail it enables a practise chosen issue delegation. In this practice, when we 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 upwardly to their parent rather than having to gear up the event listener on every child individually.

Permit's go dorsum to our kickoff instance, where we ready the background colour of the whole page when the user clicked a button. Suppose that instead, the page is divided into sixteen tiles, and we desire to fix each tile to a random colour when the user clicks that tile.

Here'southward the HTML:

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

We 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 together a click event handler for every tile. But a much simpler and more efficient option is to set up the click result handler on the parent, and rely on event 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                        )                        }                                            )                      `                                        ;                    render                    rndCol;                    }                    const                    container                    =                    document.                    querySelector                    (                    '#container'                    )                    ;                    container.                    addEventListener                    (                    'click'                    ,                    effect                    =>                    issue.target.fashion.backgroundColor                    =                    bgChange                    (                    )                    )                    ;                                  

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

Note: In this example we're using event.target to get the element that was the target of the outcome (that is, the innermost chemical element). If nosotros wanted to access the element that handled this event (in this instance the container) we could utilise result.currentTarget.

Test your skills!

You've reached the end of this commodity, but can yous remember the most important information? To verify you've retained this information before you move on — see Test your skills: Events.

Conclusion

You should now know all you need to know about web events at this early stage. Every bit mentioned, events are not really part of the cadre JavaScript — they are defined in browser Web APIs.

Also, it is of import to sympathize that the unlike contexts in which JavaScript is used accept dissimilar event models — from Web APIs to other areas such every bit browser WebExtensions and Node.js (server-side JavaScript). We are not expecting y'all to understand all of these areas now, but information technology certainly helps to understand the basics of events as y'all forge ahead with learning web evolution.

If there is annihilation you didn't sympathize, feel free to read through the article again, or contact united states of america to enquire for help.

See also

  • domevents.dev — a very useful interactive playground app that enables learning about the behavior of the DOM Issue organization through exploration.
  • Event reference
  • Outcome lodge (discussion of capturing and bubbles) — an excellently detailed piece past Peter-Paul Koch.
  • Event accessing (give-and-take of the event object) — another excellently detailed slice past Peter-Paul Koch.
  • Previous
  • Overview: Building blocks
  • Adjacent

In this module

fralickthowithid.blogspot.com

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

0 Response to "Javascript Change Css Onclick and Chnage Back Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel