Organize javascript code under jquery (javascript function-based)

Source: Internet
Author: User

Starting with the magic "$" Function
The "$" function binds a specified button after the document is loaded. The code works properly on a single webpage. But if we have other web pages, we have to repeat this process.
Copy codeThe Code is as follows:
<A href = "javascript:;" id = "sayHello"> Say Hello </a>
<Script type = "text/javascript">
// When dom ready, do something.
// Bind click event to a button.
$ (Function (){
$ ('# SayHello'). click (function (){
Alert ('Hello world! ');
});
});
</Script>

What if we need a button for another action? For example:
Copy codeThe Code is as follows:
<A href = "javascript:;" id = "sayUnlike"> Unlike it </a>
<Script type = "text/javascript">
// When dom ready, do something.
// Bind click event to a button.
$ (Function (){
$ ('# SayUnlike'). click (function (){
Alert ('I unlike it .');
});
});
</Script>

Next, there are more problems, and we need a lot of such buttons, which is not difficult.
Copy codeThe Code is as follows:
<A href = "javascript:;" class = "sayUnlike"> Unlike it </a>
<Script type = "text/javascript">
// Change to a class selector to match all the button elements.
$ (Function (){
$ ('. SayUnlike'). click (function (){
Alert ('I unlike it .');
});
});
</Script>

There are two buttons in one page ......
Copy codeThe Code is as follows:
<A href = "javascript:;" class = 'sayhel'> Say Hello </a>
<A href = "javascript:;" class = "sayUnlike"> Unlike it </a>
<Script type = "text/javascript">
$ (Function (){
$ ('. SayHello'). click (function (){
Alert ('Hello world! ');
});
$ ('. SayUnlike'). click (function (){
Alert ('I unlike it .');
});
});
</Script>

However, not all pages use these two buttons. In order not to use the extra selector on the page, we need to make some necessary adjustments, because the performance of the class-based selector is much overhead than that of the id selector, We need to traverse all dom elements and use a regular expression to match the class attribute to select elements that meet the conditions.
Copy codeThe Code is as follows:
<? If ($ page = 'A') {?>
<Script type = "text/javascript">
$ (Function (){
$ ('. SayHello'). click (function (){
Alert ('Hello world! ');
});
});
</Script>
<? }?>
<? If ($ page = 'B') {?>
<Script type = "text/javascript">
$ (Function (){
$ ('. SayUnlike'). click (function (){
Alert ('I unlike it .');
});
});
</Script>
<? }?>

Our project functions become more and more complex. After a period of time, it becomes like this: quick but dirty ......
Copy codeThe Code is as follows:
<? If ($ page = 'A' or $ page = "C" and $ page is not "D") {?>
<Script type = "text/javascript">
......
</Script>
<? }?>
<? If ($ page = "B" or $ page = "E" and $ page is not "X") {?>
<Script type = "text/javascript">
.....
</Script>
<? }?>
<? If ($ page = "B" or $ page = "E" or $ page = "C") {?>
<Script type = "text/javascript">
.....
</Script>
<? }?>

This is really bad. We need to load a lot of code snippets on a page to bind all events, if we load different codes into multiple js files, this will add http requests for multiple page resources. Both management and user experience will face challenges, we need to find a better solution.
Since the overhead of class selector is so large, can we bind all events in one scan? Let's try:
Copy codeThe Code is as follows:
<Script type = "text/javascript">
// Register global name space.
Var Yottaa = Yottaa || {};
Yottaa. EventMonitor = function (){
This. listeners = {};
}
// Bind all event.
Yottaa. EventMonitor. prototype. subscribe = function (msg, callback ){
Var lst = this. listeners [msg];
If (lst ){
Lst. push (callback );
} Else {
This. listeners [msg] = [callback];
}
}
// Create the event monitor instance.
Var event_monitor = new Yottaa. EventMonitor ();
Function load_event_monitor (root ){
Var re =/a _ (\ w +)/; // using a regular expression to filter all event object.
Var fns = {};
$ (". J", root). each (function (I ){
Var m = re.exe c (this. className );
If (m ){
Var f = fns [m [1];
If (! F) {// create a function object if the event processing function does not exist.
F = eval ("Yottaa. init _" + m [1]);
Fns [m [1] = f; // call the binding function.
}
F & f (this );
}
});
}
$ (Function (){
// When dom ready, bind all event.
Load_event_monitor (document );
});
// Here is 2 sample components.
Yottaa. init_sayhello = function (obj ){
$ (Obj). click (function (){
Alert ('Hello world! ');
});
}
Yottaa. init_unlike = function (obj ){
$ (Obj). click (function (){
Alert ('I unlike it .');
});
}
</Script>

Write the DOM element as follows:
<A href = "javascript:;" class = "j a_sayhello"> Say Hello </a>
<A href = "javascript:;" class = "j a_unlike"> Say Unlike </a>

This seems much better. We only need to execute the class selector once during page loading (in the above Code, it is all '. you can find all the elements that need to be bound to events. The specific component to be bound is determined by a_xxx in the class name, which corresponds to Yottaa. init_xxx, and pass the reference of the current element as a parameter to the Event Logic.
In this processing mode, we do not need to manually write the event processing logic again and put it in $ (function (){....}); in this initialization function, all we need to do is add two classes: "j a_XXX" to the component's "Container" to help me complete event binding. Is it cool? Like common expansion/folding effects, full selection/inverse selection effects, tab switching allows you to use this method for some other simple functions. Is this the legendary silver bullet? No, it's not that simple. We should see some weaknesses in this processing method:
Initialization parameters cannot be passed to components.
It cannot reflect the components, nor use inheritance, polymorphism, and other object-oriented features to make the program easier to write and understand.
Components with specific associations are slightly difficult to handle, and there is no reasonable event notification mechanism.
Let's take a look at the first article: Concerning parameter passing, in many scenarios, for the list of multiple entries, we usually assign a unique id to each entry, the behavior of these elements is similar. The difference is that the number of the server is different, for example, a message list or a production port list. We can use the id attribute to do something for us. Let's look at the following code. We use the id attribute to tell javascript the server serial number corresponding to the entry, in the subsequent event logic processing, it is sent back to the server as part of the server callback function parameter.
Copy codeThe Code is as follows:
<Script type = "text/javascript">
Yottaa. init_sampleajax = function (obj ){
$ (Obj). click (function (){
Var component_id = $ (this). attr ('id'). split ('-') [1];
$. Get ('/server/controller/method', {id: component_id}, function (data ){
If (data ){
Alert ('message from server: '+ data );
}
});
});
}
</Script>
<A href = "javascript:;" class = 'J a_sampleajax 'id = 'item-a'> Show server message. </a>
<A href = "javascript:;" class = 'J a_sampleajax 'id = "item-B"> Another button with same action but different server side identifier. </a>

In more complex scenarios, we can use the inline code on the page to pass some necessary information to the component.
Copy codeThe Code is as follows:
Yottaa. globalConst = {
User :{
FamilyName: "Jhone ",
GivenName: 'Bruce'
},
Url :{
SiteName: 'yottaa. com ',
Score: 98
}
}
Yottaa. componentMetaData = {
Compoment_id_1 :{......},
Component_id_2 :{......}
};

The above discusses a possible code organization method, but it is not applicable to all projects. What we need to do is to find a reconstruction solution with a low cost for the current situation. Consider the following:
Bind the Event code and component code of the Separation element: the component Code includes the jquery library, related extension plug-ins, and the components we have compiled, such as chartbox.
Event binding and processing logic: divided into multiple modules based on different components. Each module is placed in a function.
On the page, you must specify the modules to be initialized on the page, and provide a list to be processed by the global event binder.
The following shows some code:
Copy codeThe Code is as follows:
<Script type = "text/javascript">
Function init_loginPanel = function (){
Var container = $ ('login _ panel ');
$ ('# Login_button'). click (function (){
......
});
}
Function init_chart = function (){
......
}
// Global static init method
Yottaa. initComponents = function (components ){
For (var I = 0; I <components. length; I ++ ){
If (typeof window [components [I] = 'function '){
Window [components [I] ();
}
}
}
// Above is in the 'all-in-one 'assets file which is compressed to one file in production.
Var components = ['init _ loginPanel ', 'init _ chart'];
Var metaData = {
LoginPanel :{},
Chart :{},
......
};
$ (Function (){
Yottaa. initComponents (components );
});
// Here is inline script on the page.
</Script>

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.