JavaScript onclick event and three ways to handle events. Using event handlers


The topic of the events is very important and very interesting. Thanks to it, you can do a lot of interesting things that the user will be delighted with. An event in JavaScript is a specific action that is triggered either by the user or the browser. For example, an event could be a mouse click on a button, mouse movement, focusing on an element, changing a value in a text field, resizing a browser window, and so on.

I have prepared a table with all the events (that I know at least) in JavaScript. In it you will find, firstly, the name of the event, elements that can generate this event and a description of the JavaScript event itself.

EventAn objectCause of occurrence
AbortionImageInterrupting image loading
BlurLost element focus
ChangeFileUpload, Select, Text, TextareaChange value
ClickArea, Button, Checkbox, Document, Link, Radio, Reset, SubmitMouse click on an element
DblClickArea, Document, LinkDouble click on an element
DragDropWindowMove to browser window
FocusButton, Checkbox, FileUpload, Frame, Layer, Password, Radio, Reset, Select, Submit, Text, Textarea, WindowSetting focus on an element
KeyDownPressing a key on the keyboard
KeyPressDocument, Image, Link, TextareaHolding a key on the keyboard
KeyUpDocument, Image, Link, TextareaReleasing a key on the keyboard
LoadDocument, Image, Layer, Window
MouseDownButton, Document, LinkMouse button pressed
MouseMoveWindowMouse in motion
MouseOutArea, Layer, LinkThe mouse goes beyond the borders of the element
MouseOverArea, Layer, LinkThe mouse is over the element
MouseUpButton, Document, LinkMouse button released
MoveFrameMoving an element
ResetFormReset form
ResizeFrame, WindowResizing
SelectText, TextareaText selection
SubmitFormData transfer
UnloadWindowUnloading the current page

Now let's figure out how to use events in JavaScript. There are so-called event handlers. Event handlers determine what will happen when a certain event occurs. Event handlers in JavaScript have the following general form:

OnEventName

That is, first comes the prefix “on”, and then the name of the event, for example, the following event handlers: onFocus, onClick, onSubmit, and so on. I think there are no questions here. And now the main question: “How to use events in JavaScript?”. The scope of their application is huge, and now we will look at one problem. There are three links on the page. Each of the links is responsible for a different background color (for example, white, yellow and green). At first the background is white. When you hover your mouse over a specific link, the background color changes. When you move the mouse away, the background color returns to the default color. When you click on a link, the background color is retained as the default.




a (
color:blue;
text-decoration: underline;
cursor: pointer;
}


var default_color = "white";

function setTempColor(color) (
document.bgColor = color;
}

function setDefaultColor(color) (
default_color = color;
}

function defaultColor() (
document.bgColor = default_color;
}



White
Yellow
Green

Let's look at this script, or rather the entire HTML page with JavaScript support and CSS (in other words, this is an example of DHTML). First come the usual HTML tags, with which any HTML page begins. Next, we create a style in which we require that all links on a given page be blue, underlined, and that the mouse pointer on them be in the form of a "Pointer". You may say: “Why do you need to set a style? After all, the links will be exactly the same.” That’s right, links, but we don’t have links as such (after all, there is no href attribute in the tag), so they will be simple black text by default (however, you can also click on the text). Therefore, style is a must. You can remove it and see what happens. Better yet, add the href attribute (with any value, even empty) and explain why the script stopped working. Then JavaScript begins. We create a variable default_color responsible for the default color. Next come three functions:

The setTempColor() function is responsible for temporarily changing the color.

The setDefaultColor() function is responsible for changing the default color.

The defaultColor() function sets the default background color.

Then there are links with attributes in the form of event handlers. When you hover the mouse over a link, the MouseOver event occurs; accordingly, the onMouseOver event handler calls the setTempColor() function and passes the corresponding parameter. When you remove the mouse from an element, the MouseOut event is raised, and then the defaultColor() function is called, which sets the background color to the default color. And finally, when the mouse clicks on the link (onClick handler), the setDefaultColor() function is called, which sets the color specified in the parameter to the default background color. As you can see, everything is quite simple.

This was the principle of using events in JavaScript, and then everything depends only on your imagination!

One of the most important features of the JavaScript language, which is perhaps the main one in this language, is the ability to process some events. This feature is unique to JavaScript compared to other languages ​​from web programming, because only this language has the power to do something like this.

What is an event and event handlers

An event is an action that can be performed either by the user or other objects on the page.

The most striking example of an event is the user clicking on some object( click), be it a button, link or any other element. Another example of an event is hovering the mouse over some object( mouseover), say above the image. Also the event is the complete loading of the page( load). In general, all actions that occur on the site are events.

So, we can capture any event that occurs on the page and process it using the appropriate handler. For example, when you hover your mouse over something div block, we can display a message, say “You are in text area". Or, when you click on a button, hide some block from the page. In general, a lot of things can be done before processing some event.

And in order to process some event, you need to use a special handler for of this event. Each event has its own handler, for example, the click event ( click) there is a handler onclick. The event of mouse over an object( mouseover) there is a handler onmouseover. And the page full load event( load) there is a handler onload.

That is, as you understand, the name of the handler is formed from the prefix “on” + the name of the event.

A complete list of events and handlers can be found in the reference book; in this article we will consider only those that are most often used.

The event handler is called as an attribute, in the tag itself HTML element. You can immediately write JavaScript code into the handler value, but it is better to call some function that will do necessary actions. The function must be described inside a script tag, which can be located either inside the head block or at the end of the body tag. The word this, that is, the current object, is passed as a parameter to this function.

Now let's write a simple example. When you hover the mouse over a block with text, we will display a message using the alert method indicating that the user is inside the text area.

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.

Div( padding-left: 50px; width: 200px; border: 1px solid #000; )

JavaScript code:

Function blockOver(block)( alert("You are in the text area "); )

We save the document, open it in the browser, hover the mouse cursor over the text and see the result of processing this event:


How to get the value of an attribute in javascript?

Using the function parameter (this), you can get the value of some attribute of the current object, for example, find out its id.

For example, let's create a button and give it an id with the value "justButton". When we click on this button, then we will display the following message: “You clicked on the button with the identifier value_id.” Here you need to already use the onclick handler.

JavaScript code:

Function clickOnButton(button)( alert("You clicked on a button with identifier: " + button.id); )

Save the document, open it in the browser and click on the button.


In the same way you can display the name of the button( button.name) or its value( button.value)

Getting the width and height of an element

You can also find out the meanings CSS properties element, such as width and height. The clientWidth and offsetWidth properties are used to get the width, and the clientHeight and offsetHeight properties are used to get the height. For example, let's display the width and height of the button that was clicked.

Now the contents of the clickOnButton function will be like this:

Function clickOnButton(button)( //alert("You clicked on a button with ID: " + button.id); var width = button.clientWidth || button.offsetWidth; var height = button.clientHeight || button.offsetHeight; alert("Button width: " + width + "\nButton height: " + height); )

The result of this example:


Let me remind you that the width of the element is calculated together with the padding value, so it is equal to 111px [ 99px(width) + 6px(padding-left) + 6px(padding-right) ].

If you don’t need to write a lot of code to process an event, you can write this code directly into the handler value. That is, instead of calling a function, we immediately write the necessary code.

For example, when a page loads, you can display a message that "page is loading." To do this, you need to use the load event and its onload handler. We will write this handler in the opening body tag.

This method can only be used if only one short line of code is needed to process the event. Otherwise, if the processing code consists of one long line or many lines, then you need to use a function.

And at the end of this article, we’ll look at a simple example of form processing. Processing the form in JavaScript, firstly, reduces the load on the server and, secondly, gives an additional advantage to the usability of the site.

The form consists of one login field and a submit button. When submitting the form, we will check the login length. Its length should be more than three characters.

Let's start with the HTML structure of this form.

Now, let’s add an onsubmit handler for the submit event as an attribute to the form tag. In the following way:

The submit event fires when the form is submitted. We wrote the return statement to prevent the form from being submitted if an error is detected in the data entry. If the function returns false, then the value of the onsubmit handler will be “return false”, which means that the form will not be sent to the server. Otherwise, if the form returns true, then the value of the handler will be “return true” and the form will be submitted without problems.

Sometimes it is necessary to completely disable form submission, in which case the value of the onsubmit handler will be like this:

Onsubmit = "checkForm(this); return false;"

As you probably already guessed, checkForm is the name of the function that will be called when the submit event fires. You can call it whatever you want, following the function naming conventions.

And so, let's return to our example. Now we need to describe the checkForm function. It will contain the following condition: if the login length less than three characters, then we return false and the form will not be sent, otherwise, if the data was entered correctly, then we send the form to the server.

Function checkForm(form)( //Get the value of the form field whose name is login var login = form.login.value; //Check if the login length is less than three characters, then display an error message and cancel submitting the form. if(login .length > 3)( alert("Login length must be more than three characters"); return false; )else( return true; ) )

We save the document, open it in the browser and test it.


This is how you can check the form for: JavaScript and cancel its sending in case of an error.

Well, that’s all, dear readers. Let's summarize.
Events are used very often, so you must be able to work with them 100%.

In this article you learned what an event and an event handler are. You learned how to get element attribute values ​​and how to find the width and height of an element. You also learned how to perform form validation.

Tasks
  • Create a simple number adding calculator.
    • Create a form with two numeric fields (type="number") for entering numbers and a button labeled "Add"
    • When you click the submit button, call the function for processing this event.
    • Inside the function, get the field values ​​and using the alert method, display the result of adding the entered numbers.
    • Make sure that the form is not submitted after clicking the button.
  • Last update: 11/1/2015

    Built-in handlers

    In the previous topic we looked at built-in event handlers, which are defined in the element code using attributes:

    Although this approach works great, it has a bunch of disadvantages:

      HTML code is mixed with JavaScript code, making the application more difficult to develop, debug, and maintain

      Event handlers can only be set for elements already created on the web page. Dynamically created elements in this case are deprived of the ability to process events

      Only one handler can be attached to an element for one event

      You can't remove a handler without changing the code

    Event Handler Properties

    The problems that arise when using built-in handlers were designed to be solved by the properties of the handlers. Just as html elements have attributes for handlers, in javascript code for DOM elements we can get handler properties that correspond to attributes:

    function handler(e)( alert(e.type); ) document.getElementById("rect").onclick = handler;

    As a result, we just need to take the onclick property and assign it a function that is used as a handler. Due to this, the html code is separated from the javascript code.

    It is also worth noting that the browser automatically passes an Event object to the event handler, which stores all the information about the event. Therefore, we can also receive this object in the handler function as a parameter.

    Event Listeners

    While handler properties solve a number of problems associated with using attributes, they are also not the optimal approach. Another way to set up event handlers is to use listeners.

    To work with event listeners, JavaScript has an EventTarget object, which defines the addEventListener() (to add a listener) and removeEventListener() methods to remove a listener. And since html DOM elements are also EventTarget objects, they also have these methods. In fact, listeners represent the same functions as handlers.

    The addEventListener() method takes two parameters: the name of the event without the on prefix and the handler function for this event. For example:

    #rect( width:50px; height:50px; background-color:blue; ) var rect = document.getElementById("rect"); rect.addEventListener("click", function (e) ( alert(e.type); ));

    That is, in in this case again being processed click event. And it would also be possible to use the name of the function as the second parameter:

    Function handler(e)( alert(e.type); ) var rect = document.getElementById("rect"); rect.addEventListener("click", handler);

    Removing a listener is similar to adding:

    Rect.removeEventListener("click", handler);

    The advantage of using listeners is that we can set several functions for one event:

    Var clicks = 0; function handlerOne(e)( alert(e.type); ) function handlerTwo(e)( clicks++; var newNode = document.createElement("p"); newNode.textContent = "a click occurred " + clicks; document.body.appendChild (newNode); ) var rect = document.getElementById("rect"); // attach the first handler rect.addEventListener("click", handlerOne); // attach the second handler rect.addEventListener("click", handlerTwo);

    Event Handling

    JavaScript client programs are based on an event-driven programming model. With this style of programming, the web browser generates an event when something happens to the document or some element of it. For example, a web browser generates an event when it finishes loading a document when the user hovers the mouse over a hyperlink or presses a key on the keyboard.

    If a JavaScript application is interested in a particular type of event for a particular document element, it can register one or more functions to be called when that event occurs. Keep in mind that this is not a unique feature of web programming: all GUI applications operate this way - they constantly wait for something to happen (i.e., wait for events to occur), and respond to what happens.

    The event type is a string that identifies the type of action that caused the event. The type "mousemove", for example, means that the user has moved the mouse pointer. The type "keydown" means that a key on the keyboard was pressed. And the “load” type means that the download of the document (or some other resource) from the network has completed. Because the event type is just a string, it is sometimes called the event name.

    The target of an event is the object in which the event occurred or with which the event is associated. When talking about an event, they usually mention the type and purpose of the event. For example, the "load" event of a Window object or the "click" event of a . The most typical goals of events in client applications in JavaScript are Window, Document, and Element objects, but some types of events can occur in other object types.

    An event handler is a function that processes, or responds to, an event. Applications must register their event handler functions with the web browser, specifying the event type and purpose. When an event of the specified type occurs on the specified target, the browser will invoke the handler. When event handlers are called on an object, we sometimes say that the browser has "raised" or "thrown" the event.

    An event object is an object associated with a specific event and containing information about that event. Event objects are passed to the event handler function as an argument (except IE8 and newer earlier versions, where the event object is only available as a global event variable). All event objects have the property type, which defines the event type, and the property target, defining the purpose of the event.

    For each event type, a set of properties is defined in the associated event object. For example, an object associated with mouse events includes the coordinates of the mouse pointer, and an object associated with keyboard events contains information about the key pressed and the modifier keys pressed. For many event types, only standard properties such as type and target are defined and no additional properties are passed. useful information. For these types of events, the mere occurrence of the event is important and no other information is relevant.

    Event propagation is the process by which the browser decides which objects to call event handlers on. In the case of events intended for a single object (such as the "load" event of a Window object), there is no need to propagate them. However, when an event occurs on a document element, it propagates, or "bubbles," up the document tree.

    If the user clicks on a hyperlink, the "mousemove" event will first be raised on the element , defining this link. It will then be delivered to the containing elements: perhaps the element

    The element and the Document object itself. Sometimes it is more convenient to register a single event handler on a Document object or other container element than to register on all the elements of interest.

    Having defined some terms, we can move on to exploring issues related to events and their processing.

    Registering Event Handlers

    There are two main ways to register event handlers. The first, which appeared early in the development of the World Wide Web, is to set the property of the object or document element that is the target of the event. The second method, newer and more universal, is to pass a handler to a method of an object or element.

    The matter is complicated by the fact that each technique has two versions. You can set an event handler property in JavaScript code or in a document element by defining the corresponding attribute directly in the HTML markup. Registering handlers with a method call can be done by a standard method called addEventListener(), which is supported by all browsers except IE versions 8 and below, and another method called attachEvent(), supported by all versions of IE up to IE9.

    Setting event handler properties

    The simplest way to register an event handler is to set a property of the event target to the desired handler function. By convention, event handler properties have names consisting of the word "on" followed by the event name: onclick, onchange, onload, onmouseover, etc. Note that these property names are case-sensitive and use only lowercase characters, even when the event type name is multiple words (for example, "readystatechange"). Below are two examples of registering event handlers:

    // Assign the function to the onload property of the Window object. // The function is an event handler: it is called when the document is loaded window.onload = function() ( // Find the element var elt = document.getElementById("shipping_address"); // Register an event handler that will be called // directly before submitting the form elt.onsubmit = function() ( return validate(this); ) )

    This method of registering event handlers is supported in all browsers for all commonly used event types. In general, all widely supported application interfaces that define their events allow handlers to be registered by setting the properties of the event handlers.

    The disadvantage of using event handler properties is that they are designed with the assumption that event targets will have at most one handler per event type. When creating a library for use in arbitrary documents, it is better to use a technique (such as calling the addEventListener() method) to register handlers that does not change or overwrite previously registered handlers.

    Setting event handler attributes

    The properties of event handlers on document elements can also be set by defining attribute values ​​in the corresponding HTML tags. In this case, the attribute value must be a string of JavaScript code. This program code should not be a complete declaration of the event handler function, but only its body. That is, the implementation of the event handler in HTML markup should not be enclosed in curly braces and preceded by the function keyword. For example:

    If the event handler HTML attribute value consists of multiple JavaScript statements, they must be separated by semicolons, or the attribute value must appear on multiple lines.

    Some event types are intended for the browser as a whole, rather than for any specific document element. Handlers for such events in JavaScript are registered in the Window object. In HTML markup they must be placed in a tag, but the browser will register them in the Window object. The following is a complete list of such event handlers defined by the draft HTML5 specification:

    onafterprint onfocus ononline onresize onbeforeprint onhashchange onpagehide onstorage onbeforeunload onload onpageshow onundo onblur onmessage onpopstate onunload onerror onoffline onredo

    When developing client-side scripts, it is common practice to separate the HTML markup from the JavaScript code. Programmers who follow this rule avoid (or at least try to avoid) using HTML event handler attributes to avoid mixing JavaScript code with HTML markup.

    addEventListener()

    In the standard event model, supported by all browsers except IE versions 8 and below, the target of an event can be any object - including Window and Document objects and all Elements objects of document elements - defining a method called addEventListener() with which event handlers can be registered for this purpose.

    The addEventListener() method takes three arguments. The first is the event type for which the handler is registered. The event type (or name) must be a string and must not include the "on" prefix used when setting the properties of event handlers. The second argument to the addEventListener() method is a function that should be called when an event of the specified type occurs. The last argument is passed to the addEventListener() method with a boolean value. Typically this argument is false. If you pass it true, the function will be registered as an interception handler and will be called in another phase of event propagation.

    The specification may eventually change so that it is acceptable to omit the third argument rather than explicitly passing it false, but as of this writing, the omission of the third argument results in an error in some current browsers.

    The following snippet registers two "click" event handlers on the element. Note the differences between the two techniques used:

    Click me! var b = document.getElementById("mybutton"); b.onclick = function() ( alert("Thanks for clicking on me!"); ); b.addEventListener("click", function() (alert("Thanks again!")), false);

    Calling the addEventListener() method with the string "click" as the first argument does not affect the value of the onclick property. In the snippet above, clicking the button will bring up two alert() dialog boxes. But more importantly, the addEventListener() method can be called multiple times and can be used to register multiple handler functions for the same event type in the same object. When an event occurs on an object, all handlers registered for that event type will be called, in the order in which they were registered.

    Calling addEventListener() multiple times on the same object with the same arguments has no effect - the handler function is registered only once and repeated calls do not affect the order in which the handlers are called.

    Paired with the addEventListener() method is the removeEventListener() method, which takes the same three arguments, but instead of adding, it removes a handler function from the object. This is often useful when you need to register a temporary event handler and then remove it at some point.

    Internet Explorer versions earlier than IE9 do not support the addEventListener() and removeEventListener() methods. IE5 and later define similar methods, attachEvent() and detachEvent() . Because the IE event model does not support an interception phase, the attachEvent() and detachEvent() methods take only two arguments: the event type and the handler function, with the first argument passing the handler property name prefixed with “on” to the methods in IE rather than the type events without this prefix.

    Calling event handlers

    Once you register an event handler, the web browser will call it automatically when an event of the specified type occurs on the specified object. This section details the order in which event handlers are called, the arguments to the handlers, the context of the call (the value of this), and the purpose of the handler's return value. Unfortunately, some of these details differ between IE versions 8 and below and other browsers.

    Event Handler Argument

    When an event handler is invoked, it is usually (with one exception, discussed below) passed the event object as a single argument. The properties of an event object contain additional information about the event. The type property, for example, determines the type of event that occurred.

    In IE version 8 and below, event handlers registered by setting a property are not passed an event object when called. Instead, the event object is stored in the global variable window.event. For portability, event handlers can be styled as follows so that they use the window.event variable when called without an argument:

    The event object is passed to event handlers registered with the attachEvent() method, but they can also use the window.event variable.

    When you register an event handler using an HTML attribute, the browser converts a string of JavaScript code into a function. Browsers other than IE create a function with a single argument, event. IE creates a function that takes no arguments. If you use the event identifier in such functions, it will refer to window.event. In either case, event handlers defined in HTML markup can reference an event object using the event identifier.

    Event Handler Context

    When an event handler is registered by setting a property, it looks like defining a new document element method:

    E.onclick = function() ( /* handler implementation */ );

    It is therefore not surprising that event handlers are invoked (with one exception regarding IE, which is described below) as methods of the objects in which they are defined. That is, in the body of the event handler, the this keyword refers to the target of the event.

    In handlers, the this keyword refers to the target object, even when they were registered using the addEventListener() method. However, unfortunately, this is not the case for the attachEvent() method: handlers registered with the attachEvent() method are called as functions, and in them the this keyword refers to the global (Window) object. This problem can be solved in the following way:

    /* Registers the specified function as an event handler of the specified type in the specified object. Ensures that the handler will always be called as a method on the target object. */ function addEvent(target, type, handler) ( if (target.addEventListener) target.addEventListener(type, handler, false); else target.attachEvent("on" + type, function(event) ( // Call the handler as target method, // and pass it an event object return handler.call(target, event); )); )

    Note that event handlers registered in this manner cannot be removed because the reference to the wrapper function passed to the attachEvent() method is not stored anywhere so that it can be passed to the detachEvent() method.

    Handler return values

    The value returned by an event handler registered by setting an object property or by an HTML attribute should be taken into account. Typically, returning false tells the browser that it should not perform the default actions for this event.

    For example, the onclick handler of a form submit button might return false to prevent the browser from submitting the form. (This can be useful if the user's input fails client-side validation.) Similarly, an input field's onkeypress event handler can filter keyboard input by returning false when invalid characters are entered.

    Also important is the value returned by the Window object's onbeforeunload handler. This event is generated when the browser navigates to another page. If this handler returns a string, it will be displayed in a modal dialog box prompting the user to confirm that they want to leave the page.

    It is important to understand that the return values ​​of event handlers are only counted if the handlers are registered by setting properties. Handlers registered with addEventListener() or attachEvent() must instead call the preventDefault() method or set the event object's returnValue property.

    Canceling events

    The value returned by an event handler registered as a property can be used to override the browser's default actions in the event of that event. In browsers that support the addEventListener() method, default actions can also be overridden by calling the event object's preventDefault() method. However, in IE version 8 and below, the same effect is achieved by setting the event object's returnValue property to false.

    The following snippet demonstrates a hyperlink click event handler that uses all three methods of canceling the event (blocking the user from following the link):

    Window.onload = function() ( // Find all links var a_href = document.getElementsByTagName("a"); // Add a click event handler (not for IE

    The current DOM Events 3 module project defines a property on the Event object called defaultPrevented . It is not yet supported by all browsers, but its essence is that under normal conditions it is false and only becomes true if the preventDefault() method is called.

    Canceling the default actions associated with an event is just one type of canceling an event. It is also possible to stop the event from spreading. In browsers that support the addEventListener() method, the event object has a stopPropagation() method, which when called stops further propagation of the event. If other handlers for this event are registered on the same target object, then the remaining handlers will still be called, but no other event handlers on other objects will be called after the stopPropagation() method is called.

    In IE version 8 and below, the stopPropagation() method is not supported. Instead, the event object in IE has a property cancelBubble. Setting this property to true prevents the event from propagating.

    The current draft of the DOM Events 3 specification defines another method on the Event object, a method called stopImmediatePropagation(). Like the stopPropagation() method, it prevents the event from propagating to any other objects. But in addition, it also prevents any other event handlers registered on the same object from being called.

    Some JavaScript event programs work directly with user input. The moment of occurrence and the order of such interactions cannot be predicted in advance.

    Event Handlers

    You can react to a key press by constantly reading its state to catch the moment the key is pressed before it is released again.

    This is how data input was processed on primitive machines. More advanced is detecting a keystroke and queuing it. The program can then periodically check the queue of new events and react to what it finds there. In this case, the program must remember to scan the queue and do so often.

    In the period from pressing a key until the program detects this event, it actually does not respond to requests. This approach is called polling (survey).

    Most programmers try to avoid it if possible.

    The best way is to implement a system that gives the code the ability to react to events as they happen. Browsers implement this by providing the ability to register handler functions for specific JavaScript events:

    Click on this document to activate the handler.

    addEventListener("click", function() ( console.log("You clicked!"); ));

    The addEventListener function is registered so that its second argument is called whenever the event described by the first argument occurs.

    Events and DOM nodes

    Each browser event handler is registered with a context. When the addEventListener function is called, it is called as a method on the entire window, since in the browser the global range is equivalent to the window object. Each DOM element has its own addEventListener method, which allows you to listen for events specifically on that element:

    Click on me

    There is no handler here.

    var button = document.querySelector("button"); button.addEventListener("click", function() ( console.log("Button clicked."); ));

    In this example, the handler is connected to the button node. JavaScript mouse events fire the handler, but clicks in the rest of the document do not.

    By setting the node's onclick attribute, we get the same result. But a node only has one onclick attribute, so you can only register one handler per node. The addEventListener method allows you to add any number of handlers. This way we are insured against accidental replacement of a processor that has already been registered.

    The removeEventListener method is called with arguments similar to addEventListener . It removes the handler:

    One-time button var button = document.querySelector("button"); function once() ( console.log("Done."); button.removeEventListener("click", once); ) button.addEventListener("click", once);

    To cancel a handler function, we give it a name (for example, once ). So we pass it to both addEventListener and removeEventListener.

    Event Objects

    Although we didn't mention it in the examples above, the JavaScript event handlers function is passed an argument: the event object. It provides additional information about the event. For example, if we want to know which mouse key was pressed, we need to get the value of the which event object property:

    Click on me with any mouse key var button = document.querySelector("button"); button.addEventListener("mousedown", function(event) ( if (event.which == 1) console.log("Left button"); else if (event.which == 2) console.log("Middle button" ); else if (event.which == 3) console.log("Right button"); ));

    The information stored in an object varies depending on the type of event. The object's type property always contains a string identifying the event (for example, "click" or "mousedown").

    Spreading

    Event handlers (such as JavaScript touch events) registered for parent nodes will also receive events that occur on child elements. If a button inside a paragraph was clicked, the paragraph's event handlers will also receive a click event.

    An event propagates from the node in which it occurred, to the parent node, and to the document root. After all handlers registered in a particular node have taken action in turn, handlers registered for the entire window are able to respond to the event.

    At any time, the event handler can call the stopPropagation method on the event object to prevent the event from propagating further. This can be useful when you have a button inside another interactive element and you don't want clicking the button to trigger the behavior defined for clicking on external elements.

    In the following example, we register "MouseDown" handlers for both the button and the paragraph. When you right-click (JavaScript mouse events), the handler calls the stopPropagation method, which prevents the paragraph handler from running. When you click on the button with another mouse key, both handlers are launched:

    A paragraph and a button in it.

    var para = document.querySelector("p"); var button = document.querySelector("button"); para.addEventListener("mousedown", function() ( console.log("Handler for paragraph."); )); button.addEventListener("mousedown", function(event) ( console.log("Handler for button."); if (event.which == 3) event.stopPropagation(); ));

    Most event objects have a target property that points to the node where they occurred. You can use this property to avoid accidentally handling some event that propagates up from the node.

    You can also use a JavaScript event target to extend the scope of an event of a certain type. For example, if you have a node containing a long list of buttons, it is more convenient to register one click handler for the outer node and use the target property to track whether the button was clicked, rather than registering handler instances for all buttons:

    A B C document.body.addEventListener("click", function(event) ( if (event.target.nodeName == "BUTTON") console.log("Clicked", event.target.textContent); ));

    Default Actions

    Many events have default actions associated with them. If you click on a link, it will take you to the target element of the link. If you click the down arrow, the browser will scroll down the page. If you right-click, a context menu will open.

    For most event types, JavaScript event handlers are called before default actions are performed. If you do not want the default behavior to occur, you must call the preventDefault method on the event object.

    Use it to implement custom keyboard shortcuts or context menus. Or, to override the behavior that users expect. Below is a link that cannot be followed:

    MDN var link = document.querySelector("a"); link.addEventListener("click", function(event) ( console.log("Nope."); event.preventDefault(); ));

    Try not to do this unless you have a good reason to do so.

    Depending on the browser, some events may not be intercepted. In Google Chrome, for example, the keyboard shortcut (JavaScript event keycode) to close the current tab (Ctrl-W or Command-W) cannot be handled using JavaScript.

    Key Events

    When the user presses a key on the keyboard, the browser fires the "keydown" event. When he releases the key, the "keyup" event fires:

    This page turns purple when you press the V key.

    addEventListener("keydown", function(event) ( if (event.keyCode == 86) document.body.style.background = "violet"; )); addEventListener("keyup", function(event) ( if (event.keyCode == 86) document.body.style.background = ""; ));

    This event also fires when the user presses and holds a key, or while the key is held down. For example, if you want to increase the speed of a character in a game by pressing an arrow key, and decrease it again by releasing the key, then you need to be careful not to increase the speed each time the key is pressed.

    The previous example used the event object's keycode JavaScript property. With its help, it is determined which key was pressed or released. It's not always obvious how to translate a key's numeric code to an actual key.

    To read the meanings of the letter and number keys, a code is used Unicode character. It is associated with the letter (uppercase) or number indicated on the key. The charCodeAt method for strings allows you to get this value:

    console.log("Violet".charCodeAt(0)); // → 86 console.log("1".charCodeAt(0)); // → 49

    Other keys have less predictable key codes associated with them. The best way to determine the code you need is to experiment. Register a keypress event handler that captures the keycodes it receives and presses the desired key.

    Keys such as Shift , Ctrl , Alt generate events like regular keys. But when tracking key combinations, you can also determine whether those keys are pressed by the properties of the keyboard events and JavaScript mouse events: shiftKey , ctrlKey , altKey and metaKey :

    To continue, press Ctrl-Space.

    addEventListener("keydown", function(event) ( if (event.keyCode == 32 && event.ctrlKey) console.log("Continuing!"); ));

    The "keydown" and "keyup" events provide information about actual keypresses. But what if we need the input text itself? Retrieving text from keycodes is inconvenient. There is an event for this, "keypress", which fires immediately after "keydown". It repeats along with "keydown" as long as the key is pressed. But only for the keys with which characters are entered.

    The charCode property on the event object contains a code that can be interpreted as the Unicode character code. We can use the String.fromCharCode function to convert this code into a single character string.

    Set the input focus to this page and type something.

    addEventListener("keypress", function(event) ( console.log(String.fromCharCode(event.charCode)); ));

    The DOM node at which the event occurs depends on the element that had input focus when the key was pressed. Regular nodes cannot have input focus (unless you set the tabindex attribute to them), but elements such as links, buttons, and form fields can.

    If no specific element has input focus, then the target node for key events and JavaScript touch events is document.body .

    Mouse clicks

    Pressing a mouse button also triggers a series of events. The "mousedown" and "mouseup" events are similar to the "keydown" and "keyup" events. They are triggered when a mouse button is pressed and released. These events occur on the DOM nodes that were hovered over when the event occurred.

    For a shared node that has both a mouse press and release, the click event is fired after the mouseup event. For example, if you press the mouse button on one item, and then move the cursor to another item and release the button, the click event will occur on the element that contains both of these items.

    If two clicks occur close to each other, the "dblclick" (double click) event is also fired. It appears after the second click. To get exact information about the location where the mouse event occurred, you need to get the value of the pageX and pageY properties, which contain the coordinates of the event (in pixels) relative to the upper left corner of the document.

    Below is an implementation of a primitive drawing program. Each time you click the mouse in the document (under the cursor), a dot is added:

    body ( height: 200px; background: beige; ) .dot ( height: 8px; width: 8px; border-radius: 4px; /* rounded corners*/ background: blue; position: absolute; ) addEventListener("click", function(event) ( var dot = document.createElement("div"); dot.className = "dot"; dot.style.left = (event.pageX - 4) + "px"; dot.style.top = (event.pageY - 4) + "px"; document.body.appendChild(dot); ));

    The clientX and clientY properties are similar to pageX and pageY , but they relate to the visible part of the document. They can be used to compare mouse coordinates with the coordinates returned by the getBoundingClientRect function.

    Mouse movement

    Every time the mouse moves, the “mousemove” event from the JavaScript mouse events set is fired. It can be used to track the position of the mouse. This is used when implementing the ability to drag elements with the mouse.

    IN following example The program displays a panel and sets up event handlers so that when dragged, the panel becomes narrower or wider:

    Drag the edge of the panel to change its width:

    var lastX; // Tracks the last X position of the mouse var rect = document.querySelector("div"); rect.addEventListener("mousedown", function(event) ( if (event.which == 1) ( lastX = event.pageX; addEventListener("mousemove", moved); event.preventDefault(); // Prevents selection ) ) ); function buttonPressed(event) ( if (event.buttons == null) return event.which != 0; else return event.buttons != 0; ) function moved(event) ( if (!buttonPressed(event)) ( removeEventListener( "mousemove", moved); ) else ( var dist = event.pageX - lastX; var newWidth = Math.max(10, rect.offsetWidth + dist); rect.style.width = newWidth + "px"; lastX = event .pageX; ) )

    Note that the "mousemove" handler is registered for the entire window. Even if the mouse moves out of the panel while resizing, we still update the panel's width and terminate JavaScript touch events when the mouse key is released.

    We must stop resizing the panel when the user releases the mouse button. Unfortunately, not all browsers set the which property for mousemove events. There is a standard buttons property that provides similar information, but it is also not supported in all browsers. Luckily, all major browsers support one thing: either buttons or which . The buttonPressed function in the example above first tries to use the buttons property, and if it's not available, goes to which .

    When the mouse cursor moves over or leaves a node, the "mouseover" or "mouseout" events are fired. They can be used to create hover effects, display some kind of caption, or change the style of an element.

    To create such an effect, it is not enough to simply start displaying it when the mouseover event occurs and end after the mouseout event. When the mouse moves from a node to one of its children, a "mouseout" event occurs for the parent node. Although the mouse pointer has not left the node's spread range.

    To make matters worse, these JavaScript events are propagated just like other events. When the mouse leaves one of the child nodes for which a handler is registered, the "mouseout" event will be raised.

    To work around this issue, you can use the relatedTarget event object property. When the "mouseover" event occurs, it indicates which element was hovered over before. And in the event of a “mouseout” - to which element the pointer is moved. We will only change the mouseover effect when the relatedTarget is outside our target node.

    In this case, we are changing the behavior because the mouse was hovering over the node from outside of it (or vice versa):

    Hover your mouse over this paragraph.

    var para = document.querySelector("p"); function isInside(node, target) ( for (; node != null; node = node.parentNode) if (node ​​== target) return true; ) para.addEventListener("mouseover", function(event) ( if (!isInside (event.relatedTarget, para)) para.style.color = "red"; )); para.addEventListener("mouseout", function(event) ( if (!isInside(event.relatedTarget, para)) para.style.color = ""; ));

    The isInside function tracks parental connections given node or until the top of the document is reached (when node is zero ). Or the parent element we need will not be found.

    A hover effect is much easier to create using the CSS:hover pseudo-selector, as shown in the following example. But when the hover effect involves something more complex than just changing the style of the target node, then you need to use a trick using the mouseover and mouseout events (JavaScript mouse events):

    Scroll Events

    Every time an element is scrolled, a JavaScript scroll event is fired on it. It can be used to track what's in this moment viewed by the user; to disable animation located outside the viewport.

    In the following example, we display a progress bar in the top right corner of the document and update it so that it fills with a different color piece by piece as we scroll down the page:

    .progress ( border: 1px solid blue; width: 100px; position: fixed; top: 10px; right: 10px; ) .progress > div ( height: 12px; background: blue; width: 0%; ) body ( height: 2000px ; )

    Scroll me...

    var bar = document.querySelector(".progress div"); addEventListener("scroll", function() ( var max = document.body.scrollHeight - innerHeight; var percent = (pageYOffset / max) * 100; bar.style.width = percent + "%"; ));

    By setting the element's position or fixed property, we get the same result as setting position:absolute . But this also locks the element from scrolling along with the rest of the document. As a result, the progress indicator will be statically fixed in the top corner. Inside it is another element, the size of which changes in accordance with the current progress.

    We use % rather than px as the unit of measurement when setting the width, so that the element's dimensions change proportionally to the size of the progress bar.

    The global variable innerHeight contains the height of the window, which we must subtract from the total available scrollable height of the document. You cannot scroll down the window when you reach the bottom of the document. With innerHeight innerWidth can also be used. Dividing pageYOffset( current position scroll box ) by the maximum allowed scroll position and multiplying by 100 gives the percentage for the progress bar.

    Calling preventDefault on a JavaScript scroll event does not prevent scrolling. The event handler is called only after scrolling occurs.

    Input focus events

    When an element has input focus, the browser fires a "focus" event on it. When input focus is removed, the "blur" event is fired.

    These two events do not spread. The parent element handler is not notified when child element is highlighted with input focus.

    The following example displays a tooltip for the text field that currently has input focus:

    Name:

    Age:

    var help = document.querySelector("#help"); var fields = document.querySelectorAll("input"); for (var i = 0; i< fields.length; i++) { fields[i].addEventListener("focus", function(event) { var text = event.target.getAttribute("data-help"); help.textContent = text; }); fields[i].addEventListener("blur", function(event) { help.textContent = ""; }); }

    The window object receives the "focus" and "blur" events when the user navigates to or leaves the tab, browser window in which the document is displayed.

    Load event

    When the page finishes loading, a JavaScript event “load” is raised for the document body and window objects. It is used to schedule the initialization of actions that require loading the entire document. Don't forget that the content is launched immediately when this tag is encountered. Sometimes it's too early. For example, when a script needs to do something with parts of a document that load after the .

    and script tags that load external files also contain a "load" event. It indicates that the file that was associated with them has been downloaded. Like input focus events, load events are not propagated.

    When we close a page or move to another (for example, by clicking on a link), the “beforeunload” event is fired. It is used to prevent the user from accidentally losing what he was working on after closing the document.

    Preventing a page from unloading is not done using the preventDefault method. Instead, a string is returned from the handler. It is used in a dialog box that asks the user whether they want to stay on the page or leave it. This mechanism ensures that the user will have the opportunity to leave the page, even if a malicious script is running, the purpose of which is to keep the visitor on the page.

    Script execution sequence

    Various factors can trigger script execution: reading a tag, occurrence of an event. The requestAnimationFrame method specifies a function call before the next page is re-rendered. This is another way that scripts can be run.

    JavaScript select events and all the others can fire at any time, but two scripts will never fire at the same time in the same document. If a script is already running, event handlers and code snippets scheduled by another script will have to wait their turn. This is the reason why the document freezes when the script is running for a long time. The browser does not respond to clicks and other events because it cannot fire event handlers until the current script finishes running.

    Some programming environments allow you to create multiple threads of execution that run simultaneously. By providing the ability to perform multiple tasks simultaneously, you can increase the speed of program execution. But when we have multiple actions that affect the same parts of the system at the same time, it becomes more difficult for the program to perform them.

    If you need to run processes in background Without freezing the page, browsers provide us with what are called web workers. It is a JavaScript sandbox that runs on the document alongside the main program and can only communicate with it by sending and receiving messages.

    Let's say that in a file called code/squareworker.js we have the following code:

    addEventListener("message", function(event) ( postMessage(event.data * event.data); ));

    Imagine that the number you are squaring is very large, lengthy to calculate, and you need to perform the calculation on a background thread. This code starts web workers, sends it some messages and prints out the responses:

    var squareWorker = new Worker("code/squareworker.js"); squareWorker.addEventListener("message", function(event) ( console.log("The worker responded:", event.data); )); squareWorker.postMessage(10); squareWorker.postMessage(24);

    The postMessage function sends a message that triggers the message event at the receiver. The script that created the web workers sends and receives messages through the Worker object. Using this object, the environment interacts with the script that created it, sending information and listening to it in its global with the original script.

    Setting timers

    The setTimeout function is similar to requestAnimationFrame. It calls another function that will be called later. But instead of calling the function the next time the page is rendered, it waits a certain number of milliseconds. In that JavaScript example event the page background turns from blue to yellow after two seconds:

    document.body.style.background = "blue"; setTimeout(function() ( document.body.style.background = "yellow"; ), 2000);

    Sometimes we need to cancel a function we have planned. This is done by storing the return value of setTimeout and calling clearTimeout on it:

    var bombTimer = setTimeout(function() ( console.log("BOOM!"); ), 500); if (Math.random()< 0.5) { // 50% chance console.log("Defused."); clearTimeout(bombTimer); }

    The cancelAnimationFrame function works the same as clearTimeout . It is called by the value returned by requestAnimationFrame to cancel the frame (if it has not already been called).

    A similar set of functions, setInterval and clearInterval are used to set a timer that should repeat an action every X milliseconds:

    var ticks = 0; var clock = setInterval(function() ( console.log("tick", ticks++); if (ticks == 10) ( clearInterval(clock); console.log("stop."); ) ), 200);

    Splitting up

    Some event types can be fired many times within a short period of time (such as "mousemove" and javascript scroll event). When handling such events, you need to be careful that it doesn't take too long, otherwise the handler will take so long to perform the action that interaction with the document becomes slow and choppy.

    If you need to do something non-standard in such a handler, you can use setTimeout to make sure it doesn't take too long. This is commonly referred to as event splitting. There are several different approaches to crushing.

    In the first example we want to do something while the user is typing. But we don't want to do this after every keypress event. When the user is typing quickly, you need to wait until there is a pause. Instead of immediately executing the action in the event handler, we set a delay. We also clear the previous delay (if any). If events occur at short intervals (less than the delay we set), then the delay from the previous event is canceled:

    Type something here... var textarea = document.querySelector("textarea"); var timeout; textarea.addEventListener("keydown", function() ( clearTimeout(timeout); timeout = setTimeout(function() ( console.log("You stopped typing."); ), 500); ));

    Passing an undefined value for clearTimeout or calling it on a delay that is already running will have no effect. We no longer have to be careful about when to call it, we just do it for every event.

    You can use a different script if you need to separate the answers over a short period of time. But at the same time, they should be launched during a series of events, and not just after it. For example, you can send the current mouse coordinates in response to mousemove events (JavaScript mouse events), but only every 250 milliseconds:

    function displayCoords(event) ( document.body.textContent = "mouse is at " + event.pageX + ", " + event.pageY; ) var scheduled = false, lastEvent; addEventListener("mousemove", function(event) ( lastEvent = event; if (!scheduled) ( scheduled = true; setTimeout(function() ( scheduled = false; displayCoords(lastEvent); ), 250); ) ));

    Conclusion

    Event handlers allow us to detect and respond to events over which we have no direct control. To register such a handler, use the addEventListener method.

    Each event has a specific type (“keydown”, “focus”, etc.) that identifies it. Most events are raised on a specific DOM element and then propagated to the element's parent nodes. This allows handlers associated with these elements to process them.

    When a handler is called, it is passed an event object with additional information about action. This object also contains methods to stop further propagation of the event (stopPropagation) or to prevent the default browser from processing the event (preventDefault).

    Keypresses generate the "keydown", "keypress" and "keyup" events. Clicking the mouse generates the "mousedown", "mouseup" and "click" events. Moving the mouse - "mousemove", "mouseenter" and "mouseout".

    A JavaScript scroll event can be defined using the "scroll" event, and changing focus can be defined using "focus" and "blur". Once the document has finished loading, the “load” event is raised for the window.

    Only one part of a JavaScript program can run at a time. Event handlers and other scheduled scripts must wait for other scripts in the queue to finish executing.

    If you have a photo of your favorite cat Murzik posted on your website, but you don’t want anyone to copy it or save it on a hard drive, then put such a script in the body of the site.





    

    2024 gtavrl.ru.