Search code examples
javascriptobject-literaliife

Unable to get dom element inside JS object literal method


I was trying to refactor a simple JS plugin that I had created and after referring to various patterns in JS, i was able to make some good efforts considering that I'm a newbie in JS. The below code is the sample refactored one. But my "selectedDom" object returns null. Logically I'm unable to find the mistake. Please guide me in this.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <style>
        .cross {
            background: red;
            width: 5px;
            height: 5px;
        }

        .input-field {
            height: 20px;
            width: 100px;
        }

        .input-area {
            height: 100px;
            width: 100px;
        }
    </style>
    <script>
        var InputActions = (function () {
            "use strict";
            var options = {
                textVal: ".input-field",
                crossClass: ".cross",
                border: ".input-area",
                borderNone: "1px solid #e4e5e7",
                borderShow: "1px solid #006f9e"
            };

            function InputActions() {

            };
            InputActions.prototype = {
                selectedDom: document.querySelector(options.textVal),
                cross: function () {
                    var text = this.selectedDom.value;
                    var cross = document.querySelector(options.crossClass);
                    this.selectedDom.focus();
                    (text === "") ? cross.style.opacity = "0": cross.style.opacity = "1";
                },
                clearField: function () {
                    var input = this.selectedDom;
                    input.value = '';
                    this.cross();
                },
                focusItem: function () {
                    document.querySelector(options.border).style.border = options.borderShow;
                    this.cross();
                },
                blurItem: function () {
                    document.querySelector(options.border).style.border = options.borderNone;
                }
            };
            return InputActions;
        })();

        window.inputAct = new InputActions();
    </script>
</head>

<body>
    <div class="input-area cross">
        <input type="text" class="input-field" onclick="inputAct.focusItem()" />
    </div>
</body>

</html>

Solution

  • It's because you placed your script tag in head and it executed before document.body was even created.

    To solve this problem you can move your script to the end of body or wrap it in function and execute it on DOMContentLoaded event.


    If you wrap only instantiation part in DOMContentLoaded event handler then you have to move querying DOM to constructor body. So your code will look like

    // ...
    function InputActions() {
        this.selectedDom = document.querySelector(options.textVal);
    };
    InputActions.prototype = {
        cross: function () {
            var text = this.selectedDom.value;
    // ...
    

    And the DOMContentLoaded handler part:

    document.addEventListener( "DOMContentLoaded", function () {
        window.inputAct = new InputActions();
    });