Table, Overlay and Event

Think big, Act small! Yep, It’s typical me. I was conceiving of some fancy app like Google Doc, whereas I ended up with a tiny piece like the following.

 

How to play with it? Well, clicking on one table cell starts drawing the overlay. Moving the cursor around moves and expands the overlay. Clicking once again ends the drawing process. The final overlay is a large rectangle which covers an area formed by the starting cell and the ending cell. Actually, the starting table cell and the ending table cells form two corners of the overlay. What I have learned from making this little app?

  • How to layout overlay?

Apparently, it should be positioned absolutely. And the stack order of it must be large enough so that it’s displayed in the front.

  • How to detect the table cell under mouse?

If the center of a table cell is clicked, the target or srcElement of the event is exactly the cell element under mouse. However, if the border is clicked, the cell under mouse have to be calculated out via the mouse position.

 

  • How to forward mouse event through layers?

The key-point of forwarding the mouse event from the overlay to the underline table is to re-dispatch the mouse event on the table. At re-dispatching, the location of the mouse cursor must be preserved, so that this location could be used later on to calculate the table cell under mouse.

Be Careful with Prototype Property

Today, I have spent nearly half a day wrestling with a bug. Eventually, it turned out that the root cause is the misuse of prototype property. Prototype property is like a pitfall for someone like me who comes from the object-oriented world. In Java, for instance, it’s quite normal to define a common property in the base class, so that all the derived classes contain this property. Hence, it’s no surprise I wrote down some silly codes like below:

Everything looks fine! ChildModel is a constructor function. Its prototype is a BaseModel object, which owns a property map. In the beginning, an instance of ChildModel is created and assigned to child. It inserts a key-value pair ‘salary : 2000’ into map. Subsequently, it restores map to an empty object. And then, another instance of ChildModel is created and assigned to child. I assumed that the map property of this newly created instance is clean. Isn’t it?

Oh, no. It still holds the key-value pair ‘salary : 2000’. Haven’t I already cleaned it? The pity is I didn’t. Let’s take a closer look at insert and teardown function and find out why. In the insert function, child manipulates the prototype property map directly. Hence, the key-value pair ‘salary : 2000’ is stored in the prototype property map.

However, in the teardown function, child restores map to a clean object. Doesn’t it? What, it doesn’t touch the prototype property map, instead, in creates a new property map on itself. And the newly added property overrides the prototype property.

Oh, I see. So the second created instance of ChildModel still inherits from prototype object. And the prototype object still contains the key-value pair ‘salary : 2000’.

JSLint: Errors and Solutions

JSLint is cool! It helps us identify a number of hidden bugs in our codes. However, JSLint only represents a type of coding style, which you may not totally agree with. For example, JSLint doesn’t expect a function name to start with uppercase; it prefers dot notation to subscript notation. In summary, there are times you would like to suppress JSLint warnings. Following is a guidance of JSLint warnings and possible solutions.

[E] Missing ‘use strict’ statement.

[S] “use strict”;  

Enable strict mode by placing “use strict”; at the top of a script. To learn more about script mode, please read http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/.

[E] ‘$’ was used before it was defined.

[S] /*global $: false */   

The JavaScript file is dependent on global variables defined elsewhere. For instance, it depends on the jQuery functions defined in the jquery.js. To tell JSLint that variables used in this file are defined in other files, use /*global */ directive. Separate the global variable names by comma.

[E] ‘window’ was used before it was defined.

[S] /*jslint browser: true */   

To use the global properties provided by web browser, such as window and document, add the browser directive.

[E] A constructor name ‘XXX’ should start with an uppercase letter.

      Missing ‘new’.

[S] /*jslint newcap: true */

JSLint enforces that the constructor function names be started with uppercase, while the normal function names be started with lowercase. To ignore this convention, add the newcap directive.

[E] ‘[XXX]’ is better written in dot notation.

[S] /*jslint sub: true */

JSLint prefers dot notation to subscript notation, i.e. user.name is better than user[‘name’]. To allow subscript notation, add the sub directive.

[E] Expected exactly one space between ‘function’ and ‘(‘.

[S] /*jslint white: true */

As far as anonymous function is concerned, JSLint prefers one space between keyword function and the parameter bracket. To mute this warning, add the white directive.

[E] Move the invocation into the parens that contain the function.

[S] }());

End the self-executing anonymous function as (function(){…}()); instead of (function(){…})();.

[E] Weird assignment.

[S] Convert the subscript notation to dot notation.

No specific directive could be used to suppress this warning. My experience is simply converting the subscript notation on the line to dot notation. In this way, the warning is gone.

JSONP : Cross-Domain Ajax Request

  • What’s JSONP

JSONP is JSON with padding. It’s an artful means to bypass the same origin policy restriction, which is imposed by web browsers. Web browser prohibits scripts running on a domain requesting data from a server in a different domain. However, an exception is the HTML <script> element. Hence, JSONP makes use of it and dynamically injects a script element into HTML DOM. P actually stands for a callback function which is executed at response time.

  • JSONP via jQuery

jQuery allows cross-domain Ajax request via JSONP. An example is shown below:

What is done after launching this request? Firstly, the complete request URL looks like “url?_callback=XXX“. The url, of course, is the url specified in the url property. The query parameter “?_callback=XXX“, however, is appended by jQuery. Actually, the appendix reveals the nature of JSONP request, JSON with padding. JSONP response looks like below, a function wraps the JSON data:

However, if the server actually doesn’t support JSONP, probably, a JSON is sent back directly. In this case, the browser throws an exception “Uncaught SyntaxError: Unexpected token:“, warning that it’s invalid JavaScript:

Talking about the callback function, what does the callback look like in jQuery? Well, it’s not what we specify in the success or error property. It’s actually dynamically created by jQuery. The callback function is installed on window and its responsibility is simple: extracting the JSON data.

As what I have mentioned before, to launch a cross-domain Ajax request, a script element is dynamically injected into HTML DOM. How does jQuery do it? Firstly, jQuery creates a script element, the src property of which links to the complete URL “url?_callback=XXX“.

And then the script element is injected in to head. At meantime, the script’s onload event is listened. After script is entirely loaded, the loaded JavaScript is evaluated and executed, which basically invokes the callback function.

And we already know that the callback function extracts the JSON data. And then, the JSON data is really passed to the success callback function, which we specify in the success property.

After we know the life cycle of JSONP request via jQuery, let’s take a closer look at the ajax parameters. Firstly, dataType is jsonp, indicating it’s a cross-domain Ajax request. Then, you either explicitly set crossDomain to true or ignore this property. If you ignore it, jQuery does the work for you. It checks the Ajax request url, if it is in another domain, jQuery set crossDomain to true. However, DO NOT set crossDomain to false. See how jQuery checks request url to determine whether it’s a cross-domain request.

Out of security concerns, jQuery only allows cross-domain GET request. GET request ensures user doesn’t post malicious data to the server. Once again, you don’t have to explicitly set it because jQuery changes the type to GET on a cross-domain Ajax request.

Cross-domain Ajax request must be asynchronous whether async is set true or false. By default, jQuery append a query parameter “?callback=XXX” to the end of the URL to specify the callback. However, you are able to change the parameter name to whatever by specifying jsonp property. In my example, the appendix looks like “?_callback=XXX“.

JavaScript Private Methods

People share some consensus on what’s the best way in defining a public method for a JavaScript Class, that is:

The biggest advantage of defining methods via prototype rather than straight inside the constructor is that a single function object is shared among all the class instances. 

By contrast, there is no such rule of thumb on how to define private methods. A simple and probably most prevalent way is declaring the private functions using var inside constructor, for example:

However, a major drawback of this solution is that the public methods which make use of the private methods must be defined in the same scope as that of private methods. That is these public methods have to be defined inside constructor too. As a result, each class instance has a respective copy of these function objects. 

How to avoid the redundancy? Self-executing anonymous function comes to help.

Self-executing anonymous function creates a function-level scope, which is a perfect place to wrap private methods:

See it! By defining privateMethod inside the self-executing anonymous function, we are able to isolate it from global scope. That is privateMethod is not accessible outside the function. Yet, it’s exposed to publicMethod because publicMethod is defined in the same function-level scope. Additionally, publicMethod is defined via prototype which ensures that all the instances of TestClass share a single function object.

Minify JavaScript via UglifyJS

UglifyJS is a JavaScript minifying tool, which runs on NodeJS. Compared with other popular JavaScript minifiers, such as YUI Compressor and Google Closure, a remarkable advantage of using UglifyJS is that it’s available as a native command. To utilize UglifyJS, we need to install NodeJS first and then the UglifyJS module.

Here is the guideline on installing NodeJS https://github.com/joyent/node/wiki/Installation. After successful installation, node server starts running.

Then, install UglifyJS module https://github.com/mishoo/UglifyJS#Install on the node server. After adding the UglifyJS path into PATH, we are able to use it via command prompt:

$ uglifyjs -nc -o [output js] [input js]

Extremely easy, isn’t it? Following is a small test comparing the compressing efficiency of different minifiers:

 

Original

Uglify

Closure

YUI Compressor

size

193.5 KB

62.3 KB

61.3 KB

64.4 KB

 

Enable vs Disable – jQuery Mobile

How to enable and disable various components in jQuery Mobile? Following are my tips.

  • Button

To disable a button, simply add the ‘disabled‘ attribute to it:

Or you’d like to manipulate the button component via Javascript:

The same applies to a submit button. Adding the ‘disabled‘ attribute to the submit button disables it.

Or we’re able to manipulate the submit button via Javascript:

As far as link button is concerned, since anchors don’t natively have any disabled state, jQuery Mobile group decides not to support disable and enable anchors like buttons. Therefore, we have to apply ‘ui-disabled’ class to the anchor to achieve the same effect.

Here’s how to do via Javascript:

  • Form 

It’s extremely easy to disable form components by just adding ‘disabled‘ attribute to them.

The display looks like below:

To implement it via Javascript:

Or we’re able to disable the entire form by adding ‘ui-disabled‘ class to it:

Through this way, the labels inside the form are dimmed too.

vim Frequent Used Commands

 

Command

Description

 Save and Quit

:w

Save changes

:wq   or   😡

Save changes and quit

:q! 

Quit without saving

u

Undo last change

 Move Cursor

^

Move cursor to the beginning of current line

$

Move cursor to the end of current line

w

Move cursor to the beginning of next word

b

Move cursor to the beginning of preceding word

Delete

dw

Delete single word beginning with the character under cursor

dd

Delete current line

d$

Delete the remaining of line beginning with the character under cursor

:1,$d

Delete all the lines

:1,Nd

Delete 1 to N lines

:Ndd

Delete the next N lines, including the current line

Copy and Paste

yw

Copy a word

yy

Copy current line

Nyy

Copy the next N lines, including the current line

:1,Ny

Copy 1 to N lines

p

Paste buffer after the current line

:r filename

Read file named filename and insert after current line

 Search and Replace

/string

Search for a string. Press n, cursor moves to the next occurrence; Press N, cursor moves to the preceding occurrence.

:s/old/new/g

Find each occurrence of ‘old’ on the current line and replace it with ‘new’

:%s/old/new/g

Find each occurrence of ‘old’ throughout the file and replace it with ‘new’

 Display

:set number

Display line numbers

:vsplit filename

Split vi vertically and display file named filename on the left half

ctrl-w ctrl-w

Move cursor between split screens

Tips of jQuery Mobile

I have been intensively working with jQuery Mobile during recent days. Following are some of the tips I grasp via using this library.

  • Methods
  1.  $.mobile.changePage

It enables programmatically change from one page to another. That implies your Javascript codes take full control of page loading and page transition. For example, after the user correctly fills and submits the authentication form, the view changes from the login page to the home page, with a sliding left transition effect.

The first parameter is a string which specifies the relative URL of the home page resource. The second parameter is an object with one property ‘transition’, which specifies the transition to use when showing the page. Actually, you could specify more properties in the second parameter. Please refer to http://jquerymobile.com/test/docs/api/methods.html for the details.

By taking a closer look of jQuery Mobile codes, we could find out what has been done after invoking the method above. Firstly, ‘pagebeforechange‘ event is triggered prior to any page loading and transition. Then, $.mobile.loadPage is invoked to load external page ‘home.html’ via Ajax. The Ajax call looks like below.

By default, Ajax request type is ‘GET’ and data is ‘undefined’. All these default configurations could be rewritten via the second parameter of  $.mobile.changePage method. In addition, cross-domain Ajax request is disallowed by default. To allow cross-domain requests, $.mobile.allowCrossDomainPages configuration option should be set to true. After the external page is successfully loaded and injected into DOM, a ‘pageload‘ event is triggered. Later on, page transition occurs. Finally, after the page transition animations complete, ‘pagechange‘ event is triggered. In addition to above events, a ‘hashchange‘ event is also triggered because the current location hash is changed.

  1.  $.mobile.path.parseUrl

URL path helper provide many useful utility methods. One of them is parseUrl function. It parses a URL into a structure that allows easy access to parts of the URL. It returns an object which allows us to access the sub-parts of the URL.

Additionally, path object also provides functions to get (get()) and set (set(path)) location hash, to check whether a URL is relative (isRelativeUrl(url)) or absolute (isAbsoluteUrl(url)).

  • Refresh

Refresh is highly important especially when the page is partially updated. For example, if we update a select via Javascript, we have to call the refresh method on it to update the visual styling.

 

Here, we add options into select dynamically via Javascript. Afterwards, we have to invoke refresh explicitly so that the display could be refreshed. It’s the same case with list views. If we add items to a listview, we have to call .listview(‘refresh’) on it.

Another generic way to refresh the display is to trigger ‘create‘ event.  In most of the cases, it’s the easiest way to update the whole display.

CSS Sprites

While I was working on the navigation bar, I came across this AaHa… trick. In the beginning, I thought it was crazy that icons and small images are combined into a large picture. A minute later, I realized that there must be some reason because so many websites have applied this technique.

         Facebook                                 Google

Not surprisingly, it turns out to be a must-to-know CSS technique called CSS Sprites. The basic idea is by combining multiple images into one, it’s able to reduce the number of HTTP requests. One HTTP request is able to fetch all of the icons and small images required to display the web page. And performance research has indicated that “reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make“.

How to implement sprites with CSS? Generally speaking, firstly, we have to merge the icons into one big sprite image via Photoshop or any other kind of image processing tool. Next, we set the sprite image as the background image. Finally, we could display any part of the image via shifting the background position.

The top picture in this post is a demo I did applying CSS sprites.  I merged a series of apple products into one image (the icons are downloaded from Icon Archive). Each icon is of the size 64px * 64px. All the icons are aligned side by side, without gaps between them. Therefore, the whole sprite image is of the size 256px * 64px.

 The content consisting the navigation bar is an unordered list:

To align the unordered list horizontally, the tip is to set the list element’s display as inline-block. Basically speaking, inline-block is a way to make elements inline, yet preserving their block capabilities such as setting width and height, top and bottom margins and paddings etc. Thus, list elements are displayed horizontally. 

However, since the list elements are treated as inline elements, there is always some space between two list elements even if the margin of li is set to zero. To remove these annoying gaps, one method is to set the margin to a negative value, say -2px

Next, I set the sprite image as the background image of the anchor element itself:

Each anchor element displays only a part of the whole background. For example, the second anchor element displays the iPhone icon. To do that, merely shift the background position with negative X coordinates -64px. The shift is calculated in this way: originally, the background image is positioned with its (0, 0) aligned to the top-left of the container. Since the iPhone icon starts at (64px, 0) on the image, we have to shift the image leftward of 64px to align the start of iPhone icon to the top-left of the container. Therefore, the background is shifted with X coordinates -64px

Here, I want to take some time to showcase the inset shadow effect. See, I have dropped some shadow inside the top of the boxes (only on the top side).

This effect is done by setting the box shadow to inset and the spread radius to a negative value. Feel free take a try.

Reference