JavaScript/Notes/ParameterObject: Difference between revisions

From Noisebridge
Jump to navigation Jump to search
Garrett (talk | contribs)
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 3: Line 3:
The DOM event methods for creating events are an example of what not to do. My [http://lists.w3.org/Archives/Public/www-dom/2010OctDec/0188.html comments on w3c DOM mailing list] led to the current Event constructor.  
The DOM event methods for creating events are an example of what not to do. My [http://lists.w3.org/Archives/Public/www-dom/2010OctDec/0188.html comments on w3c DOM mailing list] led to the current Event constructor.  


 
=== Refactoring ===
Method <code>initTouchEvent</code> (Apple) takes 18 parameter variables.  
Method <code>initTouchEvent</code> (Apple) takes 18 parameter variables. It is hard to remember the order and type of each and every variable.
<source lang="javascript">
<source lang="javascript">
// Note: This code is iOS specific!
var touchEvent, canceled;
var touchEvent, canceled;


touchEvent = doc.createEvent("TouchEvent");
touchEvent = document.createEvent("TouchEvent");
if (typeof touchEvent.initTouchEvent == "function") {
if (typeof touchEvent.initTouchEvent == "function") {
   touchEvent.initTouchEvent(type, bubbles, cancelable, view,
   touchEvent.initTouchEvent(type, bubbles, cancelable, view,
Line 19: Line 20:
}
}
</source>
</source>
18 parameter variables is too many. It would be much easier can pass in an object that has named property values, and give some defaults for missing property values, such as "rotation".
 
=== Pass an Object ===
It would be much easier can pass in an object that has named property values, and give some defaults for missing property values, such as <code>rotation</code>.


Like this:
Like this:
Line 27: Line 30:
Where <code>options</code> has a corresponding property for each argument for a single touch event.
Where <code>options</code> has a corresponding property for each argument for a single touch event.


<source lang="javascript">
touchstart : function(target, options) {
  return fireTouchEvent("touchstart", target, options);
}
</source>
<source lang="javascript">
function fireTouchEvent(type, target, options){
    var c = getTouchEventData(target, options),
    doc = target.ownerDocument || target.document || target;
    //setup default values.
    if (!doc || !doc.createTouch) {
        throw TypeError("simulateTouchEvent(): Invalid target.");
    }
    return simulateTouchEvent(doc,
            target, type, c.bubbles, c.cancelable, c.view,
            c.detail, // Not sure what this does in "touch" event.
            c.screenX, c.screenY, c.pageX, c.pageY,
            c.ctrlKey, c.altKey, c.shiftKey, c.metaKey,
            c.touches, c.targetTouches, c.changedTouches, c.scale, c.rotation);
}
</source>


== Defaults ==  
== Defaults ==  

Latest revision as of 19:56, 25 April 2014

Passing around lists of parameters? Typechecking arguments? Stop doing that. Here's how to make your code clearer and less error-prone.

The DOM event methods for creating events are an example of what not to do. My comments on w3c DOM mailing list led to the current Event constructor.

Refactoring

[edit | edit source]

Method initTouchEvent (Apple) takes 18 parameter variables. It is hard to remember the order and type of each and every variable. <source lang="javascript"> // Note: This code is iOS specific! var touchEvent, canceled;

touchEvent = document.createEvent("TouchEvent"); if (typeof touchEvent.initTouchEvent == "function") {

 touchEvent.initTouchEvent(type, bubbles, cancelable, view,
 detail, screenX, screenY, pageX, pageY, ctrlKey,
 altKey, shiftKey, metaKey, touches, targetTouches,
 changedTouches, scale, rotation);
   // fire the event
 canceled = target.dispatchEvent(touchEvent);

} </source>

Pass an Object

[edit | edit source]

It would be much easier can pass in an object that has named property values, and give some defaults for missing property values, such as rotation.

Like this: <source lang="javascript"> Action.touchstart( document.body, {clientX: 330, clientY: 330} ); </source> Where options has a corresponding property for each argument for a single touch event.

<source lang="javascript"> touchstart : function(target, options) {

 return fireTouchEvent("touchstart", target, options);

} </source> <source lang="javascript"> function fireTouchEvent(type, target, options){

   var c = getTouchEventData(target, options),
   doc = target.ownerDocument || target.document || target;
   //setup default values.
   if (!doc || !doc.createTouch) {
       throw TypeError("simulateTouchEvent(): Invalid target.");
   }
   return simulateTouchEvent(doc,
           target, type, c.bubbles, c.cancelable, c.view,
           c.detail, // Not sure what this does in "touch" event.
           c.screenX, c.screenY, c.pageX, c.pageY,
           c.ctrlKey, c.altKey, c.shiftKey, c.metaKey,
           c.touches, c.targetTouches, c.changedTouches, c.scale, c.rotation);

} </source>

Defaults

[edit | edit source]

<source lang="javascript"> function getTouchEventData(target, options) {

 options = options || {};
 var doc = target.ownerDocument || target.document || target;
 return {
   target        : target,
   bubbles       : ("bubbles" in options) ? !!options.bubbles : true,
   cancelable    : ("cancelable" in options) ? !!options.cancelable : true,
   view          : options.view||doc.defaultView,
   detail        : +options.detail||1, // Not sure what this does in "touch" event.
   screenX       : +options.screenX||0,
   screenY       : +options.screenY||0,
   pageX         : +options.pageX||0,
   pageY         : +options.pageY||0,
   ctrlKey       : ("ctrlKey" in options) ? !!options.ctrlKey : false,
   altKey        :  ("altKey" in options) ? !!options.altKey : false,
   shiftKey      : ("shiftKey" in options) ? !!options.shiftKey : false,
   metaKey       : ("metaKey" in options) ? !!options.metaKey : false,
   scale         : +options.scale||1,
   rotation      : +options.rotation||0,
   touches       : createTouchList(options.touches||options),
   targetTouches : createTouchList(options.targetTouches||options),
   changedTouches: createTouchList(options.changedTouches||options)
 };

}</source> See also Too Many Parameters.