Simple examples of Event Listeners in Javascript

Hi there,

I have written a small example above and it does what it was supposed to do, but I believe that there would be a better way to write this.

P.S The program converts to UpperCase.

have you not considered doing away with the JavaScript?

coothead

1 Like

I posted so that someone can give insight if there are any ways to do it in some other way maybe not categorized as better or worst but an alternative way of writing code - the more polished one.

I think that this can be further refined as →

document.getElementById("name").addEventListener("onblur", caseCheck);

Instead of putting the function in the HTML Input element.

Hi there codeispoetry,

I always consider JavaScript to be the last resort.

This would be my first resort…

input{
  text-transform: uppercase;
 }

coothead

3 Likes

I ended up creating one more small programme, but seems to be having some error as its not delivering what it was supposed to deliver.

Hi there codeispoetry,

you have a typing error…

document.getElementById("button").addEventListener("onclick", copyNow);

It should be…

document.getElementById("button").addEventListener("click", copyNow);

coothead

2 Likes

You came here looking for a better way. A better way is with no JavaScript at all.

I agree with @coothead - CSS is a better way to achieve the uppercase that you are looking for.

#name {
  text-transform: uppercase;
}

It’s not so uncommon to go without JavaScript either. There are plenty of things that can be done without JavaScript at all these days.

2 Likes

Hi There @Paul_Wilkins

Actually, I was looking for better(If there are any) ways within the domain of JS.

I was revising what I learned and left in August last year so was building some small programs with fundamentals that deliver those concepts. Someone who has years of experience and Knack on the subject can give some insight as compared to me who is still in the very early phases of learning. That was the objective when I write those lines: better ways. The point I missed was better ways while we stay within JS.

Apple(My version) was compared to Apple(someone else version). Not Apple with dry Fruits(CSS as pointed out).

Thanks for sharing that resource that was awesome.

1 Like

Now that the CSS squad is done putting down Javascript… and we can take for gratis that the user is attempting to write cleaner javascript, rather than this specific example having a CSS solution…

I would capture the element instead of the value in your function.

function caseCheck() {
  var name = document.getElementById("name").value;
  document.getElementById("name").value = name.toUpperCase();
}

=>

function caseCheck() {
  var name = document.getElementById("name");
  name.value = name.value.toUpperCase();
}

An element reference is a live pointer, meaning you can continue to access its properties. Once you define name to be the value, you’ve copied a string into memory that no longer has a link to the element it came from, and you dont need to have your code look up the element again (which is a more costly process)

6 Likes

Thanks for the understanding and thanks for refining the code.

I was trying to make use of onfocus vs onblur.
I think I was able to do it the old school method →


Field 1: <input type="text" id="text1" onfocus="activeField(id)" onblur="revertBack()"><br><br>
Field 2: <input type="text" id="text1" onfocus="activeField(id)" onblur="revertBack()"><br><br>

function activeField(x) {
	document.getElementById(x).style.background="yellow";
} 

function revertBack(x) {
	document.getElementById(x).style.background="none";
}

I was not sure how can I organize the code flow with the below mentioned method:

document.getElementById("name").addEventListener("onblur", caseCheck)

addEventListener method.

Remove the “on”.

On the matter of improvements to the code:

Access the element instead of the element value

By accessing the element, you have an easier way to get back to it with the updated value.

  var nameField = document.getElementById("name");
  nameField.value = nameField.value.toUpperCase();

Use the event object to access the form field

Instead of directly getting the name field, it’s more appropriate to use the event object to access it instead. That way when the field gets renamed, you won’t need to update that part of the scripting code at all.

function caseCheck(evt) {
  var inputField = evt.target;
  inputField.value = inputField.value.toUpperCase();
}

I also renamed nameField to a more generic name of inputField, so that the caseCheck function will have a less confusing time of being used with other form fields too.

Assign events from JavaScript

Currently the code is using an inline event hander, which conflicts strongly with the principle of clearly separating HTML, CSS, and JS code.

More appropriate is to use addEventListener instead.

Enter Name: <input type="text" id="name">
var nameField = document.getElementById("name");
nameField.addEventListener("blur", caseCheck);

Prefer verb-noun instead of noun-verb

The function name of caseCheck is more suitably named when it starts with the verb, i.e., checkCase instead.

function checkCase(evt) {
  ...
}
...
nameField.addEventListener("blur", checkCase);

Summary

We end up with simpler HTML code:

Enter Name: <input type="text" id="name">

and JS code that gives better information about what happens.

function checkCase(evt) {
  var inputField = evt.target;
  inputField.value = inputField.value.toUpperCase();
}
var nameField = document.getElementById("name");
nameField.addEventListener("blur", checkCase);
3 Likes

Hi there everyone,

In the current old school method →

The Programme is not working fine.

Anticipated result →

When clicked onfocus event should be triggered and when clicking somewhere else onblur events should trigger.

Once it is figured out why the current program is not working I will try to write the program in the event object method.

Current Update:
I was able to fix as it was a typo error.

Applying similar techniques to this other set of code:

Field 1: <input type="text" id="text1" onfocus="activeField(id)" onblur="revertBack()"><br><br>
Field 2: <input type="text" id="text1" onfocus="activeField(id)" onblur="revertBack()"><br><br>

function activeField(x) {
	document.getElementById(x).style.background="yellow";
} 

function revertBack(x) {
	document.getElementById(x).style.background="none";
}

Remove the inline event attributes

There are no good reasons for using inline event attributes. Those all get removed, leaving us with easier to understand HTML code.

Field 1: <input type="text" id="text1"><br><br>
Field 2: <input type="text" id="text1"><br><br>

Unique identifiers must be unique

The text1 id cannot be successfully repeated. Using different numbers is bad too, such as text1 and text2. Much more suitable is to use class names instead.

Field 1: <input type="text" class="showActive"><br><br>
Field 2: <input type="text" class="showActive"><br><br>

Assign events from JavaScript

We want to assign events to the HTML elements that have the showActive class name. That means getting a list of those elements, and looping through them.

var showActiveFields = document.querySelectorAll(".showActive");
showActiveFields.forEach(function addEvents(field) {
  //...
});

We can now assign the activeField and revertBack functions to the different field events:

var showActiveFields = document.querySelectorAll(".showActive");
showActiveFields.forEach(function addEvents(field) {
  field.addEventListener("focus", activeField);
  field.addEventListener("blur", revertBack);
});

We can now update the functions so that they work. Currently they expect to receive an id name. We should update the functions so that they get the element from the event object instead.

function activeField(evt) {
  var inputField = evt.target;
	inputField.style.background = "yellow";
} 

function revertBack(evt) {
	var inputField = evt.target;
  inputField.style.background = "none";
}

The code now works, but there are still remaining some sins to correct.

Use paragraph tag instead of br

The break tag should only be used for two purposes. One is to separate lines when showing an address, and the other is for poetry. There are no other reasons or excuses for using the break tag. Paragraphs are used instead.

<p>Field 1: <input type="text" class="showActive"></p>
<p>Field 2: <input type="text" class="showActive"></p>

Use similar function names for similar behaviour

The activeField and revertBack function names don’t tell you that they are a matched set, designed to turn something on and turn that same thing off.

More suitable names are activateField and deactivateField

function activateField(evt) {
  ...
} 
function deactivateField(evt) {
  ...
}
...
  field.addEventListener("focus", activateField);
  field.addEventListener("blur", deactivateField);

Update class name instead of changing style

It’s not JavaScript’s job to fiddle around with style attributes. Instead, define some CSS that properly does the job, so that you can add and remove that CSS class name.

.active {
  background: yellow;
}
function activateField(evt) {
  var inputField = evt.target;
  inputField.classList.add("active");
} 
function deactivateField(evt) {
  var inputField = evt.target;
  inputField.classList.remove("active");
}

Summary

We are now left with simple code that does the job.

<p>Field 1: <input type="text" class="showActive"></p>
<p>Field 2: <input type="text" class="showActive"></p>
.active {
  background: yellow;
}
function activateField(evt) {
  var inputField = evt.target;
  inputField.classList.add("active");
} 
function deactivateField(evt) {
  var inputField = evt.target;
  inputField.classList.remove("active");
}

var showActiveFields = document.querySelectorAll(".showActive");
showActiveFields.forEach(function addEvents(field) {
  field.addEventListener("focus", activateField);
  field.addEventListener("blur", deactivateField);
});
2 Likes

Just because we know how to use JavaScript, doesn’t mean that it should be used for everything.

An even better way is to get rid of all that JavaScript code and use the following CSS code instead.

.showActive:focus {
  background: yellow;
}

https://jsfiddle.net/19wo07rg/

Why do people want to complicate things so much? Just use the right tool for the job.

2 Likes

I think this is more about getting familiar with events and handling them, rather than specific tasks.

An alternative might be to wrap that HTML in form tags, then use event delegation to listen to the events bubble up.

Forms also come with their own elements property, which avoids having to search the DOM for a particular field. MDN formElement.elements

<form id='form1'>
  <label for='field1'>First Field:</label>
  <input type='text' id='field1' name='field1'>
  <label for='field2'>Second Field:</label>
  <input type='text' id='field2' name='field2'>
  <label for='field3'>Third Field:</label>
  <input type='text' id='field3' name='field3'>
</form>
const form = document.querySelector('#form1')

const setBackgroundColor = (elem, color = '') => (
  elem.style.backgroundColor = color
)

// let the events bubble up to the form element instead
// I'm using focusin instead of focus to make that work
form.addEventListener('focusin', (event) => {
  console.log(`focused on ${event.target.name}`)
  setBackgroundColor(event.target, 'yellow')
})

// and focusout instead of blur
form.addEventListener('focusout', (event) => {
  console.log(`blurred from ${event.target.name}`)
  setBackgroundColor(event.target, 'white')
})

2 Likes

That’s correct you have put it very precisely @rpg_digital

@Paul_Wilkins

You have been very nice to me since the first day. There was a point when I do not use to even understand what is event object, but you were so highly committed when writing posts that may require at least 1 hour in its publishing I used to nod my head then because it would be disrespectful to a person who is investing so much time.

Analogy: Focus is very wanton in nature. There are many mindful cultures such as zen where it is advocated you cant meditate you can just be mindful and the key to mindfulness is watchfulness. To substantiate the above premise no one can say I am preparing to win the Wimbledon Champion,but one can only practice evolve and become a great tennis player. The trophy is the highest state of that Journey, a peak of the mountain.

The above analogy is connected to the current situation, when attempting to learn JS I find this a skewed judgment that this is better possible in CSS. In a real-life application, it should be, but on the Road to JS css is another man’s wife.

English is not my first language and I know it was slightly Rhetoric.

In the current situation, it may appear that this is not the best way, but the competition for the best way is not among many programming schools or paradigms, but with in JS itself.

Thank you so much for your understanding and thank you so much for all the help that you have given in yesteryears.

In real life application this will be a very optimized method to write a code →

2 Likes

I also eneded up creating another simple program using Keydown function →

Comment, Criticism and scope of suggestions, including alternative ways of writing, will be highly appreciable. Thank you so much for keeping the patience in my endeavors.