March 14, 2018
Looking for job!
I'm a full-stack developer looking for remote job opportunities, checkout out my one-minute presentation to know more: http://ivanca.work/html5/Your+Startup.html
November 22, 2012
Fast development of pretty HTML design with CSS3 "opening" effect.
So I created a little service (v.1.0) in Node.JS where you can get categorized but random images for your HTML designs called PlaceAnything; lets create something cool with it and a little bit of CSS3. Check out the final result if you want.
Now the CSS that includes the prefixes for Firefox and Webkit browsers.
Take care.
for( var i = 0; i < 30 ; i++){ $('<a href="#"></a>') .append('<div class="data">'+i+'</div>') .append('<div class="top"><img></div>') .append('<div class="bottom"><img></div>') .appendTo("#container") .find('img') .attr('src','http://placeanything.com/AlbumArtPorn/200/200/?r='+i); }Don't get exited, AlbumArtPorn is just a collection by Reddit users of album art.
Now the CSS that includes the prefixes for Firefox and Webkit browsers.
body{ background:black; } #container img, #container a { padding:0; margin:0; border:0; width:200px; height:200px; } #container a { -webkit-perspective:200px; -moz-perspective:200px; perspective:200px; float:left; border:1px solid black; } .bottom, .top { -webkit-transition: -webkit-transform 0.5s; -moz-transition: -moz-transform 0.5s; transition: transform 0.5s; } .bottom { -webkit-transform-origin: right bottom; -moz-transform-origin: right bottom; transform-origin: right bottom; } .top{ -webkit-transform-origin: left top; -moz-transform-origin: left top; transform-origin: left top; } #container .top, #container .bottom { height: 100px; overflow: hidden; } #container .bottom img{ margin-top: -100px; } #container a:hover .bottom { -webkit-transform: rotateX( 117deg ); -moz-transform: rotateX( 117deg ); transform: rotateX( 117deg ); } #container a:hover .top { -webkit-transform: rotateX( -117deg ); -moz-transform: rotateX( -117deg ); transform: rotateX( -117deg ); } .data { position:absolute; width:100%; height:100%; max-width:200px; max-height:200px; line-height: 197px; color:#CCC; font-family: Verdana, Tahoma, serif; font-size:10px; text-align:center; background-image: url(http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/blackorchid.png); opacity:0; -webkit-transition:opacity 0.5s linear; -moz-transition:opacity 0.5s linear; transition:opacity 0.5s linear; z-index:-1; } #container a:hover .data { opacity:1; }This is just an example but for the sake of good practices lets add a fallback for browsers who don't support 3D CSS transformations (remember that IE9 does not support 3D transformations).
if( typeof document.body.style["-webkit-transform"] === "undefined" && typeof document.body.style["MozTransform"] === "undefined" && typeof document.body.style["transform"] === "undefined"){ $("#container a").on("mouseenter mouseleave",function(event){ var action = ( event.type === "mouseenter" ? "hide" : "show" ); $(this).find("img")[action](); }); }Don't forget to check out PlaceAnything; very useful for random but on-topic HTML placeholders.
Take care.
May 4, 2012
Sharing prototypes in JS
jQuery is certainly awesome, but thanks to modern browsers and the prototypical nature of Javascript we can have many of its features just by interchanging methods from different prototypes.
Just to cheer you up after that disappointment lets implement the find method on arrays, similar to the one jQuery uses.
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;And now we can chain the forEach method after anything that returns a NodeList (or HTMLCollection in IE9) object.
document.getElementsByClassName("links").forEach(function(node){ console.dir(node) })
document.querySelectorAll(".menu").forEach(function(node){ console.dir(node) })And many others work as well:
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filterBut there are some methods that do not work the way you may expect:
NodeList.prototype.pop = Array.prototype.pop var collection = document.querySelectorAll(".example") console.log( collection.length ) // 13 collection.pop() console.log( collection.length ) // 13But there is a way to avoid this problem and similar ones: instead of directly using the Array prototype we explicitly convert it to an array with a simple method.
NodeList.prototype.toArray = function(){ return Array.prototype.slice.call(this) } document.getElementsByTagName("a").toArray()Yeah, is not as sexy but it works a lot better and nobody will have to guess if it returns a NodeList or an Array.
Just to cheer you up after that disappointment lets implement the find method on arrays, similar to the one jQuery uses.
Array.prototype.find = function(selector){ var matches = []; var each = Array.prototype.forEach; each.call(this,function(ele){ if(ele.querySelectorAll){ each.call(ele.querySelectorAll(selector),function(ele){ if(matches.indexOf(ele) === -1){ matches.push(ele) } }) } }) return matches; }Now we can do cool stuff, like:
[document].find(".related a").map(function(ele){ // your awesome code })
March 21, 2012
Zero nested callbacks
function init(){; //init code some.event(function callback1(){; // callback 1 code other.event(function callback2(){; // callback 2 code another.event(function callback3(){; // callback 3 code }) }) }) }Instead of a lots of nested callbacks or creating a lot of named functions in your javascript (for node.js or browsers) you can use something like this:
function fullProcess(){ this._step = ++this._step || 0; switch(this._step){ case 0: // init code some.event(fullProcess) break; case 1: // callback 1 code other.event(fullProcess) break; case 2: // callback 2 code another.event(fullProcess) break; case 3: // callback 3 code break; } }Be aware that the "this" keyword is referring to the global object and not the function.
January 13, 2012
Add class for each Internet Explorer Version
Edit: Now supports IE10!
There is a little code snippet to detect the current version of IE (or if its not IE at all):
var ie = (function(){ var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i'); do { div.innerHTML = ''; } while(all[0]); /*@cc_on;if(v<5)v=10;@*/ return v > 4 ? v : undef ; }());Its pretty useful; and if you want to have dynamic class names for each IE version, just do this after the initial <body> tag (with jQuery):
if(ie){$('body').addClass("ie"+ie)}Or in plain Javascript:
if(ie){document.body.className += " ie"+ie}Now you can easily apply CSS rules for those ugly browsers:
.ie8 #menu, ie7 #menu{ position:absolute; } .ie6 #top{ display:none; }You get the idea.
November 11, 2011
SetInterval With Context
When i started experimenting with the "OOP" structures that one could use in Javascript, there was something that always annoyed me; the timeOuts and setIntervals think that the context is the global object (window) instead of the current object; so the 'this' keyword points to the global object.
Yeah, yeah... i have read all about why it does that... the thing is... i don't care why it does that! I just want it to work!
The good news is that it haves multiple work-arounds but the one i find the best is this simple function:
Now i can call this new function and have an in-context setInterval, awesomeness!
And because the function returns the ID of the interval, you can save it in a variable and clear the interval anywhere you want (including inside the callback itself)
In other news:
The graphic tool for my little project "CreativeTextBoxes" is now available:
More info at: http://creativetextboxes.com/
Graphic tool at: http://creativetextboxes.com/graphic_tool.php
function hero(){ this.speed = 0 this.getFaster = function(){ this.control = setTimeout(function(){ console.log(++this.speed) // returns NaN },1000) } } var superman = new hero(); superman.getFaster()
Yeah, yeah... i have read all about why it does that... the thing is... i don't care why it does that! I just want it to work!
The good news is that it haves multiple work-arounds but the one i find the best is this simple function:
setIntervalWithContext = function(code,delay,context){ return setInterval(function(){ code.call(context) },delay) } setTimeoutWithContext = function(code,delay,context){ return setTimeout(function(){ code.call(context) },delay) }
Now i can call this new function and have an in-context setInterval, awesomeness!
function hero(){ this.speed = 0 this.getFaster = function(){ this.interval = setIntervalWithContext(function(){ console.log(this.speed++) // Run Forest! RUN!!! },100,this) } } var flash = new hero(); flash.getFaster()
And because the function returns the ID of the interval, you can save it in a variable and clear the interval anywhere you want (including inside the callback itself)
this.interval = setIntervalWithContext(function(){ if(this.speed++ > 100){ clearInterval(this.interval) } },100,this)
In other news:
The graphic tool for my little project "CreativeTextBoxes" is now available:
More info at: http://creativetextboxes.com/
Graphic tool at: http://creativetextboxes.com/graphic_tool.php
September 10, 2011
jQuery CSS3 Rotate (and animate Rotation)
This is for browsers with CSS3 support only! That means Chrome 1+, Firefox 3.5+ and IE9+.
Just put this somewhere after jQuery:
And then if you want to rotate an object:
And if you want animation:
BTW if you want to check if an old browser didn't rotate the object; you can do something like this:
Just put this somewhere after jQuery:
(function($){ var _e = document.createElement("canvas").width $.fn.cssrotate = function(d) { return this.css({ '-moz-transform':'rotate('+d+'deg)', '-webkit-transform':'rotate('+d+'deg)', '-o-transform':'rotate('+d+'deg)', '-ms-transform':'rotate('+d+'deg)' }).prop("rotate", _e ? d : null) }; var $_fx_step_default = $.fx.step._default; $.fx.step._default = function (fx) { if(fx.prop != "rotate")return $_fx_step_default(fx); if(typeof fx.elem.rotate == "undefined")fx.start = fx.elem.rotate = 0; $(fx.elem).cssrotate(fx.now) }; })(jQuery);
And then if you want to rotate an object:
$("div").cssrotate(95) // value in degrees
And if you want animation:
$("div").animate({rotate:95},{duration:1000})
BTW if you want to check if an old browser didn't rotate the object; you can do something like this:
if($("div").prop("rotate")==null){ // Fallback }
August 17, 2011
Revolution in Web Design - Creative Text Boxes
Jaja ok it many not be a revolution, but its a pretty neat; check out some examples like a guitar or a triangle.
The illusion of irregular shape text boxes: Now you can give any shape you want to your HTML text container. The effect is accomplished only with empty floating <span> tags so it doesn't hurt SEO or anything like that.
This script works on IE8,IE9, Firefox and Chrome; it also works on IE7 but not as well as in the others browsers... and i couldn't care less for IE6 so don't ask for support on that browser!
Some example of how to use it:
And actually i created a website just for this script: CreativeTextBoxes.com; there you can find the documentation, a little video tutorial and a couple of tools that helps you get the shapes you want.
If after reading the documentation you have questions about how to use it post them here in this post entry; if you have questions/comments about how the script works internally please do so on Github. The code is minified on the website but it is uncompressed and commented in github.
Hope you like it.
The illusion of irregular shape text boxes: Now you can give any shape you want to your HTML text container. The effect is accomplished only with empty floating <span> tags so it doesn't hurt SEO or anything like that.
This script works on IE8,IE9, Firefox and Chrome; it also works on IE7 but not as well as in the others browsers... and i couldn't care less for IE6 so don't ask for support on that browser!
Some example of how to use it:
CreativeTextBox({ text: document.getElementById("text"), leftSizes: [410, 456, 487, 507, 520, 524, 525, 518, 506, 485, 454, 407, 328], pixelDistance:40 });
And actually i created a website just for this script: CreativeTextBoxes.com; there you can find the documentation, a little video tutorial and a couple of tools that helps you get the shapes you want.
If after reading the documentation you have questions about how to use it post them here in this post entry; if you have questions/comments about how the script works internally please do so on Github. The code is minified on the website but it is uncompressed and commented in github.
Hope you like it.
July 26, 2011
Dont Reload jQuery on your Iframes
So, you may have some pages (in the same domain) that always are going to be loaded as iframes. But if you have jQuery loaded in the parent document and you want to use it INSIDE the iframe (a script tag inside) you just have to do this:
But that is only if you are not going to use document.ready or any of its shortcuts. If you want to use any of those there is a workaround (Note: The iframe needs to have an id)
So now you can write jQuery like it was loaded naturally inside the iframe (using the dollar sign)
var $ = function(a,b){ b = b || document; return parent.jQuery.apply(this,[a,b]) };
But that is only if you are not going to use document.ready or any of its shortcuts. If you want to use any of those there is a workaround (Note: The iframe needs to have an id)
var $ = function(a,b){ var that = this; b = b || document; function ready(a){ parent.jQuery("#"+window.frameElement.id).load(function(){a.call(that)}) } if(typeof a == "function"){ ready(a) } else { var r = parent.jQuery.apply(this,[a,b]); r.ready = ready; return r } };
So now you can write jQuery like it was loaded naturally inside the iframe (using the dollar sign)
July 24, 2011
Faster than jQuery(document).ready() - Wait Until Exists
Update: This script no longer works and shounln't be used, this post remains here for historical purposes
Well, lets be honest; 99% of the time you are waiting for ONE <div> (or other HTML element) to exists to do some javascript; not the entire document.
So i created a javascript function called waitUntilExists and it basically does what its name says it does, it waits until one HTML element exists.
So how does it work?
And that is it; you can put any code inside of it...
But guess what? Is also faster if you are waiting for all the <body> to load
This is faster:
Than this:
Well, but i got to be honest to you, is not faster on old versions of Internet Explorer (IE8 and all the crap before), but in any other browser it is faster.
But this thing can do stuff that $(document).ready() cannot do; it is called waitUntilExists for a reason... it will wait until the div exists no matter if it takes one milisecond or ten hours to come into existence. This can be handy for ajax and stuff like that, because you don't need callbacks, the function is executed once if the div comes into existence.
Lets check some other nice little features, there is a third paramater that is optional for the context; for example:
So, in that third parameter you may want to write the keyword this.
Another nice little feature is the ability to use the HTML element as the context, you just have to write "itself" in the third parameter.
Another nice little feature is to be able to remove one "listener"; so if you want to stop waiting for an HTML element to exist:
You can also put the function as the second parameter if you need to be specific.
Oh yeah... you can find the code here: http://pastebin.com/raw.php?i=XTDKbQvK
Well, lets be honest; 99% of the time you are waiting for ONE <div> (or other HTML element) to exists to do some javascript; not the entire document.
So i created a javascript function called waitUntilExists and it basically does what its name says it does, it waits until one HTML element exists.
So how does it work?
waitUntilExists("id_of_the_div",function(){ // Div exists, do whatever you want with it now })
And that is it; you can put any code inside of it...
But guess what? Is also faster if you are waiting for all the <body> to load
This is faster:
waitUntilExists(document,function(){ // Page finished loading })
Than this:
jQuery(document).ready(function(){ // Page finished loading })
Well, but i got to be honest to you, is not faster on old versions of Internet Explorer (IE8 and all the crap before), but in any other browser it is faster.
But this thing can do stuff that $(document).ready() cannot do; it is called waitUntilExists for a reason... it will wait until the div exists no matter if it takes one milisecond or ten hours to come into existence. This can be handy for ajax and stuff like that, because you don't need callbacks, the function is executed once if the div comes into existence.
Lets check some other nice little features, there is a third paramater that is optional for the context; for example:
var obj = {} obj.value = 123 obj.a = function(){ waitUntilExists(document, function(){alert(this.value)},this) } obj.a() // outputs 123
So, in that third parameter you may want to write the keyword this.
Another nice little feature is the ability to use the HTML element as the context, you just have to write "itself" in the third parameter.
waitUntilExists("content",function(){ this.style.background = "red" },"itself")
Another nice little feature is to be able to remove one "listener"; so if you want to stop waiting for an HTML element to exist:
waitUntilExists.stop("id_of_div")
You can also put the function as the second parameter if you need to be specific.
The dark secret!
The code is in few words... just a wrapper of functions for a DOMNodeInserted event listener... yep, that is pretty much all about it. In old IE versions it becomes a wrapper for one setInterval.Oh yeah... you can find the code here: http://pastebin.com/raw.php?i=XTDKbQvK
July 22, 2011
Be a god among internet users
EDIT: Bug fixed, now also works in firefox.
So many times i inject jQuery on a site to do something inside it. Here is a bookmarklet i use a lot: View it on pastebin; so basically why it does is inject jQuery (if is not already on the page) and take care about $.noConflict and all that jazz.
Drag this to your bookmarks: jQuery with prompt (or just click it to test it)
But it also brings a nice prompt in which to write the javascript code (eval is NOT evil!); and it also have some little nice features, you can open the prompt with Shift+J or by clicking the bookmarklet again. It remembers the last code you wrote on it. It also haves a handy function called print, it basically works as a wrapper for document.write javascript function. It also handle any errors in your syntax and you can use the function "$" instead of "jQuery" without breaking anything in the current web site.
So, lets see what this baby can do:
If you need to get the list of you are listening in Grooveshark, you could write this:
If you need to select all your friends in Facebook when you create an event...
If you need to get all URL addresses from a Google search
To archive all your facebook messages (well, just current page)
Everyone loves to scrapp; so lets do that (ab)using Ajax! This code gets all links of the first 9 pages of a Google search result.
So many times i inject jQuery on a site to do something inside it. Here is a bookmarklet i use a lot: View it on pastebin; so basically why it does is inject jQuery (if is not already on the page) and take care about $.noConflict and all that jazz.
Drag this to your bookmarks: jQuery with prompt (or just click it to test it)
But it also brings a nice prompt in which to write the javascript code (eval is NOT evil!); and it also have some little nice features, you can open the prompt with Shift+J or by clicking the bookmarklet again. It remembers the last code you wrote on it. It also haves a handy function called print, it basically works as a wrapper for document.write javascript function. It also handle any errors in your syntax and you can use the function "$" instead of "jQuery" without breaking anything in the current web site.
So, lets see what this baby can do:
If you need to get the list of you are listening in Grooveshark, you could write this:
$(".songName").each(function(){print($(this).html())})
If you need to select all your friends in Facebook when you create an event...
$(".checkbox").click()
If you need to get all URL addresses from a Google search
$("cite").each(function(){print(this.innerHTML)})
To archive all your facebook messages (well, just current page)
$("#MessagingDashboard .archiveLink input").click();
Scrapping FUN!
Everyone loves to scrapp; so lets do that (ab)using Ajax! This code gets all links of the first 9 pages of a Google search result.
window.arrxx=[];$("#navcnt .fl").each(function(i){var opq = i;var that=this;setTimeout(function(){ $.get(that.href,function(data){ $("<div"+">").html(data).find("cite").each(function(){arrxx.push("http://"+$(this).text()) });if(opq == $("#navcnt .fl").length - 1){document.write("<pre"+">"+arrxx.join("\n")+"</p"+"re>")}})},1000*(i+1))});
July 19, 2011
jQuery weird mouseenter and mouseleave events
So jQuery is all-mighty but like any god is full of flaws... one of them is with the event.type when you are using "mouseenter" or "mouseleave",
This works fines:
But in this other case the alert never gets executed
That is because when the variable event is called inside a setTimeout (or setInterval) it returns "mouseover" instead of "mouseenter" as it should.
So just save the actual event type and you will be just fine.
This works fines:
$("body").bind("mouseenter",function(event){ if(event.type == "mouseenter"){ alert("OK") } })
But in this other case the alert never gets executed
$("body").bind("mouseenter",function(event){ setTimeout(function(){ if(event.type == "mouseenter"){ alert("OK") } }) })
That is because when the variable event is called inside a setTimeout (or setInterval) it returns "mouseover" instead of "mouseenter" as it should.
So just save the actual event type and you will be just fine.
$("body").bind("mouseenter",function(event){ var eventType = event.type setTimeout(function(){ if(eventType == "mouseenter"){ alert("Mouse inside... i can feel it inside of me!") } }) })
July 18, 2011
HTML Comments are diamonds
So everyone thinks that html comments are lame... well... they are NOT! They can be extremely useful! In fact...
- What?
- What did you do that was so "ta-da"?
- Well, using jQuery i just converted all the comments content into actual HTML, so if someone had <!-- <h1>Haters gonna hate</h1> --> it will transform into actual HTML!
- And why would i want to do that?
- You know that comments don't get read by the Google Search bot, right?
- Yeah....
- Well, ajax is cool and all that... but is always faster if the content is already on the current page
- Yeah...
- Mmmm... do i need to make you a drawing or something dude?
- F*ck you.
I know some of you are lame as sh*t and don't love the all-mighty jQuery javascript library so here it is the same code in 100% pure cross-browser javascript (IE7+, Chrome, Firefox):
$("*").contents().filter(function() { return this.nodeType == 8;}) .after(function(){return this.data})- Ta-da
- What?
- What did you do that was so "ta-da"?
- Well, using jQuery i just converted all the comments content into actual HTML, so if someone had <!-- <h1>Haters gonna hate</h1> --> it will transform into actual HTML!
- And why would i want to do that?
- You know that comments don't get read by the Google Search bot, right?
- Yeah....
- Well, ajax is cool and all that... but is always faster if the content is already on the current page
- Yeah...
- Mmmm... do i need to make you a drawing or something dude?
- F*ck you.
I know some of you are lame as sh*t and don't love the all-mighty jQuery javascript library so here it is the same code in 100% pure cross-browser javascript (IE7+, Chrome, Firefox):
function find_comments(selection) { selection = selection || document comments_found=[]; loop(selection.childNodes) function loop(arr) { for(var i = 0; i<arr.length;i++) { if(arr[i].nodeType == 8) { comments_found.push(arr[i]) }else{ loop(arr[i].childNodes) } } } return comments_found; } var comments = find_comments(document) for(var i=0;i<comments.length;i++){ var one_comment = comments[i] var div = document.createElement("div"); div.innerHTML = one_comment.data for(var j=0;j<div.childNodes.length;j++){ one_comment.parentNode.insertBefore(div.childNodes[0],one_comment) } }
Subscribe to:
Posts (Atom)