want 8 spaces?
(new Array(8)).join(' ')
it's quick not only as in fewer keystrokes/less code, but is also blazingly fast to execute compared to a for-loop implementation.
Everything pertaining to the presentation layer, but focusing on javascript and css
want 8 spaces?
(new Array(8)).join(' ')
it's quick not only as in fewer keystrokes/less code, but is also blazingly fast to execute compared to a for-loop implementation.
Fireworks' export wizard seems to be plagued by filesize bugs. I thought they squashed them in CS3, but CS4 seems to have re-introduced or made a new one: it reports an exported file's size as Kilobytes = bytes/1000 instead of bytes/1024.
I just exported a file, noting that FW tells me it will be 754K, when in fact, it is 737K (754,807 bytes).
/* order matters! */
.carousel a:hover .playbutton{background:transparent url(/css/i/x.gif);filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/css/i/icons/playbutton_thumb_hover.png", sizingMethod="crop");}
.carousel .playbutton{background:transparent url(/css/i/x.gif);filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/css/i/icons/playbutton_thumb_normal.png", sizingMethod="crop");}
a:hover .playbutton{background:transparent url(/css/i/x.gif);filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/css/i/icons/playbutton_hover.png", sizingMethod="crop");}
.playbutton{background:transparent url(/css/i/x.gif);filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/css/i/icons/playbutton_normal.png", sizingMethod="crop");}
//will break if element.on[event] is modified directly elsewhere
//will break if the markup itself contains inline event listener functions ( <element onevent="function body"> )
//is incompatible with prototype library (Prototype library should not be used for ANY project.)
// using EVENT namespace ... could be different if needed, could possibly be Element.prototype ... could possibly be a jQuery extension/plugin (or incorporated into jQuery core?)
EVENT = {};
EVENT.elements = [];
EVENT.addListener = function(el, type, f, prepend){
if(!el.eventListenerList){
el.eventListenerList = [];
}
if(!el.eventListenerList[type]){
el.eventListenerList[type] = [];
}
if(prepend){
el.eventListenerList[type].splice(0,0,f);
} else {
el.eventListenerList[type].push(f);
}
if(!el['on'+type]){
el['on'+type] = function(e){
for(var i in el.eventListenerList[type]){
el.eventListenerList[type][i](e);
}
};
}
};
EVENT.removeListener = function(el, f){
if(!el.eventListenerList){
return;
}
//note: "var i in obj" is incompatible with icky prototype library
var list = el.eventListenerList;
for(var i in list){
for(var j in list[i]){
if( list[i][j] == f ){
//remove it.
el.eventListenerList[i].splice(j,1);
return;
}
}
}
};
EVENT.hasListener = function(el, f){
if(!el.eventListenerList){
return false;
}
//note: "var i in obj" is incompatible with icky prototype library
var list = el.eventListenerList;
for(var i in list){
for(var j in list[i]){
if( list[i][j] == f ){
return true;
}
}
}
return false;
};
Found out last night that safari has a bug in its svg implementation (ok, probably lost most of you right there “who cares about svg?” … but there’s a possibility that this could be useful for flash/actionscript too)
Turns out that if you rotate an ellipse, the getBBox method returns a rather generous bounding box, because it’s using an implicit rectangle wrapped around the ellipse to get the bounding box.
You can see below what the browser bug is and what the correct box is. The red—buggy—implementation is created by the browser basing its calculations on the blue (implicit) rectangle that surrounds the ellipse.
The correct result is the box in green.
I created a javascript workaround for this bug.
It uses calculus. This is the first time I’ve used calculus in programming something that didn’t exist solely to demonstrate calculus.
I first tried to find a solution posted somewhere on the net, but only found a post where someone says it’s solved in the latest version, then reverses himself and says, ‘oh, no, actually it’s firefox that fixed its version of the same bug.’
If someone happens to find the bug # or a posted solution, that’d be cool.
// Trig functions (Math shortcut aliases)
var sin = Math.sin,
cos = Math.cos,
tan = Math.tan,
cot = function(a){return 1/tan(a);},
sqrt= Math.sqrt,
acos= Math.acos,
// our instance of an ellipse .. will become something more like this._shape (if this.type == ELLIPSE)
ellipse = $('e').getElementsByTagName('ellipse')[0],
// the properties of our instance of an ellipse
a = ellipse.getAttribute('rx')*1, //x-radius (major, minor, who knows)
b = ellipse.getAttribute('ry')*1, //y-radius (major, minor, who cares)
cx = ellipse.getAttribute('cx')*1, //center's x-coord .. not currently used (assume the ellipse is centered at the origin)
cy = ellipse.getAttribute('cy')*1, //center's y-coord .. not currently used (assume the ellipse is centered at the origin)
matrix = ellipse.getCTM(), //the transform matrix
angle = acos( matrix.a ),
// the x coordinates where the ROTATED xmax and ymax occur on the ellipse BEFORE ROTATION.
// these "magical" formulas represent the recombined derivative of the ellipse function
x1 = (-1*(a*a)*tan(angle)) / sqrt(a*a*tan(angle)*tan(angle) + (b*b)),
x2 = ( (a*a)*cot(angle)) / sqrt(a*a*cot(angle)*cot(angle) + (b*b)),
// the actual xmax and ymax, reflecting the above, rotated into position (AFTER ROTATION).
xmax = (cos(angle) * x2) + (sin(angle) * f(x2)),
// (using negative-angle because positive screen y-axis is the same as 'normal maths' negative y-axis)
ymax = (sin(-angle) * x1) + (cos(-angle) * f(x1));
///
// the f(x) that defines the ellipse (in general form)
function f(x){
return b * Math.sqrt(1-((x*x)/(a*a)));
};
//~ console.log(ellipse.getAttribute('transform'));
//~ log(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
// browser's idea of where the bbox is... (red box)
var box = ellipse.parentNode.getBBox();
re = $("re");
re.setAttribute("x", box.x);
re.setAttribute("y", box.y);
re.setAttribute("width", box.width);
re.setAttribute("height", box.height);
re.setAttribute("stroke", "red");
// my idea of where the bbox is... (green box)
re = $("re2");
re.setAttribute("x", -Math.abs(xmax));
re.setAttribute("y", -Math.abs(ymax));
re.setAttribute("width", Math.abs(xmax)*2);
re.setAttribute("height", Math.abs(ymax)*2);
re.setAttribute("stroke","#090");
Debug in production?! .. when you have to .. you can target a strange userAgent string .. such as "Quality Assurance Browser" .. that you set yourself with some tool that allows you to set your userAgent.
/** debug **/
console.dir( myObj );
/**/
$ java -jar yuicompressor-2.5.2.jar -rmdebug script.js -o script-min.js
;; console.dir( myObj ); //double-semicolon prefix indicates this line is for debugging
if (data.image.length) {
// Group of images
for (var i = 0; i < data.image.length; i++) {
debug("Image " + data.image[i].imageUrl + ": " + data.image[i].statusText);
}
}
else {
// Just a single image
debug("Image " + data.image.imageUrl + ": " + data.image.statusText);
}
but it can be expressed more succinctly as:
if (!data.image.length) data.image = [data.image];
// Group of images
for (var i = 0; i < data.image.length; i++) {
debug("Image " + data.image[i].imageUrl + ": " + data.image[i].statusText);
}
var xmlString = "<root><a/><b>data1</b><b>data2</b></root>";
function xmlString2json (xmlString) {
return xmlString.replace(
//expand empty tags
/\<([^>]*)\/\>/g, "<$1></$1>"
).replace(
//convert closing tags to closing braces
/\<\/([^>]*)\>/g,"},"
).replace(
//convert opening tags to "{NODENAME:["
//notice that the array literal is opened, but not closed.
/\<([^>]*)\>/g,"{'$1':["
).replace(
//remove extraneous commas
/,}/g,"]}"
).replace(
//close array literal, begin adding needed singlequotes
/:([^{}]*?)}/g,":'$1]'}"
).replace(
//adjust singlequotes, bring inside array literal notation (left side)
/'\[/g,"['"
).replace(
//adjust singlequotes, bring inside array literal notation (right side)
/\]'/g,"']"
).replace(
//remove empty strings (which are from empty tags)
/\[''\]/g,"[]"
).replace(
//remove final, ending extraneous comma
/},$/, '}'
);
}
var json = xmlString2json(xmlString);
// {'root':[{'a':[]},{'b':['data1']},{'b':['data2']}]}
function cleanTree(r, p){
if(r.length == 1 && typeof r[0] == "string"){
//might want to trim leading and trailing whitespace from r[0] first
// could be expressed as a series of ternary operations:
// return r[0]=="true"?true:r[0]=="false"?false:r[0].search(/^[0-9]+$/)==0?1*r[0]:r[0]
// expressed this way for readability:
if(r[0] == "true"){
return true;
}
if(r[0] == "false"){
return false;
}
if(r[0].search(/^[0-9]+$/) == 0){
return 1*r[0];
}
return r[0];
}
p = p || {};
for( i in r ){
var nn = '';
for( name in r[i] ){
nn = name;
}
var subnode = r[i][nn];
if(p[nn]){
if(typeof p[nn] == "object" && typeof p[nn].length == "number"){
p[nn].push( cleanTree(subnode) );
} else {
p[nn] = [ p[nn], cleanTree(subnode) ];
}
} else {
p[nn] = cleanTree(subnode);
}
}
return p;
}
var jso = eval('('+json+')');
var cleaned = cleanTree(jso.testImages);
console.log(cleaned);
var xmlString = (new XMLSerializer()).serializeToString( myXMLDoc );
Someone else's related post (reminder to self to see if his xml2json will work in actionscript / how readily adaptable it is): converting xml to json.
var s=['prototype.yc','lightbox','dsn'];
while(s.length) document.write('<scr'+'ipt src="/js/'+s.shift()+'.js"></scr'+'ipt>');
/ home home home /mainsection mainsection home > mainsection <html class="mainsection"> /mainsection/subsection mainsection > subsection home > mainsection > subsection <html class="mainsection"><body class="subsection"> /mainsection/subsection/leaf mainsection > subsection > leaf home > mainsection > subsection > leaf <html class="mainsection"><body class="subsection"><div id="siteContainer" class="leaf">
for( var i = 0; i < len; i++){
var el = elements[i];
el.addListener('click', function(){clicked(i);}, false);
}
(function loop( I ){
if (I == len) return;
var i = I;
var el = elements[i];
el.addListener('click', function(){clicked(i);}, false);
loop(++I);
})(0);
Note: addListener is not any browser’s implementation. It’s just my way of saying addEventListener (or, for IE, attachEvent). Also, for brevity, the function ‘clicked’ is not here defined. Yes, this is documented in a couple places around the web. But those places are not obvious or easily searchable for everyone.
if(condition){
stuff
}
This won't work for all cases, but I often enjoy writing it like this:
if(!condition) return;
stuff
Note: if you are NOT minifying your code, the bottom method is probably leaner, but if you ARE minifying, stick with the top method.
function SomeClass(args){
...
}
SomeClass.prototype.firstMethod = function(args){ ... };
SomeClass.prototype.secondMethod = function(args){ ... };
SomeClass.prototype.thirdMethod = function(args){ ... };
...
...
function SomeClass(args){};
SomeClass.prototype = new (function(args){
var me = this;
me.firstMethod = function(args){ ... };
me.secondMethod = function(args){ ... };
me.thirdMethod = function(args){ ... };
...
})();
/* to test it, we'll create an instance and check if it has it's own [copy of] firstMethod */
var myClass = new SomeClass(args);
alert(myClass.hasOwnProperty('firstMethod'));
/* false, it does not have a local copy of the method */