简体   繁体   中英

Best way to implement Events on Javascript

As a .NET developer, I'm accustom to delegates and event on custom controls. I have been creating javascript codes for quite sometime but I'm wondering the best way to implement this in javascript. Below is how I normally code my components.

var RGComp= RGComp || {};
RGComp.MyComponent = function () {
    function events(){
        $("a").unbind("click");
        $("a").click(function () {
             // Do something
        });
    }
    function generateUI(){
        //generate HTML UI
        events();
    }
}

I'm sure this is improper. I have to call unbind all the time to avoid clogging up the DOM. Many thanks in advance.

Global Event Handlers

There are going to be folks for and against anything including the movement of air-molecules though at the end of the day all that matters is that you're able to do what you need to do and you stay organized in the process. On the JAB Creations web platform we use global events where appropriate and on occasion we set element specific events if necessary .

//Do not shorten event to e, you WILL want to reference e separately.
window.onclick = function(event)
{
 if (condition) {}
 else if (condition) {}
}

Setting specific events:

  1. Generally you'll want to check if the section() or page() is appropriate (presuming you have proper information hierarchy).
  2. You'll want to have a function return the current page's id, in my case this is push_current_id() or id_(push_current_id()) (eg push_current_id() == 'admin_' for the control panel and before the character limitation lift for the id attribute in HTML5).
  3. Setting static events for specific elements is okay in a few circumstances though often you'll want to have universally applicable behaviors:

CTRL + Horizontal Scrolling:

window.onwheel = function(event)
{
 if (event.ctrlKey)
 {
  if (e.scrollHeight > e.clientHeight && event.deltaY != 0)
  {
   event.preventDefault();
   //Change 5 to adjust sensitivity.
   e.scrollLeft = e.scrollLeft + (5 * event.deltaY);
  }
  //else if (condition) {}//Other behavioral tweaks.
 }
 //else if (condition) {}//Other behavioral tweaks.
}

The main take-away is that you're limiting most if not all of your event calls to the global handlers and you can be as specific or broad in the conditions required for an element to hook in to parts of those global events. You won't need to add/remove events, just adjust your if conditions. I'm sure someone out there will harshly disagree though we've had nothing but success with this approach on an entire web platform designed to work explicitly in the absence of frameworks and libraries to maximize performance.

Here's my take on what I've learned so far.

cs.js

(function () {
    document.addEventListener("DOMContentLoaded", function (event) {
        let component = RGDM.MainComponent();
        component.init("rgDiv");
    });
})();

mainComponent.js

var RGDM = RGDM || {};
RGDM.MainComponent = function () {
    let divMain;
    let lineBreak;
    function init(id) {
        divMain = document.getElementById(id);
        loadUI();
    }

    function loadUI() {
        let component = RGDM.Component();
        component.init(divMain);

        lineBreak = document.createElement("br");
        divMain.appendChild(lineBreak);
        let btnResult = document.createElement("a");
        btnResult.innerHTML = "Result";
        btnResult.style.backgroundColor = "#fff";
        btnResult.style.border = "1px solid #999";
        btnResult.style.padding = "5px 5px 5px 5px";
        btnResult.style.color = "#000";
        btnResult.style.cursor = "pointer";
        btnResult.id = "btnResult";
        btnResult.onclick = function () {
            if (component.value() != "") {
                document.getElementById("labelMainDisplay").innerHTML = "OUTSIDE_COMPONENT:" + component.value();
            } else {
                document.getElementById("labelMainDisplay").innerHTML = "[Display Outside Component]";
            }
        }
        divMain.appendChild(btnResult);
        lineBreak = document.createElement("br");
        divMain.appendChild(lineBreak);
        lineBreak = document.createElement("br");
        divMain.appendChild(lineBreak);
        let labelMainDisplay = document.createElement("span");
        labelMainDisplay.id = "labelMainDisplay";
        labelMainDisplay.innerHTML = "[Display Outside Component]";
        divMain.appendChild(labelMainDisplay);

        divMain.appendChild(componentDiv);
    }


    return {
        init: init
    };
}

component.js

var RGDM = RGDM || {};
RGDM.Component = function () {
    let divMain;
    let componentDiv;
    function init(div) {
        divMain = div
        loadUI();
    }
    function loadUI() {
        let componentDiv = document.createElement("div");
        componentDiv.style.height = "200px";
        componentDiv.style.width = "300px";
        componentDiv.style.padding = "10px 10px 10px 10px";
        componentDiv.style.border = "1px solid #000";
        componentDiv.addEventListener("click", function (e) {
            console.log(JSON.stringify(e.target.nodeName));
            if (e.target && e.target.nodeName == "A") {
                // console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
                if (e.target.id == "btnSubmit") {
                    if (document.getElementById("txtName").value !== "") {
                        document.getElementById("labelDisplay").innerHTML = "INSIDE_COMPONENT:" + document.getElementById("txtName").value;
                    } else {
                        document.getElementById("labelDisplay").innerHTML = "[Display Text]";
                    }
                } else if (e.target.id == "btnClear") {
                    document.getElementById("txtName").value = "";
                }
            }
        });

        let txtName = document.createElement("input");
        txtName.id = "txtName";
        txtName.type = "input";
        componentDiv.appendChild(txtName);

        let btnSubmit = document.createElement("a");
        btnSubmit.innerHTML = "Submit";
        btnSubmit.style.backgroundColor = "#000";
        btnSubmit.style.border = "1px solid #000";
        btnSubmit.style.padding = "5px 5px 5px 5px";
        btnSubmit.style.color = "#fff";
        btnSubmit.style.cursor = "pointer";
        btnSubmit.id = "btnSubmit";
        componentDiv.appendChild(btnSubmit);

        let btnClear = document.createElement("a");
        btnClear.innerHTML = "Clear";
        btnClear.id = "btnClear";
        btnClear.style.backgroundColor = "red";
        btnClear.style.border = "1px solid #ccc";
        btnClear.style.padding = "5px 5px 5px 5px";
        btnClear.style.color = "#fff";
        btnClear.style.cursor = "pointer";
        componentDiv.appendChild(btnClear);

        let breakLine = document.createElement("br");
        componentDiv.appendChild(breakLine);

        let labelDisplay = document.createElement("span");
        labelDisplay.id = "labelDisplay";
        labelDisplay.innerHTML = "[Display Text]";
        componentDiv.appendChild(labelDisplay);

        divMain.appendChild(componentDiv);
    }

    function getResult() {
        return document.getElementById("txtName").value;
    }
    function getComponent() {
        return componentDiv;
    }
    return {
        init: init
        , component: getComponent
        , value: getResult
    };
};

Below is the screenshot

在此处输入图像描述

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