user2233208
user2233208

Reputation:

addEventListener to ALL INPUT elements when DOM changes

At the moment I'm doing the following when the document is complete.

var passwordInputs = document.querySelectorAll("input[type=password]");

for (index = 0; index < passwordInputs.length; ++index) {
    passwordInputs[index].addEventListener("focusin", activeWordsFocusIn);
    passwordInputs[index].addEventListener("focusout", activeWordsFocusOut);
}

Which works as expected. However if the page has some additional script which modifies the DOM and adds more input elements then they are not hooked.

How can add event handlers for ALL input elements, even those added to the DOM thru script/ajax?

Not a duplicate I don't consider this a duplicate as this question Detect Changes in the DOM which focuses on detecting changes in the DOM. My questions focus is on adding an eventListener to all input elements even when the DOM changes. I have since added my own answer to this now.

Upvotes: 5

Views: 15682

Answers (3)

Karsan Chavda
Karsan Chavda

Reputation: 11

var inputs = document.querySelectorAll("input");
inputs.forEach((input) => {
    input.addEventListener("click", (event) => {
        console.log("Clicked:", event.target.name);
        console.log("Value of Clicked Input:", event.target.value);
    });
});

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191976

You can use event delegation to add an event handler to the container of the inputs. When an element inside the container triggers an event, we check if the element matches the selector, and if so, the event handler is called.

const delegate = (selector) => (cb) => (e) => e.target.matches(selector) && cb(e);

const inputDelegate = delegate('input[type=password]');

container.addEventListener('focusin', inputDelegate((el) => console.log('focus in', el.target.name)));

container.addEventListener('focusout', inputDelegate((el) => console.log('focus out', el.target.name)));

setTimeout(() => {
  const input = document.createElement('input');
  input.setAttribute('type', 'password');
  input.setAttribute('name', 'input2');
  
  container.append(input);
}, 2000);
<div id="container">
  <input type="password" name="input1">
</div>

Upvotes: 10

user2233208
user2233208

Reputation:

This is the solution I have found that works...

function activeWordsFocusIn(e) {
    if (isPassword(e)) {
        console.log("focus in");
    }
}

function activeWordsFocusOut(e) {
    if (isPassword(e)) {
        console.log("focus out");
    }
}

function isPassword(e) {
    var e = window.e || e;

    if (e.target.tagName !== 'INPUT')
        return false;

    if (e.target.type !== 'password')
        return false;

    return true;
}

document.addEventListener('focusin', activeWordsFocusIn, false);
document.addEventListener('focusout', activeWordsFocusOut, false);

Upvotes: 2

Related Questions