Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Wednesday, May 6, 2009

Javascript Closures

A re-introduction to JavaScript and Simplify Scope with Javascript Closures have a good introduction on the concept of javascript closures. A closure is the combination of a function and the scope object in which it was created. Closures let you save state. The memory of a closure can be freed only when the returned callMe is no longer accessible.

function createClosure(scope_) {
    var origScope = scope_;

    var callMe = function() {   // inner private function
        origScope.somefunc();
    }
    return callMe;    // inner function returned
}

// preserve 'this'
someobject.someproperty = createClosure(this);

function makeAdder(a) {
    return function(b) {
        return a + b;
    }
}

x = makeAdder(5);  // each call to the outer function create a closure
y = makeAdder(20);

x(6)    // return 11, with scope object a=5, 
        // a closure preserves the arguments and variables in all scopes it contains. 
y(7)    // return 27, with scope object a=20

Any nested function forms closure. It doesn't have to be returned, it can be an anonymous inner function as below. We should try to avoid closure whenever possible, it may potentially cause memory leak if there exists circular reference between JS object and DOM object.
function assignOnclick(element) {
   element.onclick = function() {
      this.style.backgroundColor = 'blue';
   };
}

See: Functions and function scope

Tuesday, March 17, 2009

Javascript/css/image loading

In Q&A-Javascript Execution & Onload Techniques in Web Browsers, It states that "Inline and external scripts are executed in the order in which they appear in an (x)HTML document…It should be noted that the loading of an (x)HTML page is halted while loading external JavaScript files."

In 14 Rules for Faster-Loading Web Sites, Rule 6 “Put script at the bottom” is used to avoid such halting. See Example.

Other resources (css/images) are loaded asynchronously and you cannot be certain when they will complete.

onload vs onDomReady
The onload event fires when the document and it's script/style/image resources are loaded, but you probably don't want to wait for images if you are doing any javascript when the page is loaded. Also, it may cause UI errors if the user tries to interact with the page before the JavaScript event handlers have been applied to the DOM via the onload event - a limitation of onload event. Instead, use something like jQuery's "ready" event or fire your own "DOMReady" event by placing a script tag at the end of the body:


<body>
<!-- your page contents here -->
<script type="text/javascript">
// DOM is ready, do scripty stuff now
DOMReady();
</script>
</body>

Single threaded script processing
The client-side javascript is single threaded. This means that the parsing of (x)HTML documents stops while scripts are loaded and executed, and that web browsers stop responding to user input while event handlers are being executed.

This is a good thing, and a bad thing. It's good because you can rest comfortable knowing that two event handlers will never run at the same time. Also, you can manipulate document content knowing that no other thread is attempting to modify the same piece of content.

It's bad in that intensive scripts can hold up the user experience by causing periods of unresponsiveness from a JavaScript driven UI.

Monday, July 21, 2008

Utility Functions

1. Sorting with user defined comparator

In PHP -


usort($bp_radios, create_function('$a, $b',
'return $a["radio_index"] - $b["radio_index"];'));


In JS -

tabRF_apList[i]['radios'].sort(function(a,b) {
return a['radio_index'] - b['radio_index']});

2. Array <=> String with delimiter

In PHP -

$radio = implode('/', $radioNameArray); // {'a', 'b'} => 'a/b'
$radioNameArray = explode('/', $radio);

In JS -

var radio = radioNameArray.join('/');
var radioNameArray = radio.split("/");

Tuesday, July 8, 2008

dynamic variable

This article talks about different ways to compose dynamic Javascript variable -


eval('name' + i + ' = "Marco"'); // compose a string with variable as eval's argument
window['name' + i] = 'Marco';

And the PHP counterpart is:

${'name'.$i} = 'Marco';
echo 'ap_bVNSRadio_${vname}';

Friday, November 16, 2007

Javascript in depth


function User (name, age) {
   this.name=name;
   this.age=age;
}

/* User is a reference to the constructor */
User.prototype.getName = function() { ...}
// add new function to object prototype
User.prototype = new Person();
// inherit all of Person object's method, in JS, we inherit from physical object;
//it is like that you get all properties/methods when creating a new Person object
User.cloneUser = function(user) { ...} // static method

var user = new User("Bob", 33);


- what is constructor?
It is same as other function, but is invoked using keyword 'new'. Two things happen when invoke using 'new'
a) the context is switched to the created object, i.e., 'this' refers to object user. Otherwise, if invoke without new, this variable refers to root object window.
b) The constructor's prototype property (the public accessible one) is assigned to the new instance's private prototype.
In a nutshell, all JS objects have a private prototype property. I say "private" because this property is not directly visible or accessible from the object itself (but Visible for constructor!!). When the runtime performs a lookup on a property, it first looks at the instance to see if that property is defined there. If it is not defined there, the runtime looks for the property on the object's private prototype. Prototypes can have their own private prototype, so the search can keep working its way up the prototype chain.

- HTML DOM load
The order of loading is:
1. HTML is parsed
2. External scripts/style sheets (include the one in header) are loaded
3. Scripts are executed as they are parsed in the document (** significant problem: the scripts in these two places won't have accessed to DOM.)
4. HTML DOM is fully constructed. (inline scripts are executed as they are encountered. DOM is partially constructed atm)
5. Images and external content are loaded
6. The page is finished loading.

- Boolean operators
In JS, a||b <=> a?a:b a&&b <=> a?b:a they are not necessary return true or false as in Java/C. Lots of thing are "true" in JS, in fact, only things that are "false" are the false Boolean, the numbers 0 and NaN, the empty string, null and undefined.

e.g., var e = e.chileNodes || e; e = e || window.e; opt.time = opt.time || 400;

Thursday, September 20, 2007

Map representation in Spring & Javascript


<bean id="action2Dashboard" class="java.util.HashMap" singleton="true">
   <constructor-arg>
     <map>
       <entry key="/admin/license/installLicense.action">
       <value>system:administration_setupsupport.3</value>
       </entry>
       <entry key="/admin/agent/listAgents.action">
       <value>system:administration_agents.5</value>
     </entry>
     </map>
   </constructor-arg>
</bean>


self.dashboards = {
  "/admin/license/installLicense.action" : "system:administration_setupsupport.3",
  "/admin/agent/listAgents.action" : "system:administration_agents.5"
}

var dashboard = dashboards["/admin/licnese/installLicense.action"];

Tuesday, September 11, 2007

Javascript keyword "this"


function doSomething() {
this.style.color = '#cc0000';
}

In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. hen we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript.

An onclick property, though, is owned by the HTML element it belongs to.

element.onclick = doSomething;

The function is copied in its entirety to the onclick property (which now becomes a method). So if the event handler is executed this refers to the HTML element and its color is changed.

However, if you use inline event registration

<element onclick="doSomething()">

you do not copy the function! Instead, you refer to it, the this keyword once again refers to the global window

Thursday, September 6, 2007

Javacript location reload

- To refresh current iframe


parent.frames['contentBox'].location.reload();

- To refresh current page

document.location.reload()

one good example, after ajax session timeout, invoking this will be taken to logon page.

Tuesday, September 4, 2007

Javascript Object Literal

- Use object literals as flexible function parameters

Object literals are objects defined using braces ({}) that contain a set of comma separated key value pairs much like a map in Java.


{key1: "stringValue", key2: 2, key3: ['blue','green','yellow']}

The example above shows an object literal which contains a string, number, and array of strings. As you may imagine object literals are very handy in that they can be used as generic for passing in arguments to a function. The function signature does not change if you choose to require more properties in a function. Consider using object literal as the parameters for methods.

function doSearch(serviceURL, srcElement, targetDiv) {
var params = {service: serviceURL, method: "get", type: "text/xml"};
makeAJAXCall(params);
}


function makeAJAXCall(params) {
var serviceURL = params.service;
...
}

Also note that with object literals you can pass anonymous functions as may be seen in the following example:

function doSearch() {
makeAJAXCall({serviceURL: "foo",
method: "get",
type: "text/xml",
callback: function(){alert('call done');}
});
}

function makeAJAXCall(params) {
var req = // getAJAX request;
req.open(params.serviceURL, params.method, true);
req.onreadystatechange = params.callback;
...
}


Object literals should not be confused with JSON which has similar syntax. JSON is a subset of object literal notation of javascript.


self.dashboards = {
"/admin/license/installLicense.action" : "system:administration_setupsupport.3",
"/admin/agent/listAgents.action" : "system:administration_agents.5"
}

*** when needed, say there is '/' or space character, we can use double quote to escape it.

Monday, July 30, 2007

Javascript validation using keyCode check

The user is not able to enter certain characters using this approach.


function isDigit(e) {
if (!e) var e = window.event;

var code;
if(e.keyCode) {
code = e.keyCode;
} else if(e.which) {
code = e.which;
}
// 8-backspace, 9-tab, 13-enter, 46-delete
if (code == 8 || code == 9 || code == 13 || code == 46) {
return true;
}
var character = String.fromCharCode (code);
return '0' <= character && character <= '9';
}


<input type="text" name="versionMajor" onkeypress="return isDigit(event);" ../>

onkeydown: Returns a unique integer keyCode representing the the physical key that is pressed. e.g., "1" key on top of keyboard produce "49" whereas in numeric keypad produces "97" since they are different keys. For details.
onkeypress: Returns an integer keyCode representing the Unicode value of the character associated with the key. "1" key produces "49"; Also, for those shift, alt, ctrl combination keys, the combined result is produced such as SHIFT+3 = '#'

The onkeypress (or onkeydown) event hander to respond to a keystroke and to capture the keyCode. If the function returns true and the keystroke produces the character in the textbox. Otherwise, the function returns false and the character is not produced.

The function String.fromCharCode(unicode) is used to convert unicode to ASCII character.

BTW, the comparison of onmousedown and onclick:
onmousedown will trigger when either the left or right (or middle) is pressed. Similarly, onMouseUp will trigger when any button is released. onmousedown will trigger even when the mouse is clicked on the object then moved off of it, while onMouseUp will trigger if you click and hold the button elsewhere, then release it above the object.

onclick will only trigger when the left mouse button is pressed and released on the same object. In case you care about order, if the same object has all 3 events set, it's onmousedown, onMouseUp, then onclick. Each even should only trigger once though.

Thursday, May 31, 2007

Bitwise AND operator

To alternate the table background color:


rows [i].className = ((rows [i].index & 1) == 1) ? "alt" : "";

Friday, May 18, 2007

Javascript RegExp

- Example 1


var regex = /<title[^>]*>([\s\S]*?)<\/title>/i;
while(match = regex.exec(httpResp)){
if ('Login Page' == match[1]) {
...

"?" is important in the above regexp. By default it is greedy mode, with ?, it means the group will stop at the first encountered '<';

exec return ["<title>Login Page</title>", "Login Page"] since group () is used in regex which is useful to extract interested content.

-Example 2

html += ' <a href="javascript:showManyToMany (groupsForUser, \'' +
rowData.name.replace(/\'/g, "\\'").replace(/\"/g, "&.quot;") + '\');">Edit</a>';

In this case, single quote has to be escaped by javascript \\'; however Double quotes has to be escaped by html as &.quot; rather than \\", otherwise, "unterminated string literal" error occur. It looks like browser can understand \', but it doesn't
understand \".

- Example 3
cartName.replace(" ", "_"); will only replace first occurrence of space character. It should be cartName.replace(/\s/g, "_"). 1st parameter is regExp, rather than string, and /g means global search for all occurrences of a pattern. Note that the regular expression doesn't need to be quoted.

Thursday, May 17, 2007

Javascript undefined vs. null

In JavaScript, undefined means a variable has been declared but has not yet been assigned a value, such as:


var TestVar;
alert(TestVar); //shows undefined
alert(typeof TestVar); //shows undefined

null is an assignment value. It can be assigned to a variable as a representation of no value:

var TestVar = null;
alert(TestVar); //shows null
alert(typeof TestVar); //shows object

From the preceding examples, it is clear that undefined and null are two distinct types: undefined is a type itself (undefined) while null is an object.

Unassigned variables are initialized by JavaScript with a default value of undefined.

JavaScript never sets a value to null. That must be done programmatically. As such, null can be a useful debugging tool. If a variable is null, it was set in the program, not by JavaScript.

null values are evaluated as follows when used in these contexts:

Boolean: false
Numeric: 0
String: “null”

undefined values are evaluated as follows when used in these contexts:

Boolean: false
Numeric: NaN
String: “undefined”

.........................................................................................................................................................

null is an object. It's type is null. undefined is not an object, it's type is undefined.

Use if (SomeObject) to check value existence is not robust. It will also catch the cases of SomeObject having numeric value of 0, or string value of empty string. Because their boolean coercion is also false. See, in JavaScript, null and undefined are actually equal according to the == and != operator! (ECMA-262 standard, section 11.9.3 tells us so.) So we have null == undefined. In vast majority of cases, you don't care about the difference at all, so using someExpr != null is good enough.

If we really need to differentiate null and undefined, use

typeof(SomeObject) == 'undefined'

Saturday, April 14, 2007

Javascript with FreeMarker & WebWork


window.parent.lastAction = "${request.requestURI}";

FreeMarker's interpolation ${expression} works inside Javascript too. Through it, WebWork's action context, value stack are accessible in Javascript and is useful in some cases. Note that the expression needs to be quoted.

Another example is:

<@ww.text id="LoadingText" name="common.message.flow.loading"/>

in script:

var messageDialog = dojo.widget.byId ('messageDialog');
messageDialog.domNode.innerHTML ="${LoadingText}"

In this way, the internalizationed text is passed to Javascript since the text is saved in the action context with the specified id attribute. [The objects in webwork are stored in five scopes: default (action context), session, application, request. Action context is a ThreadLocal storage available only during action execution.]

-- 山光悦鸟性, 潭影空人心。