<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-30307970</id><updated>2023-08-08T06:03:17.658-06:00</updated><title type='text'>Too much recursion</title><subtitle type='html'>Higher Order Javascript</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default?alt=atom&amp;start-index=26&amp;max-results=25'/><author><name>richard.m</name><uri>http://www.blogger.com/profile/08207518154334111142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-30307970.post-115905190458601827</id><published>2006-09-23T16:49:00.000-06:00</published><updated>2006-09-23T20:15:34.003-06:00</updated><title type='text'>IE 5.5 IE6.x Transparent PNG fix + Mimified Brothercake Browser Detect</title><content type='html'>IE png fix. Works well. Included with a condensed/optimized version of Brothercake&#39;s Browser Detection Script. Read comments for use with or without browser detection.&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;// minified Brothercake browser detection object (thanks bro!)&lt;br /&gt;// usage: alert(Browser.browser+&#39;\n&#39;+Browser.version+&#39;\n&#39;+Browser.OS)&lt;br /&gt;var Browser = {&lt;br /&gt;  init: function () {&lt;br /&gt;    this.browser = this.searchString(this.dataBrowser) || &quot;An unknown browser&quot;;&lt;br /&gt;    this.version = this.searchVersion(navigator.userAgent)&lt;br /&gt;      || this.searchVersion(navigator.appVersion)  || &quot;an unknown version&quot;;&lt;br /&gt;    this.OS = this.searchString(this.dataOS) || &quot;an unknown OS&quot;;&lt;br /&gt;  },&lt;br /&gt;  searchString: function (data) {&lt;br /&gt;    for (var i=0,len=data.length;i&lt;len;i++)  {&lt;br /&gt;      var dataString = data[i].string, dataProp = data[i].prop;&lt;br /&gt;      this.versionSearchString = data[i].versionSearch || data[i].identity;&lt;br /&gt;      if((dataString) &amp;&amp; (dataString.indexOf(data[i].subString) != -1)||(dataProp)){&lt;br /&gt;         return data[i].identity&lt;br /&gt;  } }  },&lt;br /&gt;  searchVersion: function (dataString) {&lt;br /&gt;    var index = dataString.indexOf(this.versionSearchString); if (index == -1) return;&lt;br /&gt;    return parseFloat(dataString.substring(index+this.versionSearchString.length+1));&lt;br /&gt;  },&lt;br /&gt;  dataBrowser: [&lt;br /&gt;    {string: navigator.vendor,   subString: &quot;Apple&quot;,    identity: &quot;Safari&quot;},&lt;br /&gt;    {prop:   window.opera,identity: &quot;Opera&quot;},&lt;br /&gt;    {string: navigator.vendor,   subString: &quot;iCab&quot;,    identity: &quot;iCab&quot;},&lt;br /&gt;    {string: navigator.vendor,   subString: &quot;KDE&quot;,     identity: &quot;Konqueror&quot;},&lt;br /&gt;    {string: navigator.userAgent,subString: &quot;Firefox&quot;, identity: &quot;Firefox&quot;},&lt;br /&gt;    {string: navigator.userAgent,subString: &quot;Netscape&quot;,identity: &quot;Netscape&quot;},// for newer Netscapes (6+)&lt;br /&gt;    {string: navigator.userAgent,subString: &quot;MSIE&quot;,    identity: &quot;IE&quot;,      versionSearch: &quot;MSIE&quot;},&lt;br /&gt;    {string: navigator.userAgent,subString: &quot;Gecko&quot;,   identity: &quot;Mozilla&quot;,  versionSearch: &quot;rv&quot;},&lt;br /&gt;    {string: navigator.userAgent,subString: &quot;Mozilla&quot;, identity: &quot;Netscape&quot;,versionSearch: &quot;Mozilla&quot;}],// for older Netscapes (4-)&lt;br /&gt;  dataOS : [&lt;br /&gt;    {string: navigator.platform, subString: &quot;Win&quot;,     identity: &quot;Windows&quot;},&lt;br /&gt;    {string: navigator.platform, subString: &quot;Mac&quot;,     identity: &quot;Mac&quot;    },&lt;br /&gt;    {string: navigator.platform, subString: &quot;Linux&quot;,   identity: &quot;Linux&quot;  }]&lt;br /&gt;};&lt;br /&gt;Browser.init();&lt;br /&gt;&lt;br /&gt;// IE PNG FIX: correctly handle PNG transparency in Win IE 5.5 &gt; 6.x&lt;br /&gt;if((Browser.version&gt;5.4) &amp;&amp; (Browser.version&lt;7) &amp;&amp; (Browser.browser==&#39;IE&#39;)){&lt;br /&gt;// uncomment line below and comment line above to become independent of browser detect script&lt;br /&gt;//if(window.attachEvent &amp;&amp; (parseFloat(navigator.appVersion.split(&quot;MSIE&quot;)[1])&lt;7)){&lt;br /&gt;window.attachEvent(&quot;onload&quot;,function(){   if (document.body.filters){ &lt;br /&gt;  var i=document.images.length; while(i--){    &lt;br /&gt;    var img = document.images[i], imgName = img.src.toUpperCase();      &lt;br /&gt;    if (imgName.substring(imgName.length-3, imgName.length) == &quot;PNG&quot;){ var&lt;br /&gt;      imgID = (img.id) ? &quot;id=&#39;&quot; + img.id + &quot;&#39; &quot; : &quot;&quot;,        &lt;br /&gt;      imgClass = (img.className) ? &quot;class=&#39;&quot; + img.className + &quot;&#39; &quot; : &quot;&quot;,&lt;br /&gt;      imgTitle = (img.title) ? &quot;title=&#39;&quot; + img.title + &quot;&#39; &quot; : &quot;title=&#39;&quot; + img.alt + &quot;&#39; &quot;,&lt;br /&gt;      imgStyle = &quot;display:inline-block;&quot; + img.style.cssText;&lt;br /&gt;      if (img.align == &quot;left&quot;) image.align=&#39;left&#39;; //imgStyle = &quot;float:left;&quot; + imgStyle        &lt;br /&gt;      if (img.align == &quot;right&quot;)image.align=&#39;left&#39;; //imgStyle = &quot;float:right;&quot;+ imgStyle        &lt;br /&gt;      if (img.parentElement.href) imgStyle = &quot;cursor:pointer;&quot; + imgStyle        &lt;br /&gt;      img.outerHTML= &quot;&lt;span &quot; + imgID + imgClass + imgTitle&lt;br /&gt;        + &quot; style=\&quot;&quot; + &quot;width:&quot; + img.width + &quot;px; height:&quot; + img.height + &quot;px;&quot; + imgStyle + &quot;;&quot;&lt;br /&gt;        + &quot;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader&quot;&lt;br /&gt;        + &quot;(src=\&#39;&quot; + img.src + &quot;\&#39;, sizingMethod=&#39;scale&#39;);\&quot;&gt;&lt;/span&gt;&quot; &lt;br /&gt;} } } } ) }; &lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115905190458601827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115905190458601827' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115905190458601827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115905190458601827'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/ie-55-ie6x-transparent-png-fix.html' title='IE 5.5 IE6.x Transparent PNG fix + Mimified Brothercake Browser Detect'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115899792268385650</id><published>2006-09-23T01:01:00.000-06:00</published><updated>2006-09-23T03:04:39.033-06:00</updated><title type='text'>Function.prototype.toEvent (bindAsEventListener)</title><content type='html'>&lt;strong&gt;Function.prototype.toEvent&lt;/strong&gt;&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;Function.prototype.bindEventListener&lt;/strong&gt;&lt;br/&gt;&lt;br /&gt;This one keeps this and sends event object as the first argument (no more checking!). It also has only one parameter or parameters maybe- the argument/s you want to send to your function. Thats it! Bonus: the last argument is the co-ordinates of the event.&lt;br /&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;Say you want to attach an onclick event to a button with id of &#39;myBut&#39;:&lt;pre class=&quot;code&quot;&gt;document.getElementById(&#39;myBut&#39;).onclick=&lt;/pre&gt;So far so good. Lets make a function for it to connect to. Remember, the first argument of an event is e. (IE doesn&#39;t use that, but we&#39;ve made IE act like the rest now). Notice how this is our button.&lt;pre class=&quot;code&quot;&gt;function doSomTing(e,h,w){&lt;br /&gt;  alert(this.nodeName+ &quot; &quot; h + w); &lt;br /&gt;}&lt;/pre&gt;    &lt;br /&gt;OK. so lets attach this function to our event. We need to pass 2 arguments (e is automagically sent):&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;document.getElementById(&#39;myBut&#39;).onclick= doSomTing.toEvent(&#39;Hello &#39;,&#39;World&#39;)&lt;/pre&gt;&lt;br /&gt;Here it is:&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;// Function.prototype.toEvent, .bindAsEventListener( args ) rem2006  &lt;br /&gt;// Important: sends event as the first argument to your function in IE also!, &lt;br /&gt;// event XY [Array][x,y] is passed as last arg, your passed args are in the middle :)&lt;br /&gt;// example: myElement.onclick= myFunc.toEvent( myArguments );&lt;br /&gt;//   &lt;br /&gt;Function.prototype.toEvent = Function.prototype.bindAsEventListener= function(){&lt;br /&gt;  var _method= this, r=[], len=arguments.length, i=0;//alert(len)&lt;br /&gt;  for (i;i&lt;len;i++){ r[i+1]=arguments[i] }&lt;br /&gt;  return function( ev ){  r[0]= ev= ev || event; &lt;br /&gt;    var db=document.body, dd=document.documentElement;&lt;br /&gt;    r[r.length++]=(ev.pageX)? [ev.pageX, ev.pageY] : &lt;br /&gt;      [ev.clientX + db.scrollLeft+ dd.scrollLeft, &lt;br /&gt;       ev.clientY + db.scrollTop + dd.scrollTop];&lt;br /&gt;    return _method.apply(ev.target|| ev.srcElement, r);&lt;br /&gt;  };&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115899792268385650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115899792268385650' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115899792268385650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115899792268385650'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/functionprototypetoevent.html' title='Function.prototype.toEvent (bindAsEventListener)'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115891894437380729</id><published>2006-09-22T03:51:00.000-06:00</published><updated>2006-09-22T03:55:44.386-06:00</updated><title type='text'>String.prototype.exe part2</title><content type='html'>Think I got it this time:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;// executes string as body of function, args = comma seprated arguments&lt;br /&gt;// ex.: &#39;var h=arguments[0]; var w=arguments[1]; alert(h+&quot;\\n&quot;+w)&#39;.exe(&#39;Hello&#39;,&#39;World&#39;);&lt;br /&gt;String.prototype.exe = function(){ &lt;br /&gt;  eval( &#39;function(){&#39; +this+ &#39;}&#39; ).apply(this,arguments); &lt;br /&gt;};&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115891894437380729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115891894437380729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115891894437380729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115891894437380729'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/stringprototypeexe-part2.html' title='String.prototype.exe part2'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115872048127221181</id><published>2006-09-19T20:42:00.000-06:00</published><updated>2006-09-19T20:48:01.286-06:00</updated><title type='text'>Javascript Speed Tester new version</title><content type='html'>Test your javascript functions out with &lt;strong&gt;jsSpeedTester v0.45:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;online: &lt;a href=&quot;http://ottbot.hismercy.ca&quot;&gt;http://ottbot.hismercy.ca&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;download with this.js api: &lt;a href=&quot;http://ottbot.hismercy.ca/jsSpeedTester.v.0.45.zip&quot;&gt;http://ottbot.hismercy.ca/jsSpeedTester.v.0.45.zip&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115872048127221181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115872048127221181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115872048127221181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115872048127221181'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/javascript-speed-tester-new-version.html' title='Javascript Speed Tester new version'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115848998965340871</id><published>2006-09-17T04:21:00.000-06:00</published><updated>2006-09-17T05:07:05.926-06:00</updated><title type='text'>goodbye expando hello addData, getData</title><content type='html'>Why are expando&#39;s needed? To hold data. Sometimes, the data is another node(bad for ie). So how do we store data about an element? Say a div wants to know who its 2 &#39;brother nodes&#39; are, or an element wants to keep track of its size changes? Whatever, check this out:&lt;pre class=&#39;code&#39;&gt;&lt;br /&gt;String.prototype.addData= String.prototype.ad = function(n,v){&lt;br /&gt;  if (!window.elData){window.elData=[]}&lt;br /&gt;  if( !elData[this] ){ elData[this]=[] } &lt;br /&gt;  if( !n ){ elData[elData.length++]=this }else{ elData[this][n]=v }; &lt;br /&gt;  return this;&lt;br /&gt;};  &lt;br /&gt;String.prototype.getData= String.prototype.gd = function(n){&lt;br /&gt;  return( n )? elData[this][n] : elData[this];&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;Now add all the data you want.  Say the div previously mentioned has an id of &#39;blah&#39;:&lt;br /&gt;&lt;pre class=&#39;code&#39;&gt;&#39;blah&#39;.ad(&#39;b1&#39;,&#39;divb1id&#39;).ad(&#39;b2&#39;,&#39;divb2id&#39;);&lt;br /&gt;el.id.ad(size);&lt;/pre&gt;&lt;br /&gt;Getting the data is also easy:&lt;br /&gt;&lt;pre class=&#39;code&#39;&gt;b1= &#39;blah&#39;.gd(&#39;b1&#39;); b2= &#39;blah&#39;.gd(&#39;b1&#39;);&lt;br /&gt;getSizeHistory=el.id.gd(); &lt;/pre&gt;&lt;br /&gt;This can also be used for classNames, function args...</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115848998965340871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115848998965340871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115848998965340871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115848998965340871'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/goodbye-expando-hello-adddata-getdata.html' title='goodbye expando hello addData, getData'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115848239909702334</id><published>2006-09-17T02:31:00.000-06:00</published><updated>2006-09-17T02:39:59.120-06:00</updated><title type='text'>String.prototype.cssObj</title><content type='html'>&lt;code&gt;String.prototype.cssObj( styleObject[Object][optional] )&lt;/code&gt;&lt;br /&gt;&lt;pre class=&#39;code&#39;&gt;String.prototype.cssObj= function( styleObj ){ styleObj = styleObj || {};&lt;br /&gt;  var  pairs=this.replace( /(^\s*)|(;\s*$)/g, &#39;&#39; ).split( /\s*;\s*/ ),selector,propAndVal,i=pairs.length;&lt;br /&gt;  while( i-- ){ propAndVal= pairs[i].split( /\s*:\s*/ );&lt;br /&gt;    selector=propAndVal[0] ;if( selector.match(/-/) ){ selector=selector.cc() }&lt;br /&gt;    styleObj[ selector ]= propAndVal[1].toLowerCase()};  return styleObj;&lt;br /&gt;};&lt;br /&gt;String.prototype.camelCase= String.prototype.cc = function(){&lt;br /&gt;  return this.replace(/-\D/gi, function(match){return match.charAt(match.length - 1).toUpperCase()} );&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code fits in wonderfully with many of the dom creation functions around, like the one on here. Example:&lt;pre class=&#39;code&#39;&gt;var s={ backgroundColor:&#39;#f00&#39;,position:&#39;absolute&#39;, width:&#39;50px&#39;, height:&#39;50px&#39;};&lt;br /&gt;&#39;padding:5px; border-width:4px; border-style:solid; border-color:#333&#39;.cssObj(s);&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115848239909702334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115848239909702334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115848239909702334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115848239909702334'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/09/stringprototypecssobj.html' title='String.prototype.cssObj'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115613938030143131</id><published>2006-08-20T23:40:00.000-06:00</published><updated>2006-08-20T23:49:40.313-06:00</updated><title type='text'>Easy Class setTimeout call keeping &#39;this&#39;</title><content type='html'>I&#39;m working on an a.p.i called this.js. Its a jquery clone in its functionality... I needed to call functions within the same class, keeping this all the same. (arguments can be passed using the same technique, but it borks in IE6..its better to have the arguments as class members anyway).  Here is some code from this.js showing the technique:&lt;br /&gt;&lt;pre class=&#39;code&#39;&gt;/// fadeIn &lt;br /&gt;this.fadeIn= function ( speed, delay ){    &lt;br /&gt;    this.el.style.visibility=&#39;visible&#39;; &lt;br /&gt;    this.op(0); this._fadeIn.count = 0;    &lt;br /&gt;    if (delay) {  var _me=this; &lt;br /&gt;        setTimeout(  function(){_me._argList[1]= speed; _me._fadeIn()}, delay*1000, _me  );  &lt;br /&gt;    } // call the fade function and returns this&lt;br /&gt;    else{ this._argList[1]= speed; this._fadeIn() }; return this;       &lt;br /&gt;};&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115613938030143131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115613938030143131' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115613938030143131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115613938030143131'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/08/easy-class-settimeout-call-keeping.html' title='Easy Class setTimeout call keeping &#39;this&#39;'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115485695853288220</id><published>2006-08-06T03:08:00.000-06:00</published><updated>2006-09-23T02:04:43.056-06:00</updated><title type='text'>DOM Node Creation Helpers</title><content type='html'>These are the foundation of this.js(another a.p.i!), available for download.&lt;pre class=&quot;code&quot;&gt;&lt;code&gt;// DOM Node Creation Helpers R.E.M. Aug.2006&lt;br /&gt;// Generic Get Element,     $,  getEl()          &lt;br /&gt;// Args:[id],[element],[array]of.. Returns: [element] or [array] of elements&lt;br /&gt;var $ = function getEl(e) {  &lt;br /&gt;    if (typeof e == &#39;string&#39;) {return window.document.getElementById(e);}  &lt;br /&gt;    if (e[0]) {var i=e.length; while(i--){e[i]=arguments.callee(e[i]);}return e;} &lt;br /&gt;    return e;  //element&lt;br /&gt;}&lt;br /&gt;// Generic Append Element(),$A, appendElement()&lt;br /&gt;// Appends [element] to [element] or [Array] of elements &lt;br /&gt;var appendElement = $A =function(bag, marbles) {&lt;br /&gt;    if (marbles.constructor == Array){var l=marbles.length,i;&lt;br /&gt;    for(i=0;i&lt;l;i++){bag.appendChild(marbles[i]);}}&lt;br /&gt;    else {bag.appendChild(marbles);}    return bag;&lt;br /&gt;}&lt;br /&gt;// Generic Create Element,  $X,  exNihilo()&lt;br /&gt;// Creates element and/or adds attributes to node and/or adds styles to node&lt;br /&gt;var exNihilo = $X =function (el,attributes,styles) {&lt;br /&gt;   if (el===&#39;textnode&#39;)&lt;br /&gt;   { return document.createTextNode(((attributes)? attributes:&#39; &#39;));   }&lt;br /&gt;   var node=(el.constructor==String)?document.createElement(el): el,arg; &lt;br /&gt;   if (attributes){for (arg in attributes){node[arg]=attributes[arg];} }    &lt;br /&gt;   if (styles)    {for (arg in styles) {node.style[arg]= styles[arg];} }    &lt;br /&gt;   return node;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115485695853288220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115485695853288220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115485695853288220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115485695853288220'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/08/dom-node-creation-helpers.html' title='DOM Node Creation Helpers'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115474074371696354</id><published>2006-08-04T19:14:00.000-06:00</published><updated>2006-08-04T19:23:22.616-06:00</updated><title type='text'>FireFox innerText</title><content type='html'>FireFox, Opera innerText fix: &lt;pre class=&quot;code&quot;&gt;// Firefox InnerText R.E.M 2006&lt;br /&gt;// Credits: Matthias Hertel , Erik Arvidsson, check by jvance&lt;br /&gt;// emulates IE&#39;s innertext on Firefox&#39;s Proprietary __defineGetter__ &lt;br /&gt;if (typeof HTMLElement != &quot;undefined&quot; &amp;&amp; typeof HTMLElement.prototype.__defineGetter__ != &quot;undefined&quot;) {&lt;br /&gt;  HTMLElement.prototype.__defineGetter__(&quot;innerText&quot;, function () {&lt;br /&gt;    if (this.textContent) { return(this.textContent)   }&lt;br /&gt;    else{var r=this.ownerDocument.createRange(); r.selectNodeContents(this);return r.toString();}});&lt;br /&gt;  HTMLElement.prototype.__defineSetter__(&quot;innerText&quot;, function (sText) {&lt;br /&gt;    if  (this.textContent)  {this.innerHTML=sText.textContent; }&lt;br /&gt;    else {this.innerHTML = sText.replace(/\&amp;/g, &quot;&amp;amp;&quot;).replace(/&lt;/g, &quot;&amp;lt;&quot;).replace(/&gt;/g, &quot;&amp;gt;&quot;);  }}  );&lt;br /&gt;}&lt;br /&gt;// opera innerText is broken&lt;br /&gt;String.fixText=function($INPUT) {&lt;br /&gt;   return $INPUT.replace(/\&amp;amp;/g, &quot;&amp;&quot;).replace(/\&amp;lt;/g, &quot;&lt;&quot;).replace(/\&amp;gt;/g, &quot;&gt;&quot;);&lt;br /&gt;} &lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115474074371696354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115474074371696354' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115474074371696354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115474074371696354'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/08/firefox-innertext.html' title='FireFox innerText'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/08207518154334111142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115473071356110829</id><published>2006-08-04T16:30:00.000-06:00</published><updated>2006-08-06T08:12:34.613-06:00</updated><title type='text'>DOM Node Creation Helper Function-updated</title><content type='html'>&lt;b&gt;Updated:&lt;/b&gt; Added functionality for text node creation: Just pass in node type as &#39;textnode&#39; and then the second argument is your text, defaults to &lt;space&gt; if omitted.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Updated:&lt;/b&gt; Now you can use it to add styles or attributes to an existing node. Just pass in the node (instead of a type of node).&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;// Generic Create Element,  $X,  exNihilo() R.E.M. 2006 &lt;br /&gt;// Creates element and/or adds attributes to node and/or adds styles to node&lt;br /&gt;var exNihilo = $X =function (el,attributes,styles) {&lt;br /&gt;   if (el===&#39;textnode&#39;)&lt;br /&gt;  { return document.createTextNode(((attributes)? attributes:&#39; &#39;));   }&lt;br /&gt;   var node=(el.constructor==String)?document.createElement(el): el,arg; &lt;br /&gt;   if (attributes){for (arg in attributes){node[arg]=attributes[arg];} }    &lt;br /&gt;   if (styles)    {for (arg in styles) {node.style[arg]= styles[arg];} }    &lt;br /&gt;   return node;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;You can call it with some code like this:&lt;pre class=&quot;code&quot;&gt;var node=exNihilo( &#39;span&#39;,&lt;br /&gt;     {innerHTML:&#39;hello World&#39;},&lt;br /&gt;     {border:&#39;2px solid red&#39;,padding:&#39;20px&#39;} )&lt;br /&gt;&lt;br /&gt;document.body.appendChild(node);&lt;/pre&gt;To add styles or attributes to existing nodes, pass in a node[element] instead of nodeType[string]:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;// change/add color style of node&lt;br /&gt;$X(node,0,{color:&#39;#ff0000&#39;})&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115473071356110829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115473071356110829' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115473071356110829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115473071356110829'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/08/dom-node-creation-helper-function.html' title='DOM Node Creation Helper Function-updated'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/08207518154334111142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115409605847766141</id><published>2006-07-28T08:06:00.000-06:00</published><updated>2006-09-23T16:58:12.506-06:00</updated><title type='text'>Bizzare Firefox Speed Tests</title><content type='html'>Here are some speed tests done in Firefox. IE6 does not exibit same behaviour. Anybody can come up with a &#39;best practises&#39; rule after looking this please post it.&lt;br /&gt;I&#39;d say, instantate your objects with the same type &lt;em&gt;before&lt;/em&gt; you get/set them within a loop.&lt;br /&gt;&lt;table style=&quot;BACKGROUND-COLOR: #ffeee8&quot; cellspacing=&quot;0&quot; cellpadding=&quot;5&quot; width=&quot;600&quot; border=&quot;1&quot;&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;#TEST&lt;/td&gt;&lt;td&gt;FUNCTION&lt;/td&gt;&lt;br /&gt;&lt;td&gt;SECONDS&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;76&quot;&gt;#1&lt;/td&gt;&lt;td width=&quot;450&quot;&gt;&lt;pre&gt;var _test2={};&lt;br /&gt;%%&lt;br /&gt;_test2._value = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;1.139 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;#3&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={};_test2._value=0;&lt;br /&gt;%%&lt;br /&gt;_test2._value.mmm = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;36.800 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;#4&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={};_test2._value=0;_test2._value.mmm=123;&lt;br /&gt;%%&lt;br /&gt;_test2._value.mmm = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;28.275 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;#5&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={_value:123};&lt;br /&gt;%%&lt;br /&gt;_test2._value.mmm = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;30.300 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;#6&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={_value:{mmm:123}};&lt;br /&gt;%%&lt;br /&gt;_test2._value.mmm = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;1.276 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td id=&quot;ww&quot;&gt;#7&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={};_test2._value={};_test2._value.mmm=123;&lt;br /&gt;%%&lt;br /&gt;_test2._value[&#39;mmm&#39;] = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;1.326 µs&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td id=&quot;ww&quot;&gt;#8&lt;/td&gt;&lt;td&gt;&lt;pre&gt;var _test2={};_test2._value={};&lt;br /&gt;%%&lt;br /&gt;_test2._value.mmm = 123;&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;1.339 µs&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115409605847766141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115409605847766141' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115409605847766141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115409605847766141'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/bizzare-firefox-speed-tests.html' title='Bizzare Firefox Speed Tests'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/08207518154334111142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115398155406115300</id><published>2006-07-27T00:05:00.000-06:00</published><updated>2006-07-27T00:25:54.096-06:00</updated><title type='text'>Higher Order DOM Scripting</title><content type='html'>Here is an example of using functional programming to speed up DOM scripting.  We&#39;ll take a Quirksmode text select script, (beautiful in its own right), and give it the functional treatment. &lt;br /&gt;After the first function call(in this case), or after initialization, what this type of programming gives us is a function that no longer needs any environment object checks.  This is as fast as browser programming can get.&lt;pre class=&quot;code&quot;&gt;//Select text from http://www.quirksmode.org/js/selected.html&lt;br /&gt;function getSel(){&lt;br /&gt;  if (window.getSelection){&lt;br /&gt;   getSel=function(){return window.getSelection() }; return getSel() }&lt;br /&gt; else if (document.getSelection){&lt;br /&gt;   getSel=function(){return document.getSelection()};return getSel() } &lt;br /&gt; else if (document.selection){&lt;br /&gt;   getSel=function(){return document.selection.createRange().text};return getSel() }&lt;br /&gt; else {getSel=function(){return null}}&lt;br /&gt;}&lt;br /&gt;document.onmouseup=function(){ alert(getSel()) };&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115398155406115300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115398155406115300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115398155406115300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115398155406115300'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/higher-order-dom-scripting.html' title='Higher Order DOM Scripting'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/08207518154334111142</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115369096800757744</id><published>2006-07-23T15:24:00.000-06:00</published><updated>2006-07-25T00:12:10.800-06:00</updated><title type='text'>Say Your Prayers with Javascript</title><content type='html'>Boy I love Javascript. Now its even saying my prayers for me. :)&lt;br /&gt;Heres an app I coded, called Rosary.Beads.v1.0.&lt;br /&gt;It says the rosary (a Catholic prayer said on beads) automatically.&lt;br /&gt;It features low tech cross-domain &#39;ajax&#39; counter, 2 images, flash audio, and slightly overcomplicated js. ;)&lt;br /&gt;&lt;a href=&quot;http://www.hismercy.ca/rosary/index.html#&quot;&gt;Online Link&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.hismercy.ca/rosary/Rosary.zip&quot;&gt;Download link &lt;/a&gt;&lt; ~360k &lt;a href=&quot;http://www.hismercy.ca/rosary/Rosary.zip&quot;&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115369096800757744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115369096800757744' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115369096800757744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115369096800757744'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/say-your-prayers-with-javascript.html' title='Say Your Prayers with Javascript'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115367785661926140</id><published>2006-07-23T12:03:00.000-06:00</published><updated>2006-07-28T08:42:19.660-06:00</updated><title type='text'>Confirm User Exit</title><content type='html'>Here is some code that alerts users that leaving the page might be a bad idea. It counts the number of attempts to leave the page and stops displaying the message after n attempts.&lt;pre class=&quot;code&quot;&gt;function confirmExit(){&lt;br /&gt; if(!this.times) {this.times=0}&lt;br /&gt; times++; if(times==2){window.onbeforeunload=&#39;&#39;}&lt;br /&gt; return &#39;All your sensitive information (email,posts,Google searches) &#39;+&lt;br /&gt;  &#39;is gathered by smart routers and warehoused in your namespace&#39;;&lt;br /&gt;}&lt;br /&gt;window.onbeforeunload= confirmExit;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115367785661926140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115367785661926140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115367785661926140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115367785661926140'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/confirm-user-exit.html' title='Confirm User Exit'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115337092389089080</id><published>2006-07-19T22:44:00.000-06:00</published><updated>2006-07-21T23:44:54.623-06:00</updated><title type='text'>Your GUI &amp; CSS- just say no</title><content type='html'>Here is one large web app developer saying no to the use of CSS. &lt;a href=&quot;http://qooxdoo.org/documentation/developer/why_we_don_t_use_css_for_appearance&quot;&gt;Why we don&#39;t use css for appearance&lt;/a&gt;!&lt;br /&gt;Gotta love it!&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115337092389089080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115337092389089080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115337092389089080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115337092389089080'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/your-gui-css-just-say-no.html' title='Your GUI &amp; CSS- just say no'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115327261700531377</id><published>2006-07-18T19:22:00.000-06:00</published><updated>2006-07-21T21:47:48.566-06:00</updated><title type='text'>Function Fun</title><content type='html'>Here I&#39;ll post some small functions.  Hopefully a few will give you a smile :) &lt;pre class=&quot;code&quot;&gt;myFun=function(){&lt;br /&gt;  var me=arguments.callee;&lt;br /&gt;  me.browser= (document.all) &lt;br /&gt;   ? function(){alert(&quot;Hi I&#39;m IE&quot;)} : function(){alert(&quot;Hi I&#39;m FireFox&quot;)}; &lt;br /&gt; myFun=function(myFun){&lt;br /&gt;   arguments.callee.caller.browser();&lt;br /&gt;  alert(myFun);&lt;br /&gt; }&lt;br /&gt; myFun(myFun);&lt;br /&gt;}();&lt;br /&gt;&lt;/pre&gt;This function at first glance exhibits some strange behaviour.  Not the fact that it tests for document.all ;), but the result of alert(myFun).  I thought it would have been == arguments.callee.caller, like this:&lt;pre class=&quot;code&quot;&gt;myFun=function(){&lt;br /&gt;  var me=arguments.callee;&lt;br /&gt;  me.browser= (document.all) &lt;br /&gt;   ? function(){alert(&quot;Hi I&#39;m IE&quot;)} : function(){alert(&quot;Hi I&#39;m FireFox&quot;)}; &lt;br /&gt; myFun=function(myFun){&lt;br /&gt;   me.browser();&lt;br /&gt;  alert(arguments.callee.caller+&quot;\n~~~~~~~~~~\n&quot;+myFun);&lt;br /&gt; }&lt;br /&gt; myFun(me);&lt;br /&gt;}();&lt;br /&gt;alert(myFun);&lt;/pre&gt;Result of alert(myFun): undefined... and&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;myFun=function(){&lt;br /&gt;  var me=arguments.callee;&lt;br /&gt;  me.browser= (document.all) &lt;br /&gt;   ? function(){alert(&quot;Hi I&#39;m IE&quot;)} : function(){alert(&quot;Hi I&#39;m FireFox&quot;)}; &lt;br /&gt; myFun=function(){&lt;br /&gt;   me.browser();&lt;br /&gt;  alert(arguments.callee.caller+&quot;\n~~~~~~~~~~\n&quot;+myFun);&lt;br /&gt; }&lt;br /&gt; myFun(me);&lt;br /&gt;}();&lt;br /&gt;alert(myFun);&lt;br /&gt;&lt;/pre&gt;Result of alert(myFun): undefined... and here is an anonymous function: &lt;pre class=&quot;code&quot;&gt;new function(){&lt;br /&gt;    arguments[0].message();&lt;br /&gt;}({message:function(){alert(&#39;called by null&#39;)}});&lt;/pre&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115327261700531377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115327261700531377' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115327261700531377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115327261700531377'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/function-fun.html' title='Function Fun'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115311382239009569</id><published>2006-07-16T22:36:00.000-06:00</published><updated>2006-07-17T03:09:38.723-06:00</updated><title type='text'>Namespacing and Application Structure #1</title><content type='html'>I use the YAHOO style architecture; thanks in no small part to Dusin Diaz. But even with his good &lt;a href=&quot;http://www.dustindiaz.com/javascript-private-public-privileged/&quot;&gt;examples&lt;/a&gt;, I still didn&#39;t feel at home. Then I came across this code:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;__=function typesNamespace(){&lt;br /&gt;  window.isBool = function(a){&lt;br /&gt;    return typeof a==&#39;boolean&#39;;&lt;br /&gt;}}();&lt;br /&gt;// alert(__); = &#39;undefined&#39;&lt;br /&gt;// alert(typesNamespace) = &#39;error undefined&#39; ???&lt;/pre&gt;Which confused me (not hard). The author emailed me back and explained:&lt;br /&gt;&lt;br /&gt;&quot;It is actually the exact same thing as writing:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;window.isBool = ....&lt;/pre&gt;The types namespace isn&#39;t a great example, but the reason I do this is so that I can have private variables that don&#39;t pollute the global namespace:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;(function whateverNamespace(){&lt;br /&gt;   var AAA, BBB;&lt;br /&gt;&lt;br /&gt;   _w.someFunction = function(){&lt;br /&gt;      // do stuff with AAA or BBB&lt;br /&gt;   }&lt;br /&gt;})();&lt;/pre&gt;This way AAA and BBB don&#39;t exist under window[].&quot;-Mark&lt;br /&gt;&lt;br /&gt;~~~~~~~~~~~~~~~~&lt;br /&gt;&lt;br /&gt;Here is a couple blocks of code which are under the REM namespace, both blocks do the same thing. Looking at the first block tells me what is actually happening.&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;// block #A&lt;br /&gt;var REM={};&lt;br /&gt;(function(){&lt;br /&gt;  REM.b=b=&#39;boolean&#39;;//b is private&lt;br /&gt; REM.isBool = function(a){&lt;br /&gt;  return typeof a==b;&lt;br /&gt; }&lt;br /&gt;})();&lt;br /&gt;alert(REM.isBool + &quot;\n&quot;+ REM.isBool(true) + &quot;\n&quot; + REM.b);&lt;br /&gt;//&lt;br /&gt;// block #B&lt;br /&gt;var REM=function(){&lt;br /&gt;  var b=&#39;boolean&#39;; //b is private&lt;br /&gt; return { isBool: function(a){&lt;br /&gt;    return typeof a==b;&lt;br /&gt;   },          b: b     // but b is returned here&lt;br /&gt; }&lt;br /&gt;}();&lt;br /&gt;alert(REM.isBool + &quot;\n&quot;+ REM.isBool(true) + &quot;\n&quot; + REM.b);&lt;/pre&gt;~~~~~~~~~~~~~~~~</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115311382239009569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115311382239009569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115311382239009569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115311382239009569'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/namespacing-and-application-structure.html' title='Namespacing and Application Structure #1'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115287131389686606</id><published>2006-07-14T04:00:00.000-06:00</published><updated>2006-07-15T18:39:28.856-06:00</updated><title type='text'>Quick and Dirty Multiple Inheritence in Javascript</title><content type='html'>This has no checks for overriding properties so last object(arguement) wins:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;/*function newObject() richard maloney 2006 &lt;br /&gt;  Args: 2+ objects&lt;br /&gt;  Usage:send in n objects and it&#39;ll return one object inheriting&lt;br /&gt;        all the prop &amp; methods of the objects passed in       */ &lt;br /&gt;function object() { &lt;br /&gt;  var o=arguments,len=o.length-1,nextObj; &lt;br /&gt;  while(len--){&lt;br /&gt;    function f() {}  &lt;br /&gt;    f.prototype =o[0], nextO=o[len+1];&lt;br /&gt;    for ( var i in nextO) { f.prototype[i]=nextO[i]; }&lt;br /&gt;  }&lt;br /&gt;  return new f();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;You like? Here is some testing code:&lt;pre class=&quot;code&quot;&gt;  // setup the objects    &lt;br /&gt;  myFruitObj= {a:&#39;apple&#39;, b:&#39;banana&#39;};&lt;br /&gt;  myFruitObj.peel=function(){this.b=&#39;banana peel&#39;;}&lt;br /&gt;  myFruitObj2={c:&#39;carrot&#39;, d:&#39;dill pickle&#39;};&lt;br /&gt;  myFruitObj3={e:&#39;eel&#39;, f:&#39;fish&#39;, time:function(){alert(&#39;lets eat some&#39;+ this.e)} }; &lt;br /&gt;  // example call to our new function in this case &lt;br /&gt;  // existing myFruitObj3 is overridden  &lt;br /&gt;  myFruitObj3=object(myFruitObj,myFruitObj2,myFruitObj3);&lt;br /&gt;&lt;br /&gt;  for ( var i in myFruitObj3) {&lt;br /&gt;    alert(i +&quot; : &quot;+ myFruitObj3[i])    &lt;br /&gt;  }&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115287131389686606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115287131389686606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115287131389686606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115287131389686606'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/quick-and-dirty-multiple-inheritence.html' title='Quick and Dirty Multiple Inheritence in Javascript'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115282931740161069</id><published>2006-07-13T15:52:00.000-06:00</published><updated>2006-07-15T18:41:27.416-06:00</updated><title type='text'>Javascript&#39;s Limitations</title><content type='html'>I&#39;m reminded of a quote from the faq pages at javascript.comp.lang in answer to the quesion: What can be done with Closures? &lt;br /&gt;&quot;Strangely the answer to that appears to be anything and everything. I am told that closures enable ECMAScript to emulate anything, so the limitation is the ability to conceive and implement the emulation. That is a bit esoteric and it is probably better to start with something a little more practical.&quot;-Richard Cornford</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115282931740161069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115282931740161069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115282931740161069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115282931740161069'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/javascripts-limitations.html' title='Javascript&#39;s Limitations'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115281538572147410</id><published>2006-07-13T12:03:00.000-06:00</published><updated>2006-07-28T08:33:54.636-06:00</updated><title type='text'>Almost ajax- Synchronous Javascript Remote Scripting</title><content type='html'>Ok, its time I started to do some &lt;h2 style=&quot;DISPLAY: inline&quot;&gt;Ajax &lt;/h2&gt;( &lt;h2 style=&quot;DISPLAY: inline; FONT-WEIGHT: bold&quot;&gt;Asynchronous JavaScript and XML&lt;/h2&gt;) type stuff. Why? Maybe it&#39;ll help get me a job. There are already so many libraries and good stuff out there, I&#39;m not going to re-invent the wheel. In the next few weeks I&#39;ll look at some good/and/or/popular ajax &#39;suites&#39;. I got my eye on a few obscure ones; I&#39;ll share these after I know what a bit more.&lt;br /&gt;For today though, I needed a cross-domain solution for this app I&#39;m making.&lt;br /&gt;So here it is; its a bit of a hack but it works in the real world. Check the recursion out. Good for one use. Goes something like this:&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;&lt;br /&gt;// the php file which sends a javascript file has function myFunction&lt;br /&gt;// var done is to keep track of setTimeout checks&lt;br /&gt;doIt=function(){&lt;br /&gt; this.done=0; &lt;br /&gt; var s=document.createElement(&quot;script&quot;);&lt;br /&gt; s.src=&quot;http://www.XX.com/js.php&quot;;&lt;br /&gt; s.type=&#39;text/javascript&#39;; s.id=&#39;loadScript&#39;;&lt;br /&gt; document.body.appendChild(s);s=null;&lt;br /&gt; doIt=function(){&lt;br /&gt;   this.done++; //alert(&quot;this.done = &quot; + this.done);&lt;br /&gt;   if (this.done&gt;15){return;} // number of setTimeout trys before forgetting it&lt;br /&gt;   if (functionFromJs.php){ &lt;br /&gt;     alert(&#39;All Good&#39;);&lt;br /&gt;     //do stuff&lt;br /&gt;   }&lt;br /&gt;   else {setTimeout(&#39;doIt()&#39;,333);}&lt;br /&gt; }&lt;br /&gt; setTimeout(&#39;doIt()&#39;,333);&lt;br /&gt;}&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115281538572147410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115281538572147410' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115281538572147410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115281538572147410'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/almost-ajax-synchronous-javascript.html' title='Almost ajax- Synchronous Javascript Remote Scripting'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115257175287026385</id><published>2006-07-10T16:48:00.000-06:00</published><updated>2006-07-28T08:35:11.673-06:00</updated><title type='text'>Changing scope with With</title><content type='html'>&lt;pre class=&#39;code&#39;&gt;/* create a global variable - y - that refers to an object:- */&lt;br /&gt;var y = {x:5}; // object literal with an - x - property&lt;br /&gt;function exampleFuncWith(){&lt;br /&gt;    var z;&lt;br /&gt;    /* Add the object referred to by the global variable - y - to the&lt;br /&gt;       front of he scope chain:-&lt;br /&gt;    */&lt;br /&gt;    with(y){&lt;br /&gt;        /* evaluate a function expression to create a function object&lt;br /&gt;           and assign a reference to that function object to the local&lt;br /&gt;           variable - z - :-&lt;br /&gt;        */&lt;br /&gt;        z = function(){alert(x);&lt;br /&gt;    //alert(this);&lt;br /&gt;            //... // inner function expression body;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   return z;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* execute the - exampleFuncWith - function:- */&lt;br /&gt;exampleFuncWith()();&lt;br /&gt;alert(x);&lt;/pre&gt;&quot;When the exampleFuncWith function is called the resulting execution context has a scope chain consisting of its Activation object followed by the global object. The execution of the with statement adds the object referred to by the global variable y to the front of that scope chain during the evaluation of the function expression. The function object created by the evaluation of the function expression is assigned a [[scope]] property that corresponds with the scope of the execution context in which it is created. A scope chain consisting of object y followed by the Activation object from the execution context of the outer function call, followed by the global object. &lt;br /&gt;&lt;br /&gt;When the block statement associated with the with statement terminates the scope of the execution context is restored (the y object is removed), but the function object has been created at that point and its [[scope]] property assigned a reference to a scope chain with the y object at its head.&quot;-Richard Cornford. March 2004</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115257175287026385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115257175287026385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115257175287026385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115257175287026385'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/changing-scope-with-with.html' title='Changing scope with With'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115241786344252646</id><published>2006-07-08T20:48:00.000-06:00</published><updated>2006-07-31T00:34:20.610-06:00</updated><title type='text'>My Dad is Paralyzed</title><content type='html'>July/08/06&lt;br /&gt;Yesterday, Friday, my dad, a well-known &lt;a href=&quot;http://www.dickmaloney.ca/&quot;&gt;local entertainer&lt;/a&gt; and celebrity, was going to lunch. (He had his usual weekend gig that night and just completed his weekly radio show) Going to lunch, he slipped on the sidewalk on a beautiful summer day, fell, and bonked his head. Later, at 3:00pm he lay in the emergency ward, paralyzed from the neck down. Today, Saturday, we await the outcome of an 8 hour surgery. The best we can hope for they say is that he will breathe on his own. Before his surgery, he mouthed &#39;will I ever sing again?&#39;. Need I say more my friends...&lt;br /&gt;Update: July/11/06 Surgery went &#39;fine&#39; and &#39;No&#39;.&lt;br /&gt;Update: July/31/06&lt;br /&gt;Today my dad was moved from I.C.U. to Trauma, meaning he can breathe on his own now without a ventilator. He still has O2 going into a trachiotomy. Still paralyzed, no change there. Prognosis for speech, OK; for singing???&lt;br /&gt;Is my dad mad at God? &#39;No, he has a plan&#39;.&lt;br /&gt;Another quote &#39;This will make me a better person&#39;.&lt;br /&gt;Oh, and he&#39;s planning a comeback, Nov.11/2007 8:00p.m., live on stage, Centerpoint theatre.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115241786344252646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115241786344252646'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/my-dad-is-paralyzed.html' title='My Dad is Paralyzed'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115228142226113449</id><published>2006-07-07T08:07:00.000-06:00</published><updated>2006-07-07T16:58:03.646-06:00</updated><title type='text'>~ js ramblings ~</title><content type='html'>&quot;You can pass a this parameter to setTimeout or setInterval, but it requires a helper function&quot;:&lt;pre class=&quot;code&quot;&gt;setInterval(function (t) { animate.call(t); }, 50, this);&lt;/pre&gt;&quot;Notice that the first arg is a function reference, not a string. This may not be well-known, but in combination with Function.prototype.call (or .apply) and extra trailing args to setInterval (or setTimeout), it does the job.&quot;-Brendan Eich&lt;br /&gt;&lt;br /&gt;&quot;Use a closure to fix the setInterval problem&quot; -Guido Wesdorp :&lt;pre class=&quot;code&quot;&gt;animateEl = function(el){&lt;br /&gt;  var _this = this;&lt;br /&gt;  this.animate = function(){&lt;br /&gt;  setInterval(_this.animate(), 50)&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&quot;There&#39;s another way to call an object&#39;s member function in a setInterval or setTimeout call. You have to create a bind() member on the Function object&#39;s prototype first:&lt;pre class=&quot;code&quot;&gt;Function.prototype.bind = function( object )&lt;br /&gt;{&lt;br /&gt;  var method = this;&lt;br /&gt;  return function()&lt;br /&gt;  {&lt;br /&gt;    method.apply( object );&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;Then you can &#39;bind&#39; a member function to a setTimeout call like this (assuming your object has a method named foo)&quot;-Tom Trenka:&lt;pre class=&quot;code&quot;&gt;setTimeout( this.foo.bind( this ), 50 );&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115228142226113449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115228142226113449' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115228142226113449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115228142226113449'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/js-ramblings.html' title='~ js ramblings ~'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115224248315413563</id><published>2006-07-06T21:17:00.000-06:00</published><updated>2006-07-27T16:04:26.400-06:00</updated><title type='text'>Doug Crockford&#39;s function object(o)</title><content type='html'>&lt;pre class=&quot;code&quot;&gt;//taken from: http://www.crockford.com/&lt;br /&gt;function object(o) {&lt;br /&gt;  function f() {}&lt;br /&gt;  f.prototype = o;&lt;br /&gt;  return new f();&lt;br /&gt;}&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115224248315413563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115224248315413563' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115224248315413563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115224248315413563'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/doug-crockfords-function-objecto.html' title='Doug Crockford&#39;s function object(o)'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30307970.post-115223055521573596</id><published>2006-07-06T17:51:00.000-06:00</published><updated>2006-07-08T12:15:32.203-06:00</updated><title type='text'>Javascript Closures for Dummies</title><content type='html'>&lt;a href=&quot;http://photos1.blogger.com/blogger/5137/3248/1600/fordummies.0.jpg&quot;&gt;&lt;img style=&quot;FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand&quot; alt=&quot;&quot; src=&quot;http://photos1.blogger.com/blogger/5137/3248/320/fordummies.0.jpg&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Here is a great article by Morris Johns:&lt;br /&gt;&lt;br /&gt;&lt;p align=&quot;left&quot;&gt;&lt;a href=&quot;http://blog.morrisjohns.com/javascript_closures_for_dummies&quot;&gt;Javascript Closures for Dummies&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;Some of John&#39;s points:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Whenever you use &lt;span class=&quot;codeSpan&quot;&gt;function&lt;/span&gt; inside another function, a closure is used.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Whenever you use &lt;span class=&quot;codeSpan&quot;&gt;eval()&lt;/span&gt; inside a function, a closure is used. The text you eval can reference local variables of the function, and within eval you can even create new local variables by using &lt;span class=&quot;codeSpan&quot;&gt;eval(&#39;var foo = &lt;/span&gt;…&lt;/li&gt;&lt;br /&gt;&lt;li&gt;When you use &lt;span class=&quot;codeSpan&quot;&gt;Function()&lt;/span&gt; inside a function, it does not create a closure. (The new function cannot reference the local variables of the function calling &lt;span class=&quot;codeSpan&quot;&gt;Function()&lt;/span&gt;).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A closure in JavaScript is like keeping a copy of the all the local variables, just as they were when a function exited.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It is probably best to think that a closure is always created just on entry to a function, and the local variables are added to that closure.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A new set of local variables is kept every time a function with a closure is called (Given that the function contains a function declaration inside it, and a reference to that inside function is either returned or an external reference is kept for it in some way).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Two functions might look like they have the same source text, but have completely different behaviour because of their &#39;hidden&#39; closure. I don&#39;t think JavaScript code can actually find out if a function reference has a closure or not.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you are trying to do any dynamic source code modifications ( for example: &lt;span class=&quot;codeSpan&quot;&gt;myFunction = Function(myFunction.toString().replace(/Hello/,&#39;Hola&#39;));&lt;/span&gt; ), it won&#39;t work if myFunction is a closure (Of course, you would never even think of doing source code string substitution at runtime, but...).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It is possible to get function declarations within function declarations within functions - and you can get closures at more than one level.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I think normally a closure is the term for both the function along with the variables that are captured. Note that I do not use that definition in this article!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I suspect that closures in JavaScript differ from those normally found in functional languages.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Heres some good stuff on stopping IE memory leaks,(I wonder if IE7 will fix most of them, not to worry &#39;bout it though; if your building a big app or lots of closures and dom stuff, heres some ways to stop them: &lt;pre class=&quot;code&quot;&gt;if (window.document.all) window.onunload= ... ;) &lt;/pre&gt;Simon Willison explains: &quot;Closures make it easy to create a memory leak without meaning to. Consider this:&lt;pre class=&quot;code&quot;&gt;function addHandler() {&lt;br /&gt;    var el = document.getElementById(&#39;el&#39;);&lt;br /&gt;    el.onclick = function() {&lt;br /&gt;        this.style.backgroundColor = &#39;red&#39;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;The above code sets up the element to turn red when it is clicked. It also creates a memory leak. Why? Because the reference to el is inadvertently caught in the closure created for the anonymous inner function. This creates a circular reference between a JavaScript object (the function) and a native object (el). There are a number of workarounds for this problem. The simplest is this:&lt;pre class=&quot;code&quot;&gt;function addHandler() {&lt;br /&gt;    var el = document.getElementById(&#39;el&#39;);&lt;br /&gt;    el.onclick = function() {&lt;br /&gt;        this.style.backgroundColor = &#39;red&#39;;&lt;br /&gt;    }&lt;br /&gt;    el = null;&lt;br /&gt;}&lt;/pre&gt; This works by breaking the circular reference. Surprisingly, one trick for breaking circular references introduced by a closure is to add another closure:&lt;pre class=&quot;code&quot;&gt;function addHandler() {&lt;br /&gt;    var clickHandler = function() {&lt;br /&gt;        this.style.backgroundColor = &#39;red&#39;;&lt;br /&gt;    }&lt;br /&gt;    (function() {&lt;br /&gt;        var el = document.getElementById(&#39;el&#39;);&lt;br /&gt;        el.onclick = clickHandler;&lt;br /&gt;    })();&lt;br /&gt;}&lt;/pre&gt;The inner function is executed straight away, and hides its contents from the closure created with clickHandler.&quot;&lt;a href=&quot;http://developer.mozilla.org/en/docs/A_re-introduction_to_JavaScript&quot;&gt;-©2006 A ReIntroduction to Javascript&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://richard-m.blogspot.com/feeds/115223055521573596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=30307970&amp;postID=115223055521573596' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115223055521573596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30307970/posts/default/115223055521573596'/><link rel='alternate' type='text/html' href='http://richard-m.blogspot.com/2006/07/javascript-closures-for-dummies.html' title='Javascript Closures for Dummies'/><author><name>Anonymous</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/blank.gif'/></author><thr:total>4</thr:total></entry></feed>