gretagremlin
gretagremlin

Reputation: 33

How to simplify Javascript on buttons with repetitive event handlers?

I am new to coding and I have been trying to learn buttons and event handlers. If there were say 50 buttons, what would be a simpler way to manage the listed event handlers so the code does not become repetitive/polluted.

function addText(add) {
  document.getElementById('words').value = add.value;
}

function takeText(take) {
  document.getElementById('words').value = document.getElementById('words').value.replace(take.value, '');
}
<button value="example 1" onmouseover="addText(this)" onmouseout="takeText(this)">Button1</button>
<button value="example 2" onmouseover="addText(this)" onmouseout="takeText(this)">Button2</button>
<button value="example 3" onmouseover="addText(this)" onmouseout="takeText(this)">Button3</button>

<input type="text" id="words">

Upvotes: 1

Views: 70

Answers (2)

Roko C. Buljan
Roko C. Buljan

Reputation: 206565

  • Remove inline JS, try to keep JS all in one place for easier debugging and for separation of concerns
  • Add a common class .btnWord to all of your desired buttons
  • Use mouseenter mouseleave events with Element.addEventListener() to trigger your specific function actions

const el_btnWord = document.querySelectorAll('.btnWord');
const el_words = document.querySelector('#words');

const fn_setWord = (ev) => el_words.value = ev.target.value;
const fn_clearWord = () => el_words.value = '';


el_btnWord.forEach(el => {
  el.addEventListener('mouseenter', fn_setWord);
  el.addEventListener('mouseleave', fn_clearWord);
});
<button class="btnWord" value="example 1">Button1</button>
<button class="btnWord" value="example 2">Button2</button>
<button class="btnWord" value="example 3">Button3</button>


<input type="text" id="words">

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/en-US/docs/Web/API/Event/target
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll


UI consideration

Since personally it makes no sense to change an input value on mouseenter - to than remove it on mouseleave, what I suggest is (if that's the desired UX) to use placeholder, and change the value only on click:

const el_btnWord = document.querySelectorAll('.btnWord');
const el_words = document.querySelector('#words');

const fn_setPH = (ev) => el_words.placeholder = ev.target.value;
const fn_clearPH = () => el_words.placeholder = '';
const fn_setVAL = (ev) => el_words.value = ev.target.value;


el_btnWord.forEach(el => {
  el.addEventListener('mouseenter', fn_setPH);
  el.addEventListener('mouseleave', fn_clearPH);
  el.addEventListener('click', fn_setVAL);
});
<button class="btnWord" value="example 1">Button1</button>
<button class="btnWord" value="example 2">Button2</button>
<button class="btnWord" value="example 3">Button3</button>


<input type="text" id="words">

Upvotes: 1

Ramon Portela
Ramon Portela

Reputation: 409

You can do that with javascript querySelector and add events to the elements.

Its also considered a better practice to add event to the elements at the javascript code.

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

buttons.forEach(button => {
   button.addEventListener('onmouseover', addText);
   button.addEventListener('takeText', takeText);
});

Upvotes: 0

Related Questions