google+javascriptbanktwitter@js_bankfacebook@jsbankrss@jsbank






Hướng dẫn xây dựng các sự kiện tùy chọn trong JavaScript Nếu đã từng làm việc nhiều với JavaScript, chắc hẳn bạn sẽ biết sự kiện trong JavaScript là gì, cùng với các sự kiện phổ biến và thông dụng như: onload, onlick, ... Hầu như các sự kiện phổ biến trong JavaScript mà người dùng cần đến đều được cài đặt bên trong bản thân ngôn ngữ lập trình này. Và mục đích của bài viết này không đề cập đến các sự kiện này.

Thông qua bài viết JavaScript này, tác giả sẽ hướng dẫn bạn cách thức xây dựng và sử dụng các sự kiện tùy chọn của riêng mình và tích hợp vào các ứng dụng JavaScript; với các kiến thức cơ bản như thiết lập/loại bỏ bộ quản lí sự kiện, cài đặt bộ xử lý.


Miễn phí web hosting 1 năm đầu tại iPage



Nếu bạn vẫn còn đang tìm kiếm một nhà cung cấp hosting đáng tin cậy, tại sao không dành chút thời gian để thử với iPage, chỉ với không quá 40.000 VNĐ/tháng, nhưng bạn sẽ được khuyến mãi kèm với quà tặng trị giá trên 10.000.0000 VNĐ nếu thanh toán cho 24 tháng ~ 900.000 VNĐ?

Có trên 1 triệu khách hàng hiện tại của iPage đã & đang hài lòng với dịch vụ, tuyệt đối chắc chắn bạn cũng sẽ hài lòng giống họ! Quan trọng hơn, khi đăng ký sử dụng web hosting tại iPage thông qua sự giới thiệu của chúng tôi, bạn sẽ được hoàn trả lại toàn bộ số tiền bạn đã sử dụng để mua web hosting tại iPage. Wow, thật tuyệt vời! Bạn không phải tốn bất kì chi phí nào mà vẫn có thể sử dụng miễn phí web hosting chất lượng cao tại iPage trong 12 tháng đầu tiên. Chỉ cần nói chúng tôi biết tài khoản của bạn sau khi đăng ký.

Nếu muốn tìm hiểu thêm về ưu / nhược điểm của iPage, bạn hãy đọc đánh giá của ChọnHostViệt.com nhé!
Thử iPage miễn phí cho năm đầu tiên NGAY

Without a doubt, the most often-used paradigm in JavaScript is events. Events are a manifestation of the observer pattern, a well-defined computer science design pattern for loose coupling. Loose coupling is incredibly important for creating maintainable, stable codebases. I talk a lot about loose coupling and its importance in my talk, Scalable JavaScript Application Architecture (video), so I won't talk too much about it here. However, the concept is very important to grasp if you wish to progress as a software engineer.

Events

Unless you've never written any JavaScript before, you've used events at some point in time (admittedly, if you've never written JavaScript before, the chances of your reading my blog are probably pretty slim). Put quite simply: the way that you tie behavior to web pages is through events. Events are a way of letting interested parties know that an important moment has occurred in the lifecycle of the application. For instance:

window.onload = function(){
    Application.init();
};

In this example, the load event is the interesting moment. I want to know when the window is fully loaded so that I can initialized the JavaScript application. The onload event handler is the location to where an event handler is assigned. The brilliant part is that window doesn't care what web page is loaded or who is writing the code; it just knows that there's a function to call when load occurs. This is the essence of loose coupling: when parts of an application have very limited knowledge of one another.

The Browser Object Model (BOM) and Document Object Model (DOM) publish events to allow developers access to the interesting moments of the browser and web page, respectively.

Custom events

It's no surprise that most JavaScript libraries rely heavily on custom events since this is a pattern that web developers are familiar with. Every major JavaScript library provides its own events, components to enable easy custom event definition, or both. This makes sense, of course, since libraries want to be loosely-coupled to the execution environment, and therefore, to your code.

There's nothing magic about custom events, though, and there's no need to load an entire library if you'd like to experiment with custom events. An object that supports custom events needs to be able to do a small set of things:

  1. Assign an event handler for a particular event.
  2. Remove an event handler for a particular event.
  3. Fire an event and call all assigned event handlers.

The following implements all of this basic functionality:

//Copyright (c) 2010 Nicholas C. Zakas. All rights reserved.
//MIT License

function EventTarget(){
    this._listeners = {};
}

EventTarget.prototype = {

    constructor: EventTarget,

    addListener: function(type, listener){
        if (typeof this._listeners[type] == "undefined"){
            this._listeners[type] = [];
        }

        this._listeners[type].push(listener);
    },

    fire: function(event){
        if (typeof event == "string"){
            event = { type: event };
        }
        if (!event.target){
            event.target = this;
        }

        if (!event.type){  //falsy
            throw new Error("Event object missing 'type' property.");
        }

        if (this._listeners[event.type] instanceof Array){
            var listeners = this._listeners[event.type];
            for (var i=0, len=listeners.length; i < len; i++){
                listeners[i].call(this, event);
            }
        }
    },

    removeListener: function(type, listener){
        if (this._listeners[type] instanceof Array){
            var listeners = this._listeners[type];
            for (var i=0, len=listeners.length; i < len; i++){
                if (listeners[i] === listener){
                    listeners.splice(i, 1);
                    break;
                }
            }
        }
    }
};

The EventTarget type has three methods: addListener(), fire(), and removeListener.

The addListener() uses the private _listeners object to store event handlers for various events. When an event handler is added, the method first checks to see if there's a named property for that event type on the _listeners object, and if not, creates one containing an array. The event handler function is then saved to the array for later.

The fire() method fires an event with a given name. In effect, this method's only job is to execute each event handler for the given event type. The method accepts either an object, in which case it's expected to have a type property, or a string, in which case a new object is created and the string is assigned as the value of type. Next, if the event object doesn't have a target property assigned, it is set to the current instance. This effectively creates an event object similar to the one most are familiar with via the BOM and DOM. Once the event object is created, the _listeners object is checked for event handlers, and if found, they are executed. Note that in order to mimic the BOM/DOM approach, event handlers are executed in the scope of this via the call() method.

The last method, removeListener(), simply reverses the process of addListener(). It searches through the _listeners property for the given event type to locate the specified event handler. If found, the event handler is removed by using the array's splice() method, and otherwise it exits without doing anything.

Basic usage:

var target = new EventTarget();
function handleEvent(event){
    alert(event.type);
};

target.addListener("foo", handleEvent);
target.fire({ type: "foo" });    //can also do target.fire("foo")
target.removeListener("foo", handleEvent);

Practically speaking, you'll likely not want to use an instance of EventTarget directly, but rather inherit from it:

function MyObject(){
    EventTarget.call(this);
}

MyObject.prototype = new EventTarget();
MyObject.prototype.constructor = MyObject;
MyObject.prototype.foo = function(){
    this.fire("foo");
};

var o = new MyObject();

o.addListener("foo", function(){
    alert("Foo just happened.");
});

o.foo();

Typically, events are fired in reaction to some other method call, as in this example (events are usually not fired external to the object that is publishing the events).

What about... ?

This is a pretty barebones implementation of a custom event providing object, so inevitably someone will come along and ask why I didn't include one feature or another. There are, of course, a lot of enhancements you can make to custom events if you so desire. Some enhancements others have implemented:

  • Bubbling of events
  • Continue to execute event handlers even if one throws an error
  • Allow event handlers to cancel further processing or default actions

Each of these can be built pretty easily on top of the base presented in this post.

Conclusion

Custom events are a very powerful and useful pattern in JavaScript programming, and your usage of them doesn't have to rely on a large JavaScript library. Implementing your own custom events is easy. The implementation presented in this post is a minimum feature set that typically fulfills most requirements, but you can consider it as a starting point for more advanced functionality if your requirements are more complex.

Ứng dụng AI Video.com
Tạo video doanh nghiệp của bạn bằng AI chỉ với giọng nói hoặc văn bản

chatGPTaz.com
Nói chuyện với ChatGPT bằng ngôn ngữ mẹ đẻ của bạn

Ứng dụng AI Video
Ứng dụng video AI MIỄN PHÍ đầu tiên của bạn

Faceswap AI trực tuyến
Đổi mặt Video, Ảnh & GIF ngay lập tức với Công cụ AI mạnh mẽ - Faceswap AI Trực tuyến MIỄN PHÍ

Temu tặng $500 cho người dùng mới
Claim Free Temu $500 Credit via Affiliate & Influencer Program

Tín dụng quảng cáo TikTok miễn phí
Làm chủ quảng cáo TikTok cho hoạt động tiếp thị doanh nghiệp của bạn

Dall-E-OpenAI.com
Tự động tạo ra hình ảnh sáng tạo với AI

chatGPT4.win
Nói chuyện với ChatGPT bằng ngôn ngữ mẹ đẻ của bạn

Sản phẩm AI đầu tiên của Elon Musk - Grok/UN.com
Nói chuyện với Grok AI Chatbot bằng ngôn ngữ của bạn

Công cụ.win
Mở trung tâm công cụ miễn phí để mọi người sử dụng với hàng trăm công cụ

GateIO.gomymobi.com
Airdrop miễn phí để nhận, chia sẻ lên đến 150.000 đô la cho mỗi dự án

iPhoneKer.com
Tiết kiệm tới 630$ khi mua iPhone 16 mới

Mua Robot Tesla Optimus
Đặt mua Tesla Bot: Robot Optimus Gen 2 ngay hôm nay với giá dưới 20.000 đô la

JavaScript theo ngày


Google Safe Browsing McAfee SiteAdvisor Norton SafeWeb Dr.Web