简体   繁体   中英

not able to access DOM object property

I created an array of all the input elements in a form, then looped through the array and tried to access the DOM element object through the array. But it gives the error "Cannot read property 'addEventListener' of null"

 window.addEventListener("DOMContentLoaded", function() {
    var paraC = document.querySelectorAll('.form-container p input');

    for (var i = 0; i < paraC.length; i++) {

        var inputField = document.getElementById(paraC[i].getAttribute('id'));
        console.log(inputField); // gives null
        inputField.addEventListener('onfocus', helperNote, false);
    }




    function helperNote() {
        var notePlace = document.querySelector('.form-container');
        var note = document.createElement('p')
        notePlace.appendChild(note);
        console.log('event fired');
    }
}, false);

The HTML Code

<section>
            <h3>Sign-Up Form</h3>
            <form method="post">
                <div class="form-container">
                    <p>Fill The Form Below</p>
                    <p>
                        <label>Email :</label>
                        <input type="email" name="email" id="email">
                    </p>
                    <p>
                        <label>Name :</label>
                        <input type="text" name="Name" id="Name">
                    </p>
                    <p>
                        <label>Age :</label>
                        <input type="number" name="age" id="age">
                    </p>
                    <p>
                        <input type="submit" name="submit" value="sign-up">
                    </p>
                </div>
            </form>
        </section>

It would be simpler to just use forEach :

document.querySelectorAll('.form-container p input')
    .forEach(function(inputField) {
         inputField.addEventListener('onfocus', helperNote, false);
    })

Using forEach()

forEach() executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (ie on sparse arrays).

Other than the use of forEach() , I have included another important fix;

  • When using addEventListener() to listen for element focus we state the event type as " focus " not " onfocus ".
  • If you don't want a helper note to be shown when the <input type="submit"> button gets focus , we can filter it out using the :not() pseudo-class in our querySelectorAll() .
  • You may want to include some handling to avoid helper notes multiplying in your form; currently, every time one is added, any that were already there remain; it could get quite crowded!

 window.addEventListener("DOMContentLoaded", function() { document.querySelectorAll('.form-container input:not([type=submit])') .forEach( function( inputField ) { console.log(inputField); inputField.addEventListener('focus', helperNote, false); } ); function helperNote() { var notePlace = document.querySelector('.form-container'); var note = document.createElement('p'); note.textContent = "Helper Note"; notePlace.appendChild(note); console.log('event fired'); } }, false); 
 <section> <h3>Sign-Up Form</h3> <form method="post"> <div class="form-container"> <p>Fill The Form Below</p> <p> <label>Email :</label> <input type="email" name="email" id="email"> </p> <p> <label>Name :</label> <input type="text" name="Name" id="Name"> </p> <p> <label>Age :</label> <input type="number" name="age" id="age"> </p> <p> <input type="submit" name="submit" value="sign-up"> </p> </div> </form> </section> 

Some pointers regarding your code

// the p is unnecessary
var paraC = document.querySelectorAll( '.form-container p input' );

// for elem at index until length
for (var i = 0; i < paraC.length; i++) {

    // the iterated array-like node list already contains references to the elements
    // paraC[i] is a reference to one of the elements
    // paraC[i].getAttribute('id') could be shortened to paraC[i].id
    // getting the id of the element in order to get the element is unnecessary.
    var inputField = document.getElementById(paraC[i].getAttribute('id'));

    // the submit input has no id but will be the last referenced input
    // the paraC[i].getAttribute('id') will return undefined
    // document.getElementById(undefined) is clearly not going to work well
    console.log(inputField); // gives null
}

first use document.addEventListener instead window.addEventListener the event DOMContentLoaded is applicable to document, after use class in your input, and do a Var to getid of input, your code should be like this :

  document.addEventListener("DOMContentLoaded", function() { var paraC = document.querySelectorAll('.yourclass'); for (var i = 0; i < paraC.length; i++) { var inputField = paraC[i], inputFieldId = inputField.getAttribute('id'); console.log(inputFieldId); inputField.addEventListener('focus', helperNote, false); } function helperNote() { var notePlace = document.querySelector('.form-container'); var note = document.createElement('p') notePlace.appendChild(note); console.log('event fired'); } }, false); 
 <section> <h3>Sign-Up Form</h3> <form method="post"> <div class="form-container"> <p>Fill The Form Below</p> <p> <label>Email :</label> <input class="yourclass" type="email" name="email" id="email"> </p> <p> <label>Name :</label> <input class="yourclass" type="text" name="Name" id="Name"> </p> <p> <label>Age :</label> <input class="yourclass" type="number" name="age" id="age"> </p> <p> <input type="submit" name="submit" value="sign-up"> </p> </div> </form> </section> 

Use document.querySelectorAll('.form-container p input:not([type="submit"])') to prevent selecting the submit button (it fails as it does not have the id attribute).

Also write focus instead of onfocus

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM