Secret
Secret

Reputation: 27

How to use this.onclick to check the buttons Id

There are 5 buttons where each button will do a different thing.

The first button will change a paragraph to green (in HTML file, Id="button1").

The second button will change a paragraph to blue (in HTML file, Id="button2").

window.onload = pageLoad;

function pageLoad() {
  this.onclick = makeChange;
}

function makeChange() {
  var paragraph = document.getElementById("paragraph");
  if (this.id = "button1") {
    paragraph.style.color = "green";
  } else {
    // change the color
  }
}

This doesn't work because I can't get the id of the button, I tried to debug it using:

paragraph.innerHTML = this.id;// I got "undefined"

Is there anyway I can get which button is pressed, and based on which button is pressed, change the text color differently? I want to use only 1 function(exclude pageLoad) to do this and I don't to have 5 variableS and 5 onclick lines and no .

var paragraph = document.GetElementById("button1");
var paragraph = document.GetElementById("button2");
var paragraph = document.GetElementById("button3");
....

Upvotes: 1

Views: 185

Answers (2)

zer00ne
zer00ne

Reputation: 43910

Using an event listener to leverage Event Delegation has a few advantages over an on event (ex. onclick) property or attribute event handler:

  • Unlike on event handlers, event listeners can be used multiple times on multiple objects and elements.

  • By setting the 3rd parameter to true, you can listen for events in capture phase. It's rarely needed.

  • We can setup a pattern to take advantage of the 3 Event.eventPhases:

    1. Capture: Starting from Event.currentTarget (ex. #set) the event chain goes down the DOM tree to the end of this phase is...
    2. Target: The element that is the origin of the event is the Event.target (ex. #btn*).In simpler terms, e.target is the element clicked, checked, changed, etc. This element will be the context related to the event, in many ways e.target is like this (in this demo, e.target is one of the buttons and this is the ancestor (fieldset#set, e.cT)...
    3. Bubbling: This is the phase after the callback is initiated and the event chain reverses its path back up to the Event.currentTarget. On its way up, should there be any other elements registered to this particular event would also be triggered. This may be an unwanted behavior depending on the developer's intentions and circumstances. For those cases, Event.stopPropagation() can be called (usually placed as the last statement in the callback). Upon reaching the end of the bubbling phase, the e.cT calls the callback (this callback will be in the context of e.target, this context allows us to identify the clicked button)
  • Event Delegation is a process in which we setup our event listener on a higher level in the DOM (an ancestor element), then at target phase the clicked button will be identified by referencing e.target. This gives us a powerful and eloquent way to handle an unlimited amount of elements with a single event listener. No on event handler is capable of doing this under normal circumstances without the use of specialized interface.

More details are commented in demo

Demo

/* Reference an ancestor element of all the buttons.
|| In this case the best choice would be 
|| fieldset#set. You could also use <body>, document,
|| or even window, but the further the ancestor is,
|| the chances of unwanted behavior from other elements
|| become greater.
*/
var set = document.getElementById('set');

/* Register #set on the click event.
|| Now #set is considered the Event.currentTarget.
|| The e.cT (#set) will listen for the event (click)
|| to occur upon itself and any of its decsendants.
|| Once event occurs, #set (e.cT) will run the
|| callback function (findBtn).
*/
set.addEventListener('click', findBtn, false);

/* This is the callback function which is a normal
|| function that is called when a registered event
|| happens.
*/
function findBtn(e) {

  // An array of 5 colors
  var rainbow = ['purple', 'blue', 'green', 'yellow', 'red'];

  // Reference to the paragraph (<p>)
  var text = document.querySelector('p');

  /* if e,target (the element clicked), is NOT
  || e.cT, then...
  */
  if (e.target !== e.currentTarget) {

    /*...and if e.T (Event.target) tagName is 
    || 'BUTTON', then...
    */
    if (e.target.tagName === 'BUTTON') {

      // ...get the button's #id
      var tgtID = e.target.id;

      /* The id of each button is basically just
      || an index number. Although I do not
      || recommend it normally, it is valid to start
      || with a number for an #id. 
      || This statement uses the style property to
      || access the paragraph's CSS color property
      || and changes the value according to the 
      || index of the rainbow array which in turn is
      || determined by the e.T (button clicked) #id
      */
      text.style.color = rainbow[tgtID];

    }

  }
  // End function 
  return false;
}
<fieldset id='set'>
  <legend>Event Delegation</legend>
  <button id='0'>Purple</button>
  <button id='1'>Blue</button>
  <button id='2'>Green</button>
  <button id='3'>Yellow</button>
  <button id='4'>Red</button>
</fieldset>

<p>Click any of the five buttons to change this text.</p>

Upvotes: 1

Michael Evans
Michael Evans

Reputation: 1011

You could try something like this. Keep the color you want to change the paragraph to inside the button, using a custom data-* attribute. Then access it with .getAttribute(). So your JS would be something like this:

function makeChange() {
  var paragraph = document.getElementById("paragraph");
  var newColor = this.getAttrbiute('data-color');
  paragraph.style.color = newColor;
}

And your buttons would be like this:

<button data-color="green">Green</button>
<button data-color="blue">Blue</button>

This way you can easily change the target color by changing the data-color attribute.

As a side note, do make sure you're listening for the click event with your buttons, like this:

var buttons = document.querySelectorAll('button');

for (var i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', makeChange);
}

Upvotes: 1

Related Questions