{"id":539,"date":"2018-04-18T14:00:17","date_gmt":"2018-04-18T14:00:17","guid":{"rendered":"https:\/\/www.audero.it\/blog\/?p=539"},"modified":"2025-05-04T22:16:14","modified_gmt":"2025-05-04T22:16:14","slug":"in-depth-guide-event-listeners","status":"publish","type":"post","link":"https:\/\/www.audero.it\/blog\/2018\/04\/18\/in-depth-guide-event-listeners\/","title":{"rendered":"An in-depth guide to event listeners"},"content":{"rendered":"<p>When creating interactive web pages, developers often need to execute some actions when a given event occurs. Changing the image of a carousel when a user clicks on one of its arrows, showing a tooltip when a word is hovered, or validating a field when a user moves the focus onto another field are common examples. To execute these actions, we have to add event listeners to the elements of the page.<\/p>\n<p>In this article, I&#8217;ll explain what event listeners are, and how to add and remove them from a web page. I&#8217;ll show several examples and talk about patterns to avoid when dealing with event listeners. The topic will be discussed in depth. So, even if you&#8217;re an expert, you might not know some of the details covered.<br \/>\n<!--more--><\/p>\n<h2>What is an event listener?<\/h2>\n<p>Before we delve into the discussion of adding and removing event listeners, let&#8217;s know more about them.<\/p>\n<h3>W3C definition<\/h3>\n<p>According to the <abbr title=\"World Wide Web Consortium\">W3C<\/abbr>, an <a href=\"https:\/\/www.w3.org\/TR\/uievents\/#event-listener\" target=\"_blank\" rel=\"noopener\"><dfn>event listener<\/dfn><\/a> is an object that implements the <a href=\"https:\/\/www.w3.org\/TR\/DOM-Level-2-Events\/events.html#Events-EventListener\"><code>EventListener<\/code> interface<\/a>, which defines a single method named <code>handleEvent()<\/code>. An event listener is used to observe a specific event and perform one or more actions when it occurs. Event listeners are executed asynchronously via the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Execution_model\" target=\"_blank\" rel=\"noopener\">event loop<\/a>, in the same order they are added.<\/p>\n<p><small>In older versions of Internet Explorer, the execution order wasn&#8217;t guaranteed to be the same as the order in which event listeners were added.<\/small><\/p>\n<p>The <code>EventListener<\/code> interface is reported below:<\/p>\n<pre><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface EventListener {\n   void handleEvent(in Event evt);\n};\n<\/pre>\n<p>The <code>handleEvent()<\/code> method defines only one parameter which is the event object, implementing the <a href=\"https:\/\/dom.spec.whatwg.org\/#event\" target=\"_blank\" rel=\"noopener\"><code>Event<\/code> interface<\/a>, representing the event triggered such as <code>click<\/code> and <code>focus<\/code>. The method returns nothing (<code>undefined<\/code>, to be precise).<\/p>\n<p>In conclusion, an object that possesses a <code>handleEvent()<\/code> method, like the one defined below, is a valid event listener.<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst eventListener = {\n   handleEvent: function(event) {\n      \/\/ Do something here, possibly using the event parameter\n   }\n};\n<\/pre>\n<p>If you have ever added an event listener to an element in the past, the previous object will look weird. It isn&#8217;t what almost every developer employs or is accustomed to. Most developers have never used an object when adding an event listener, but only a function. The W3C specifications explain this case:<\/p>\n<blockquote cite=\"https:\/\/www.w3.org\/TR\/uievents\/#dfn-event-listener\"><p>Note: In JavaScript, user-defined functions are considered to implement the <code>EventListener<\/code> interface. Thus the event object will be provided as the first parameter to the user-defined function when it is invoked.<\/p><\/blockquote>\n<p>Functions used as event listeners can be named or anonymous, and defined before their usage or inline. Some examples are shown below:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n\/\/ Named function\nfunction foo() {}\n\n\/\/ Anonymous function\nfunction() {}\n<\/pre>\n<p>Because every function is a valid event listener, methods can be used as well. The snippet below defines a <code>Utility<\/code> object with a <code>showTooltip()<\/code> method:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst Utility = {\n   showTooltip: function(event) {\n      \/\/ Do something here, possibly using the event parameter\n   }\n};\n<\/pre>\n<p>The difference between this example and the previous one where we saw an object is that we can only use the method as an event listener while in the other we can also use the object itself. So, the <code>showTooltip()<\/code> method can be used as an event listener, while the <code>Utility<\/code> object can&#8217;t. The reason is that the latter doesn&#8217;t possess a <code>handleEvent()<\/code> method. If this distinction is not clear yet, we&#8217;ll see some examples of use of a function and an object as event listeners in the remainder of the article.<\/p>\n<h3>WHATWG definition<\/h3>\n<p>The <a href=\"https:\/\/dom.spec.whatwg.org\/\" target=\"_blank\" rel=\"noopener\">WHATWG DOM specifications<\/a> provide a different definition of event listener. According to the <abbr title=\"Web Hypertext Application Technology Working Group\">WHATWG<\/abbr>, an <a href=\"https:\/\/dom.spec.whatwg.org\/#concept-event-listener\" target=\"_blank\" rel=\"noopener\">event listener<\/a> consists of a type, a callback (which can be either <code>null<\/code> or that implements the <code>EventListener<\/code> interface), and other fields like <code>capture<\/code>, <code>passive<\/code>, <code>once<\/code>, and <code>removed<\/code>. As we&#8217;ll examine in the upcoming sections, the different definitions won&#8217;t have any impact on us as developers.<\/p>\n<p>Now that we know what an event listener is, let&#8217;s see how to add one to an element of a web page.<\/p>\n<h2>Adding event listeners<\/h2>\n<p>With event listeners we can create interactive web pages by running animations, injecting new elements in the page, or performing any other action we wish when a given event occurs.<\/p>\n<p>To add an event listener we have to employ the <a href=\"https:\/\/www.w3.org\/TR\/DOM-Level-2-Events\/events.html#Events-EventTarget-addEventListener\" target=\"_blank\" rel=\"noopener\"><code>addEventListener()<\/code> method<\/a>. It allows the registration of an event listener on an <em>event target<\/em> (an object that implements <a href=\"https:\/\/www.w3.org\/TR\/2000\/REC-DOM-Level-2-Events-20001113\/events.html#Events-EventTarget\" target=\"_blank\" rel=\"noopener\">the <code>EventTarget<\/code> interface<\/a>). Most elements of a web page are event targets (for example comments are not). <code>window<\/code> and <code>document<\/code> are event targets as well. Other objects that are event targets include <code>XMLHttpRequest<\/code>, <code>AudioNode<\/code>, and <code>AudioContext<\/code>.<\/p>\n<p><code>addEventListener()<\/code> has two signatures:<\/p>\n<pre><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\naddEventListener(type, listener&#x5B;, useCapture]);\naddEventListener(type, listener&#x5B;, options]);\n<\/pre>\n<p><small>Different resources refer to the second parameter with different names. In addition to the terms <em>event listener<\/em>, <em>listener<\/em>, and <em>function<\/em>, you can find the use of <em>callback<\/em> (adopted by <a href=\"https:\/\/dom.spec.whatwg.org\/#dom-eventtarget-addeventlistener-type-callback-options-callback\" target=\"_blank\" rel=\"noopener\">the WHATWG specifications<\/a>) or <em>handler<\/em> (used by the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/EventTarget\/addEventListener#Syntax\" target=\"_blank\" rel=\"noopener\"><code>addEventListener()<\/code>&#8216;s page on <abbr title=\"Mozilla Developer Network\">MDN<\/abbr><\/a>).<\/small><\/p>\n<p>Both the signatures define three parameters, the last of which is optional. The first parameter, <code>type<\/code>, is a string representing the <em>event type<\/em> to listen (such as <code>click<\/code> and <code>focus<\/code>). <code>listener<\/code> defines the object containing a <code>handleEvent()<\/code> method or function that we wish to use as the event listener. The last parameter differs in the two signatures. <code>useCapture<\/code> is a Boolean that indicates if we want the function to be executed during the <a href=\"https:\/\/www.w3.org\/TR\/uievents\/#capture-phase\" target=\"_blank\" rel=\"noopener\">capture phase<\/a> (<code>true<\/code>) or the <a href=\"https:\/\/www.w3.org\/TR\/uievents\/#bubble-phase\" target=\"_blank\" rel=\"noopener\">bubble phase<\/a> (<code>false<\/code>). The default value for <code>useCapture<\/code> is <code>false<\/code>. The second signature has the <code>options<\/code> parameter which is an object that describes how the event listener will behave.<\/p>\n<p><small>The third parameter hasn&#8217;t always been optional. That&#8217;s why in very old code you might see the value <code>false<\/code> passed instead of relying on the default value.<\/small><\/p>\n<p>There are three properties that we can use at the moment for the <code>options<\/code> parameter, but the list is likely to grow in future:<\/p>\n<ul>\n<li><code>capture<\/code>: This option has the same meaning of <code>useCapture<\/code>, the last parameter of the first signature. The default value is <code>false<\/code>.<\/li>\n<li><code>passive<\/code>: A Boolean indicating if the listener will call the <a href=\"https:\/\/www.w3.org\/TR\/DOM-Level-2-Events\/events.html#Events-Event-preventDefault\" target=\"_blank\" rel=\"noopener\"><code>preventDefault()<\/code> method<\/a> (<code>false<\/code>) or not (<code>true<\/code>). If the value is set to <code>true<\/code> but the listener calls the method, the user agent will ignore the call to <code>preventDefault()<\/code> and generate a console warning. The default value for this property is <code>false<\/code>. <em>Passive event listeners<\/em> <q cite=\"https:\/\/github.com\/WICG\/EventListenerOptions\/blob\/gh-pages\/explainer.md\">enable developers to opt-in to better scroll performance by eliminating the need for scrolling to block on touch and wheel event listeners<\/q>. If you don&#8217;t need to call <code>preventDefault()<\/code> inside your function, I strongly encourage to set this value to <code>true<\/code>. The default value is <code>false<\/code>.<\/li>\n<li><code>once<\/code>: A Boolean specifying if the listener will only be invoked once after which it&#8217;ll be removed by the user agent. The default value is <code>false<\/code>.<\/li>\n<\/ul>\n<p>If you want to read more about passive event listeners, take a look at <a href=\"https:\/\/github.com\/WICG\/EventListenerOptions\/blob\/gh-pages\/explainer.md\" target=\"_blank\" rel=\"noopener\">the README file of the proposal<\/a> and at <a href=\"https:\/\/www.youtube.com\/watch?v=65VMej8n23A\" target=\"_blank\" rel=\"noopener\">this video<\/a>.<\/p>\n<p>Now that you know more about <code>addEventListener()<\/code>, let&#8217;s see an example.<\/p>\n<h3>An example of use of <code>addEventListener()<\/code><\/h3>\n<p>To see an event listener in action, imagine that we want to show a popup when a user clicks on a specific button. We also want the user to be able to close the popup by clicking a close button we&#8217;ll provide.<\/p>\n<p>To start, let&#8217;s take a look at the HTML that can help us with this scenario:<\/p>\n<pre><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;amp;lt;div class=&amp;amp;quot;popup&amp;amp;quot; hidden&amp;amp;gt;\n   &amp;amp;lt;h1&amp;amp;gt;Hello&amp;amp;lt;\/h1&amp;amp;gt;\n   &amp;amp;lt;p&amp;amp;gt;I'm a nice popup&amp;amp;lt;\/p&amp;amp;gt;\n   &amp;amp;lt;button class=&amp;amp;quot;close-button&amp;amp;quot;&amp;amp;gt;Close popup&amp;amp;lt;\/button&amp;amp;gt;\n&amp;amp;lt;\/div&amp;amp;gt;\n \n&amp;amp;lt;button class=&amp;amp;quot;open-button&amp;amp;quot;&amp;amp;gt;Show popup&amp;amp;lt;\/button&amp;amp;gt;\n<\/pre>\n<p>In the snippet above, we&#8217;ve defined a <code>button<\/code> element having <code>open-button<\/code> as a class name. This button will be used to show the popup when clicked. We have also created a <code>div<\/code> element representing the popup. The latter features a title (<code>h1<\/code>), a paragraph (<code>p<\/code>), and a button (<code>button<\/code>) that can be employed by the user to close the popup itself.<\/p>\n<p>With these elements in place, we are ready to define their behavior. The core of the short JavaScript code we need to write employs the <code>addEventListener()<\/code> method.<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst openButton = document.querySelector('.open-button');\nconst closeButton = document.querySelector('.close-button');\nconst popup = document.querySelector('.popup');\nconst hidePopupListener = {\n   handleEvent: function() {\n      popup.setAttribute('hidden', '');\n   }\n};\n\nopenButton.addEventListener('click', function() {\n   popup.removeAttribute('hidden');\n});\ncloseButton.addEventListener('click', hidePopupListener);\n<\/pre>\n<p>The snippet above relies on the first signature of <code>addEventListener()<\/code> but uses both a function and an object as the second argument. In the first call to <code>addEventListener()<\/code>, we pass a function as the second argument while the third is omitted (which is the same as passing <code>false<\/code>). So, the function will be executed during the bubble phase. In the second call, an object is employed as the second argument and the third is omitted.<\/p>\n<p>The final result is shown below and <a href=\"https:\/\/jsbin.com\/cihevi\/edit?html,css,js,output\" target=\"_blank\" rel=\"noopener\">it&#8217;s also available as a JS Bin<\/a>:<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"760\" data-permalink=\"https:\/\/www.audero.it\/blog\/2018\/04\/18\/in-depth-guide-event-listeners\/event-listeners-popup-example\/\" data-orig-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-popup-example.gif\" data-orig-size=\"600,384\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-popup-example.gif\" class=\"aligncenter size-full wp-image-760\" src=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-popup-example.gif\" alt=\"Showing and closing a popup with event listeners\" width=\"600\" height=\"384\" \/><figcaption>Showing and closing a popup with event listeners<\/figcaption><\/figure>\n<p>Thanks to this example, you should have a better idea of how <code>addEventListener()<\/code> works. But there is much more to say about it. So, let&#8217;s dig a bit more into event listeners and some of their less-known features.<\/p>\n<h3>Event listeners with the same conditions are executed once<\/h3>\n<p>Something that not many people know about <code>addEventListener()<\/code> is that <strong>if we add the same event<br \/>\nmultiple times, with the same conditions, it&#8217;ll be only executed once<\/strong>. To clarify this statement, let&#8217;s discuss an example.<\/p>\n<p>Imagine that we have a <code>showDialog()<\/code> function and we want to listen for two event types, for example <code>click<\/code> and <code>focus<\/code>, on the same button. Under these circumstances, <code>showDialog()<\/code> will be executed twice because the conditions are different (we are listening for different event types). But if we use the <code>showDialog()<\/code> function for the same event type (for example <code>click<\/code>) on the same button, it&#8217;ll be executed only once.<\/p>\n<p>In the example shown below, the <code>eventListener()<\/code> function will only be executed once because we&#8217;re calling it on the same element, with the same event type and phase.<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction eventListener() {\n   \/\/ Do something...\n}\n\nconst openButton = document.querySelector('.open-button');\nopenButton.addEventListener('click', eventListener);\nopenButton.addEventListener('click', eventListener);\n<\/pre>\n<p>The function would be executed twice if we had used it for the bubble phase the first time and the capture phase the second time.<\/p>\n<p>Another case worth mentioning is when an object is passed as the third argument. Because objects are passed by reference in JavaScript, you might expect that we have to provide the exact same object for two event listeners to be considered with the same conditions. Luckily, this is not the case. Two event listeners will be considered with the same conditions if the objects we provide have the same properties and values.<\/p>\n<p><a href=\"https:\/\/jsbin.com\/kilara\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">A demo of this concept is available as a JS Bin<\/a>.<\/p>\n<h3>The value of <code>this<\/code> inside an event listener<\/h3>\n<p>As discussed in the previous section, the second argument passed to <code>addEventListener()<\/code> can be either a function or an object. So far, we&#8217;ve always discussed examples of object literals being passed but we can use an instance of a class too. And that&#8217;s because class instances are, in fact, normal objects. They are just created with a different syntax.<\/p>\n<p>Take a look at the following snippet:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass Car {\n   constructor(brand) {\n      this.brand = brand;\n   }\n\n   handleEvent(event) {\n      console.log(event.type, this.brand);\n   }\n}\n\nconst myCar = new Car('Ferrari');\n<\/pre>\n<p>The <code>myCar<\/code> variable, pointing to an instance of the <code>Car<\/code> class, is a valid event listener because it&#8217;s an object and has a <code>handleEvent()<\/code> method.<\/p>\n<p>Inside the <code>handleEvent()<\/code> method we have a statement that prints on the console the event type, thanks to <code>event<\/code>, and the value of <code>this.brand<\/code>. If we pass <code>myCar<\/code> as the second argument to <code>addEventListener()<\/code>, when an event is triggered, the <code>handleEvent()<\/code> method will be executed. As a consequence, the event type and the string <samp>Ferrari<\/samp> will appear on the console. The reason is that <code>this<\/code> refers to the object pointed by the <code>myCar<\/code> variable, thus the value of the <code>brand<\/code> property is set to <code>Ferrari<\/code>.<\/p>\n<p><strong>If we pass a function to <code>addEventListener()<\/code>, the value of <code>this<\/code> is a reference to the event target. If we pass an object, the value of <code>this<\/code> is a reference to the object itself.<\/strong><\/p>\n<p>This discussion around the value of <code>this<\/code> inside an event listener might let you wonder what could be the benefits of using an object as a listener. This topic is covered in the next section.<\/p>\n<h3>Why using an object as an event listener?<\/h3>\n<p>One of the benefits of using an object is the possibility to store data. We can leverage this feature to store data that can help us managing the behavior of our web page. To better understand this concept, let&#8217;s discuss a simple example.<\/p>\n<p><small>JavaScript allows to add properties to functions too. This is possible because functions are executable objects. That is, in JavaScript, every function is actually an object with the additional feature of being executable. In the majority of the cases, objects remain the correct data structure to store data though.<\/small><\/p>\n<p>Our goal is to show a button that performs a given action only after another button has been clicked twice. Because the second button could not be completely ignored by the user, we don&#8217;t want to add the event listener for the first button unless it&#8217;s necessary. Moreover, to achieve our goal we need to keep track of the amount of time the second button is clicked.<\/p>\n<p>The following code is a possible solution for this case:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass EventListener {\n   constructor(button, hiddenButton) {\n      this.count = 0;\n      this.button = button;\n      this.hiddenButton = hiddenButton;\n   }\n\n   hiddenButtonHandler() {\n      console.log('I can log now!');\n   }\n\n   handleEvent(event) {\n      console.log('Click');\n      this.count++;\n      if (this.count === 2) {\n         this.hiddenButton.removeAttribute('hidden');\n         this.hiddenButton.addEventListener('click', this.hiddenButtonHandler);\n      }\n   }\n}\n\nconst button = document.querySelector('.button');\nconst hiddenButton = document.querySelector('.hidden-button');\nconst listener = new EventListener(button, hiddenButton);\n\nbutton.addEventListener('click', listener);\n<\/pre>\n<p><a href=\"https:\/\/jsbin.com\/disihaz\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">A demo of this example is available as a JS Bin<\/a>.<\/p>\n<p>Before moving to the next section, let&#8217;s discuss another interesting case. It shows how we can keep our code more organized by using an object as an event listener.<\/p>\n<p>By employing some naming conventions for the methods name of an object, we can create a class that has a <code>handleEvent()<\/code> method which delegates to other methods the action to perform when a given event occurs. In essence, we have the same entry point for different event types but then we use such entry point to delegate the actual action(s) to perform to other methods of the same object.<\/p>\n<p>A possible implementation is listed below:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass Listener {\n   constructor(element) {\n      this.element = element;\n   }\n\n   onBlur(event) {\n      \/\/ Do something when the blur event occurs\n      console.log('onBlur');\n   }\n\n   onClick(event) {\n      \/\/ Do something when the click event occurs\n      console.log('onClick');\n   }\n\n   onFocus(event) {\n      \/\/ Do something when the focus event occurs\n      console.log('onFocus');\n   }\n\n   handleEvent(event) {\n      const methodName = 'on' + event.type.replace(\/^.\/, function(matches) {\n         return matches&#x5B;0].toUpperCase();\n      });\n\n      this&#x5B;methodName](event);\n   }\n}\n<\/pre>\n<p>In this snippet, we create a class that has a constructor to which we can pass a DOM element. Such DOM element is stored into a property named <code>element<\/code>. We&#8217;ll use it to store the event target. The class also features a <code>handleEvent()<\/code> method, so an instance of such class can be used as an event listener. In addition, we&#8217;ve defined other three methods: <code>onBlur()<\/code>, <code>onClick()<\/code>, and <code>onFocus()<\/code>. We want to invoke these methods when the relevant event occurs. For example, we want to execute <code>onClick()<\/code> when the <code>click<\/code> event occurs.<\/p>\n<p>The most interesting part of the previous snippet is the body of the <code>handleEvent()<\/code> method. It invokes all the other methods by taking advantage of the event type. Inside <code>handleEvent()<\/code> we turn the first letter of the <code>type<\/code> property of the <code>Event<\/code> object passed to the function into uppercase. The result of this operation is concatenated to the string &#8220;on&#8221; and assigned to the <code>methodName<\/code> variable. Therefore, assuming that the <code>click<\/code> event was triggered, the value of <code>methodName<\/code> will be the string <code>\"onClick\"<\/code>. This explains how <code>handleEvent()<\/code> invokes the relevant method among those available.<\/p>\n<p><small>The approach described is not new and has been discussed <a href=\"https:\/\/esdiscuss.org\/topic\/better-way-to-maintain-this-reference-on-event-listener-functions#content-4\" target=\"_blank\" rel=\"noopener\">by other developers<\/a>.<\/small><\/p>\n<p>The final result is shown below and <a href=\"https:\/\/jsbin.com\/kicugak\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">it&#8217;s available as a JS Bin<\/a>:<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"761\" data-permalink=\"https:\/\/www.audero.it\/blog\/2018\/04\/18\/in-depth-guide-event-listeners\/event-listeners-object-as-event-listener\/\" data-orig-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-object-as-event-listener.gif\" data-orig-size=\"800,416\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-object-as-event-listener.gif\" class=\"aligncenter size-full wp-image-761\" src=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-object-as-event-listener.gif\" alt=\"Using an object as an event listener\" width=\"800\" height=\"416\" \/><figcaption>Example of using an object as an event listener<\/figcaption><\/figure>\n<p>If you want to know even more reasons on why you might want to use an object as an event listener, I recommend you to read the article <cite><a href=\"https:\/\/webreflection.medium.com\/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38\" target=\"_blank\" rel=\"noopener\">DOM handleEvent: a cross-platform standard since year 2000<\/a><\/cite> by <a href=\"https:\/\/webreflection.co.uk\" target=\"_blank\" rel=\"noopener\">Andrea Giammarchi<\/a>.<\/p>\n<p>So far, we&#8217;ve discussed a lot about the second argument of <code>addEventListener()<\/code>, but not a lot about the third one. Let&#8217;s dig into it.<\/p>\n<h3>Detecting support for the <code>options<\/code> parameter<\/h3>\n<p>The possibility to pass an object of options as the third argument to <code>addEventListener()<\/code> has been introduced with the <a href=\"https:\/\/www.w3.org\/TR\/2015\/REC-dom-20151119\/\" target=\"_blank\" rel=\"noopener\">W3C DOM Level 4 specifications<\/a>. This means that the first signature of <code>addEventListener()<\/code> has been around long before the second. Therefore, not all browsers we might want to support implement it and we should employ <a href=\"https:\/\/learn.microsoft.com\/en-us\/previous-versions\/windows\/internet-explorer\/ie-developer\/samples\/hh273397(v=vs.85)\" target=\"_blank\" rel=\"noopener\">feature detection<\/a> to establish if the browsers in use by our users support this feature.<\/p>\n<p>By adopting feature detection, we can make our code backward compatible. As you might know, in JavaScript an object is a <em>truthy<\/em> value. If the browser on which the code is running doesn&#8217;t support an object of options as the third argument, it&#8217;ll interpret the object as <code>true<\/code>. As a result, the event listener will be executed during the capture phase which might not be what we want. Another reason to use feature detection is that, except for <code>capture<\/code>, the properties available have been added at different times. So, we also have to check if the specific properties we want to use are supported.<\/p>\n<p>To test all the options available to date, we can employ the following <code>getOptionsAvailable()<\/code> function. It returns an object containing the options defined by the specifications as its properties and a Boolean specifying if the option is supported as its values. The value of a property will be <code>true<\/code> if the option is supported; <code>false<\/code> otherwise.<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction getOptionsAvailable() {\n   const optionsAvailable = {\n      capture: false,\n      passive: false,\n      once: false\n   };\n\n   try {\n      const eventListenerOptions = {};\n\n      Object\n         .keys(optionsAvailable)\n         .forEach(function(option) {\n            Object.defineProperty(eventListenerOptions, option, {\n               get: function() {\n                  optionsAvailable&#x5B;option] = true;\n               }\n            });\n         });\n\n      window.addEventListener('test', null, eventListenerOptions);\n   } catch (ex) {\n   } finally {\n      return optionsAvailable;\n   }\n}\n<\/pre>\n<p>In addition to testing the options available, we should also test if passing an object as the third argument is supported at all. To achieve this goal, we can use the following <code>isOptionsSupported()<\/code> function which relays on the previously defined <code>getOptionsAvailable()<\/code>:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction isOptionsSupported() {\n   return !!getOptionsAvailable().capture;\n}\n<\/pre>\n<p><a href=\"https:\/\/jsbin.com\/mowufip\/edit?js,console\" target=\"_blank\" rel=\"noopener\">A demo that shows both these functions in action is available as a JS Bin<\/a>.<\/p>\n<p>The examples discussed up to this point demonstrated how to add event listeners to the elements of a page. However, there are situations where we need to remove an event listener that we had previously added. In the next section we&#8217;ll examine how to achieve this goal.<\/p>\n<h2>Removing event listeners<\/h2>\n<p>Once an event listener is added, it typically remains in effect for the remainder of the page&#8217;s life. There are cases where an event listener is not needed anymore and we want to remove it. Consider, for example, a page where multiple steps are presented to the user and once a step has been completed, its controls revert to read-only. If we remove the associated event listeners, not only we avoid to run useless operations but also save memory.<\/p>\n<p>To remove event listeners which we previously added we can employ the <a href=\"https:\/\/www.w3.org\/TR\/DOM-Level-2-Events\/events.html#Events-EventTarget-removeEventListener\" target=\"_blank\" rel=\"noopener\"><code>removeEventListener()<\/code> method<\/a>. Like <code>addEventListener()<\/code>, the <code>removeEventListener()<\/code> method has two signatures:<\/p>\n<pre><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nremoveEventListener(type, listener&#x5B;, useCapture]);\nremoveEventListener(type, listener&#x5B;, options]);\n<\/pre>\n<p>The meaning of the parameters is the same as <code>addEventListener()<\/code>, so I won&#8217;t repeat their description.<\/p>\n<p>Removing an event listener is a bit more complex than you might expect. The first thing to know is that there is no such method like <code>removeEventListeners()<\/code> or <code>removeAllEventListeners()<\/code> that removes all event listeners from an event target. You need to remove the event listeners added to an event target one at a time. Moreover, in order <strong>to remove an event listener you need to keep a reference to it<\/strong>. This means that at the time you call <code>removeEventListener()<\/code>, you need to have something that points to the event listener, for example a variable. To better understand this concept, let&#8217;s see some examples.<\/p>\n<h3>Examples of use of <code>removeEventListener()<\/code><\/h3>\n<p>To start, we&#8217;ll take a look at a simple example. We&#8217;ll add an event listener on a button which will remove itself once executed. In essence, this is the same as setting the <code>once<\/code> property of the <code>options<\/code> parameter to <code>true<\/code>.<\/p>\n<p>The code to accomplish this is the following:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction eventListener(event) {\n   console.log('Executed!');\n   event.target.removeEventListener(event.type, eventListener);\n}\n\nconst button = document.querySelector('.button');\nbutton.addEventListener('click', eventListener);\n<\/pre>\n<p><a href=\"https:\/\/jsbin.com\/fenovox\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">A demo that shows this code in action is available as a JS Bin<\/a>.<\/p>\n<p>The previous example demonstrates the use of a function as the event listener. Let&#8217;s now see a case where we might want to add and then remove an object as an event listener.<\/p>\n<p>Imagine that we have a button which has an event listener added to it. The latter listens for the <code>click<\/code> event and it must be removed after a given user action, for example the user has checked a checkbox. So, we need to keep track of this state. By creating an object with a <code>isLastExecution<\/code> property and a <code>handleEvent()<\/code> method, we can solve this problem.<\/p>\n<p>The code to achieve this goal is listed below:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass Listener {\n   constructor(element) {\n      this.isLastExecution = false;\n      this.element = element;\n   }\n\n   addClickListener() {\n      this.element.addEventListener('click', this);\n   }\n\n   removeClickListener() {\n      this.element.removeEventListener('click', this);\n   }\n\n   handleEvent(event) {\n      console.log('Executed!');\n      if (this.isLastExecution) {\n         this.removeClickListener();\n      }\n   }\n}\n<\/pre>\n<p>The final result is shown below and <a href=\"https:\/\/jsbin.com\/fefugi\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">it&#8217;s available as a JS Bin<\/a>:<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"762\" data-permalink=\"https:\/\/www.audero.it\/blog\/2018\/04\/18\/in-depth-guide-event-listeners\/event-listeners-removing-event-listener\/\" data-orig-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-removing-event-listener.gif\" data-orig-size=\"800,412\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-removing-event-listener.gif\" class=\"aligncenter size-full wp-image-762\" src=\"https:\/\/www.audero.it\/blog\/wp-content\/uploads\/2018\/04\/event-listeners-removing-event-listener.gif\" alt=\"Removing an event listener\" width=\"800\" height=\"412\" \/><figcaption>Example of removing an event listener<\/figcaption><\/figure>\n<p>Finally, let&#8217;s see an example where we add and remove multiple event listeners from an element:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction eventListener(event) {\n   console.log('eventListener');\n}\nconst listener = function(event) {\n   console.log('listener');\n};\nconst myObject = {\n   handleEvent(event) {\n      console.log('handleEvent');\n   }\n};\n\nfunction customAddListeners(element) {\n   element.addEventListener('click', eventListener);\n   element.addEventListener('click', listener);\n   element.addEventListener('click', myObject);\n}\n\nfunction customRemoveListeners(element) {\n   element.removeEventListener('click', eventListener);\n   element.removeEventListener('click', listener);\n   element.removeEventListener('click', myObject);\n}\n\nconst button = document.querySelector('.button');\ncustomAddListeners(button);\n\nconst checkbox = document.querySelector('.checkbox');\ncheckbox.addEventListener('change', function(event) {\n   if (event.target.checked) {\n      customAddListeners(button);\n   } else {\n      customRemoveListeners(button);\n   }\n});\n<\/pre>\n<p>This example shows how we can add and remove event listeners of several types, functions and objects, from a button based on the checked state of a checkbox.<\/p>\n<p>We start the code with the definition of two functions and an object literal (<code>myObject<\/code>). In particular, the code shows a function declaration (<code>eventListener()<\/code>) and a function expression (<code>listener()<\/code>). All of them will be used as event listeners for the button. As mentioned, there is no way to add or remove more than one event listener at a time. So, we create two support functions, <code>customAddListeners()<\/code> and <code>customRemoveListeners()<\/code>, to achieve this goal.<\/p>\n<p>Then, we look up for the button in the page and enable the event listeners by calling <code>customAddListeners()<\/code>. Finally, we look up for the checkbox and add an event listener to it that listens for the <code>change<\/code> event. When this event occurs, we enable or disable the event listeners for the button based on the state of the checkbox.<\/p>\n<p><a href=\"https:\/\/jsbin.com\/cijumim\/edit?js,console,output\" target=\"_blank\" rel=\"noopener\">A live demo of this example is available on JS Bin<\/a>.<\/p>\n<p>The most observant of you might have noticed that I used an anonymous, inline function as the event listener for the checkbox. In most of the examples shown in this article, I&#8217;ve avoided using one for reasons that will be clarified in the next section.<\/p>\n<h2>Dangerous patterns<\/h2>\n<p>In this section we&#8217;ll cover some patterns that should be used sparingly because they have drawbacks.<\/p>\n<p>Let&#8217;s start our discussion with anonymous, inline functions. They can be used as event listeners but you should almost always avoid them because, once added, they can&#8217;t be removed. The reason is that we don&#8217;t have any reference pointing to them that we can pass to <code>removeEventListener()<\/code>. So, only use anonymous, inline functions when you&#8217;re absolutely sure that the event listener has to be kept until a user leaves the page.<\/p>\n<p>To help you visualize this situation, take a look at the following snippet:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst button = document.querySelector('.button');\nbutton.addEventListener('click', function() { \/* Some logic here *\/ });\nbutton.removeEventListener('click', ?????);\n<\/pre>\n<p>You might wonder why we care so much about removing event listeners. On one hand it&#8217;s because event listeners are stored in the browser&#8217;s memory and the memory is limited. So, if we never clean it up by removing event listeners that are not relevant anymore, we end up in a situation where the page takes up all the memory it can until the browser tab crashes. On the other hand, event listeners consume CPU time because they are executed every time the relevant event occurs. And if we haven&#8217;t removed event listeners that are not necessary anymore, we&#8217;re just wasting CPU time and slowing down our web page.<\/p>\n<p>The example above is not the only dangerous pattern. In the same way we can use an anonymous function to <code>addEventListener()<\/code>, we can pass an object literal that is not assigned to a variable first. Therefore, we don&#8217;t have a reference to it which means we can remove the event listener.<\/p>\n<p>Consider the following example:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nconst button = document.querySelector('.button');\nbutton.addEventListener('click', {\n   handleEvent: function() { \/* Some logic here *\/ }\n});\nbutton.removeEventListener('click', ?????);\n<\/pre>\n<p>The last cases I want to mention are the use of an inline, arrow function and the use of <code>bind()<\/code>. If we don&#8217;t store them somewhere (like a variable), we won&#8217;t have a way to remove the event listener. Examples of these patterns are shown below:<\/p>\n<pre><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nfunction listener() { \/* Some logic here *\/ }\n\nconst button = document.querySelector('.button');\nconst anotherElement = document.querySelector('.element');\nbutton.addEventListener('click', () =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; { \/* Some logic here *\/ });\nbutton.addEventListener('click', listener.bind(anotherElement);\nbutton.removeEventListener('click', ?????);\n<\/pre>\n<p>The list of cases described in this section is non-exhaustive, but all the others are a combination or very similar to the ones presented. So, you should have all the knowledge required to spot a bad pattern and avoid it.<\/p>\n<h2>Conclusions<\/h2>\n<p>In this in-depth tutorial I have introduced you to the definitions given by the <abbr title=\"World Wide Web Consortium\">W3C<\/abbr> and the <abbr title=\"Web Hypertext Application Technology Working Group\">WHATWG<\/abbr> for an event listener and an event target. The specifications revealed us that an object featuring a <code>handleEvent()<\/code> method can be used as an event listener too, something that not many developers know.<\/p>\n<p>Then, we examined <code>addEventListener()<\/code> which allows to add an event listener on an event target. While discussing this method, we&#8217;ve seen the parameters defined in its signature and the different values we can pass. We&#8217;ve also analyzed how to detect the support for the new <code>options<\/code> parameter, introduced in the DOM level 4 specifications. Moreover, we have discovered that different browsers support different properties of this new parameter. So, we have discussed a function that allows us to detect which properties are supported.<\/p>\n<p>Finally, I&#8217;ve described the two signatures of the <code>removeEventListener()<\/code> method, which we can use to remove event listeners, and some of the patterns we should avoid.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When creating interactive web pages, developers often need to execute some actions when a given event occurs. Changing the image of a carousel when a user clicks on one of its arrows, showing a tooltip when a word is hovered, or validating a field when a user moves the focus onto another field are common examples. To execute these actions, we have to add event listeners to the elements of the page.<\/p>\n<p>In this article, I&#8217;ll explain what event listeners are, and how to add and remove them from a web page.  I&#8217;ll show several examples and talk about patterns to avoid when dealing with event listeners. The topic will be discussed in depth. So, even if you&#8217;re an expert, you might not know some of the details covered.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[19,61,62,59,78,77,60,46,45,43,11,44],"class_list":["post-539","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-browser","tag-bubble-phase","tag-capture-phase","tag-dom","tag-event-handler","tag-event-listener","tag-event-phases","tag-javascript","tag-standard","tag-w3c","tag-web","tag-whatwg"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9Or4e-8H","jetpack-related-posts":[{"id":524,"url":"https:\/\/www.audero.it\/blog\/2018\/05\/16\/event-delegation-in-javascript\/","url_meta":{"origin":539,"position":0},"title":"Event delegation in JavaScript","author":"Aurelio De Rosa","date":"May 16, 2018","format":false,"excerpt":"One of the most common tasks a web developer deals with is to add event listeners to the elements of a page. Event listeners are employed to perform one or more actions when a given event occurs on one or more elements. For example, by using an event listener we\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/08\/event-delegation.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":832,"url":"https:\/\/www.audero.it\/blog\/2018\/07\/20\/5-javascript-interview-questions-a-mid-level-developer-should-be-able-to-answer\/","url_meta":{"origin":539,"position":1},"title":"5 JavaScript interview questions a mid-level developer should be able to answer","author":"Aurelio De Rosa","date":"July 20, 2018","format":false,"excerpt":"According to the results of the 2018's StackOverflow survey, JavaScript is the most popular technology. The amount of job offers for JavaScript developers is constantly increasing and with more companies adopting JavaScript as their main language, it's easy to find good ones. But before you are hired by a company,\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"job interview panel","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2016\/06\/job-interview-panel.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":339,"url":"https:\/\/www.audero.it\/blog\/2014\/10\/18\/state-web-notifications-api\/","url_meta":{"origin":539,"position":2},"title":"The State of the Web Notifications API","author":"Aurelio De Rosa","date":"October 18, 2014","format":false,"excerpt":"Today I was reviewing my HTML5 API demos repository to keep its information updated and relevant. In the last two weeks Google has released\u00a0Chrome 38, Opera has released Opera 25, and Mozilla has released Firefox 33.\u00a0Every time a new version of a browser is available, it may\u00a0introduce support for new\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"push notifications","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/10\/push-notifications.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/10\/push-notifications.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2014\/10\/push-notifications.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":217,"url":"https:\/\/www.audero.it\/blog\/2013\/11\/05\/my-experience-at-codemotion-madrid-2013\/","url_meta":{"origin":539,"position":3},"title":"My Experience at Codemotion Madrid 2013","author":"Aurelio De Rosa","date":"November 5, 2013","format":false,"excerpt":"As I announced in September, on the 19th October 2013 I spoke at Codemotion Madrid 2013 presenting a talk titled People don't give a f**k of JavaScript, where I showed some new HTML5 APIs. This article is a wrap up of my experience at the event, both as a speaker\u2026","rel":"","context":"In &quot;Discussions &amp; Opinions&quot;","block_context":{"text":"Discussions &amp; Opinions","link":"https:\/\/www.audero.it\/blog\/category\/discussions-opinions\/"},"img":{"alt_text":"Friends of Codemotion Madrid 2013","src":"https:\/\/i0.wp.com\/aurelio.audero.it\/blog\/wp-content\/uploads\/2013\/11\/friends-of-codemotion-madrid-2013-300x225.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":203,"url":"https:\/\/www.audero.it\/blog\/2013\/10\/15\/codemotion-madrid-2013-giveaway-win-a-free-copy-of-instant-jquery-selectors\/","url_meta":{"origin":539,"position":4},"title":"Codemotion Madrid 2013 Giveaway: Win a Free Copy of Instant jQuery Selectors","author":"Aurelio De Rosa","date":"October 15, 2013","format":false,"excerpt":"As some of you may be already aware, on Saturday October 19th 2013 I'll speak at Codemotion Madrid with a talk titled People don't give a f**k of JavaScript. If you didn't know it, it's because you don't follow me on Twitter and you're a bad guy or girl. Anyway,\u2026","rel":"","context":"In &quot;General&quot;","block_context":{"text":"General","link":"https:\/\/www.audero.it\/blog\/category\/general\/"},"img":{"alt_text":"Instant jQuery selectors cover","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2013\/10\/instant-jquery-selectors-cover.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":413,"url":"https:\/\/www.audero.it\/blog\/2015\/10\/17\/upload-files-on-github-using-github-js\/","url_meta":{"origin":539,"position":5},"title":"Upload files on GitHub using Github.js","author":"Aurelio De Rosa","date":"October 17, 2015","format":false,"excerpt":"For a few months now, I have been working on a project that employs the GitHub APIs. The application I'm\u00a0building is completely client-side and provides a feature to upload files to a repository on GitHub. To simplify the\u00a0interaction with the API, I'm\u00a0using a library called Github.js. In this article, I'll\u2026","rel":"","context":"In &quot;JavaScript&quot;","block_context":{"text":"JavaScript","link":"https:\/\/www.audero.it\/blog\/category\/javascript\/"},"img":{"alt_text":"github social coding","src":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2015\/10\/github-social-coding.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2015\/10\/github-social-coding.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2015\/10\/github-social-coding.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.audero.it\/blog\/wp-content\/uploads\/2015\/10\/github-social-coding.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/539","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/comments?post=539"}],"version-history":[{"count":75,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/539\/revisions"}],"predecessor-version":[{"id":1061,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/posts\/539\/revisions\/1061"}],"wp:attachment":[{"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/media?parent=539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/categories?post=539"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.audero.it\/blog\/wp-json\/wp\/v2\/tags?post=539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}