jQuery DOM creation tips

I want to share a neat little trick with jQuery DOM creation.

I often see jQuery scripts create DOM elements like this:

var $elem = $('<div>' + text + '</div>');
// OR
var $elem = $("<div>").addClass('some-class').text("text content");

There is nothing wrong with the above methods, but you can actually pass in an object to extend the element being created like so:


var $elem = $('<div/>', {
    "class" : "some-class",
    "attr" : "value",
    "text" : "text content", // equivalent to .text()
    "html" : "<h3>title</h3>", // equivalent to .html()
    "click" : function() { } // click event
});

Using this method, you can create an DOM using a predefined object and stay away from nasty string concatenations.

ARRRRGH… How do I get all the errors created by jquery .validate()

Ahhh yes… So you just validated your awesome form and want to grab all the awesome errors for some awesome reason.

Just add a sprinkling of:

var validator = $("#awesomeForm").validate();
var errors = validator.errorList;

This will give you a list of awesome validator error objects that includes the error message and the actual awesome jquery element object.

You’re welcome 🙂

(I used “awesome” quite a bit)

jQuery tutorial TL;DR

This is just a simple jquery tutorial, more of a reference guide for common jQuery methods and features. For complete documentation visit http://api.jquery.com/

A jQuery object contains a collection of DOM elements that have been created from an HTML string or selected from a document. The jQuery object itself behaves much like an array it has a length property and the elements in the object can be accessed by their numeric indices [0] to [length-1]

extend the jQuery fn prototype to create a custom function or plugin

jQuery.fn.customFunction = function (n) {
// custom function
}

get a jQuery object from an iframe to get a list of attached events

jQuery.data(document, 'events');

get element by id using jQuery

var element = $('#section')[0];

The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.

$( "div" ).promise().done(function() {
$( "p" ).append( " Finished! " );
});

chaining is possible because every setter method in jQuery returns the selection on which it was called.

var $elem = $( 'li' ).children('li').first().next();

delete a cookie

$.cookie("name", $(this).val(), { path: '/', expires: -1 });
$.cookie("name", $("cookie-value"), { path: '/', expires: -1 });
$.cookie("name", null);

effects in jQuery

$.cookie("name", $(this).val(), { path: '/', expires: -1 });
$.cookie("name", $("cookie-value"), { path: '/', expires: -1 });
$.cookie("name", null);

effects in jQuery

// .animate()
.animate({ fontSize: "24px" }, 1500 )
// .delay()
$("div.second").slideUp(300).fadeIn(400);
// .fadeIn ()
.fadeOut() $("span").fadeIn(300);
// .hide()
$("p").hide("slow");
// .show()
$("div").show("fast");
// .stop()
$(".block").animate({left: '+=100px'}, 2000);
$(".block").stop();
// .toggle()
$("p").toggle();

retrieve json data using ajax

// jQuery.ajax()
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});
// .ajaxSuccess() / .ajaxError() / .ajaxComplete()
$("#msg").ajaxSuccess(function(evt, request, settings){
$(this).append("Successful Request!");
});

dom selectors

// *
// selects all elements.
var elementCount = $("*").length;
// .
// selects all elements with the given class.
$(".myclass.otherclass")
// #
// selects a single element with the given id attribute.
$("#myDiv")
// :animated
// select all elements that are in the progress of an animation at the time the selector is run.
$("div:animated")
// :button
// Selects all button elements and elements of type button
$(":button")
// :checkbox
// selects all elements of type checkbox.
$("form input:checkbox")
// :checked
// matches all elements that are checked.
$("input:checked")
// :contains()
// select all elements that contain the specified text.
$("div:contains('Steven')")
// :disabled
// selects all elements that are disabled.
$("input:disabled")
// :empty
// select all elements that have no children (including text nodes).
$("td:empty")
// :enabled
// selects all elements that are enabled.
$("input:enabled")
// :eq()
// select the element at index n within the matched set.
$("td:eq(2)")
// :even :odd
// selects even / odd elements, zero-indexed.
$("tr:even")
// :file
// selects all elements of type file.
$("input:file")
// :first-child
// selects all elements that are the first child of their parent.
$("div span:first-child")
// :first / :last
// selects the first / last matched element.
$("tr:first")
// :focus
// selects element if it is currently focused.
elem.toggleClass( "focused", elem.is(":focus") );
// :has()
// selects elements which contain at least one element that matches the specified selector.
$("div:has(p)")
// :hidden :visible
// selects all elements that are hidden / visible.
$("div:hidden")
// :image
// selects all elements of type image.
$("input:image")
// :input
// selects all input, textarea, select and button elements.
$(":input");
// :text
// selects all elements of type text. $("form input:text")
// :not()
// selects all elements that do not match the given selector. $("input:not(:checked)")
// :password
// selects all elements of type password.
$("input:password")
// :parent
// select all elements that are the parent of another element, including text nodes.
$("td:parent")
// :radio
// selects all elements of type radio.
$("form input:radio")
// :reset
// selects all elements of type reset.
$("input:reset")
// :selected
// selects all elements that are selected.
$("select option:selected")
// :submit
// selects all elements of type submit.
$(":submit")

changing styles in jQuery

// .addClass
$("p").addClass("selected");
// .css()
var color = $(this).css("background-color");
$(this).css("color","red");
// .hasClass
$('#mydiv').hasClass('foo')
// .removeClass
$("p").removeClass("blue");
// .toggleClass
$("p").click( function () {
$(this).toggleClass("highlight");
});

traversing the dom in jQuery

// .add()
$("p").add("Again") $("p").add("span").css("background", "yellow");
// .children()
$("div").children()
// .closest()
var x = $("div").closest("li");
// .contents()
$("p").contents()
// .each()
$("li").each(function(){
$(this).toggleClass("example");
});
// .end()
$("p").showTags(0) .find("span") .css("background", "yellow") .end() .css("font-style", "italic");
// .eq()
$("body").find("div").eq(2).addClass("blue");
// .find()
var $allListElements = $('li');
$('li.item-ii').find($allListElements);
// .first()
$('li').first().css('background-color', 'red');
// .has()
$('li').has('ul').css('background-color', 'red');
// .is()
if ($(this).is(":first-child")) {
// execute code
}
// .last()
$('li').last().css('background-color', 'red')
// .map()
$(':checkbox').map(function() {
return this.id;
}).get();
// .next() / .prev()
$('li.third-item').next().css('background-color', 'red');
// .nextAll()
// begin at the third item, we can find the elements which come after it
$('li.third-item').nextAll().css('background-color', 'red');
// .nextUntil()
$("#term2").nextUntil("term6") .css("background-color", "red");
// .parent()
$('li.item-a').parent().css('background-color', 'red');
// .parents()
// begin at item a, we can find its ancestors:
$('li.item-a').parents().css('background-color', 'red');
// .siblings()
$('li.third-item').siblings().css('background-color', 'red');
// .slice()
$('li').slice(2).css('background-color', 'red');

dom manipulation in jQuery

// .after() / .before()
$("p").after("Hello");
// .append() / .prepend()
$("p").append("Hello");
// .appendTo() / .prependTo()
$("span").appendTo("#foo");
// .attr var title = $("em").attr("title");
// .clone()
$("b").clone().prependTo("p");
// .detach()
$("p").detach();
// .empty()
$("p").empty();
// .height() / .width()
$(this).height(30)
// .html
$("div").html("Wow...");
// .insertAfter() / .insertBefore()
$("p").insertAfter("#foo");
// .offset()
$("p:last").offset({ top: 10, left: 30 });
// .position()
var position = $("p").position();
// .prop
$("input[type='checkbox']").prop({ disabled: true });
// .remove()
$("p").remove();
// .text()
var str = $("p:first").text();
// .val()
var value = $(this).val();
// .data()
// data-id="abc"/data-value="somthing"
var value = $(this).data("value"), id=  $(this).data("id");
// .wrap()
$("p").wrap(" ");

binding to events in jQuery

// .bind()
// attach a handler to an event for the elements.
$('#foo').bind('click', function() {
alert('User clicked on "foo."');
});
// .unbind()
// remove a previously-attached event handler from the elements.
$('#foo').unbind();
// .change()
// bind an event handler to the "change" javaScript event, or trigger that event on an element.
$('.target').change(function() {
alert('Handler for .change() called.');
});
// .click() / .dblclick
// bind an event handler to the "click" javaScript event, or trigger that event on an element.
$("#target").click(function() {
alert("Handler for .click() called.");
});
// .delegate()
// attach a handler to one or more events for all elements that match the selector, now or in the future
$("table").delegate("td", "click", function() {
$(this).toggleClass("chosen");
});
// .die()
// remove all event handlers previously attached using .live() from the elements.
$("p").die( "click")
// .error()
// bind an event handler to the "error" JavaScript event.
$("img") .error(function(){
$(this).hide();
})
// .focus()
// bind an event handler to the "focus" javaScript event, or trigger that event on an element.
$('#target').focus(function() {
alert('Handler for .focus() called.');
});
// .hover() $(function () {
$("#mapping").hover( function () {
$(this).addClass("hover");
}, function () {
$(this).removeClass("hover");
} );
});
// .keyup() / .keypress() / .keydown()
$('#target').keyup(function() {
alert('Handler for .keyup() called.');
});
// .mouseover() mousedown() ...
// trigger a mouseover event.
$('#outer').mouseover();
// .on()
// attach an event handler function for one or more events to the selected elements.
$("#dataTable").on("click", function(event){
alert($(this).text());
});
// .off()
// remove an event handler.
$("p").off( "click", "**" )
// .ready()
// specify a function to execute when the DOM is fully loaded.
$(document).ready(function() {
// Handler for .ready() called.
});
// .resize()
// bind an event handler to the "resize" javaScript event, or trigger that event on an element.
$(window).resize(function() {
$('#log').append('Handler for .resize() called. ');
});
// .scroll()
// trigger a scroll $('#target').scroll();
// .select()
// bind an event handler to the "select" javaScript event, or trigger that event on an element.
$('#target').select(function() {
alert('Handler for .select() called.');
});
// .submit()
// bind an event handler to the "submit" javaScript event, or trigger that event on an element.
$('#target').submit(function() {
alert('Handler for .submit() called.');
return false;
});
// .toggle()
// bind two or more handlers to the matched elements, to be executed on alternate clicks.
$('#target').toggle(function() {
alert('First handler for .toggle() called.');
}, function() {
alert('Second handler for .toggle() called.');
});
// .trigger()
$(document).ready(function(){
$('#some-id').trigger('click');
});

The best css evar

* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

W3C really screwed up the box model. This will make your webs better. (It doesn’t work in IE7, but why are you still supporting it anyway?)

Side note, IE6 is border-box by default. IE7 changed it to follow W3C standards eventually. Perhaps one of those times IE got it right. They’re quite the hipster it appears. 😉

I wouldn’t say W3C screwed up. IE6 was using border-box and switched to content-box eventually in IE7. The other browsers were all using content-box back then and W3C standards embraced content-box. When IE7 came along, they flipped to content-box, but it doesn’t provide a box-sizing CSS property which became essential 5 years later (IE7 is released in 2006). As Paul mentioned, it does seem more intuitive to have it border-box after all. It is hard for W3C to envision this is going to be the way people prefer things so many years ago too; I’m just glad there’s a box-sizing attribute to give more options to developers.

Javascript Array push Object by reference

Let’s have a look at what is happening:

var abc = { a: 10, b: 20};

A new object is created in memory and assigned to the variable abc.

var def = [];

A new array is created in memory and assigned to the variable def.

def.push(abc);

Inside the array there is now a pointer to the formerly created object.

abc.a = 100;
def[0].a; // outputs 100!

Obviously right. We are modifying the object, which is also referenced by the array.

abc = { a: 10000, b: 20000 };

Again a new object is created and a reference to it is stored in abc. Now we have two objects (and an array) in memory.

def[0].a; // still 100, no change this time

Of course, this is still 100. The array pointer still references the first created object and not the second one.

online PDF viewing

There are many security concern about PDFs, there’s malware, malicious code that contaminated the file and some other security issues. to tackle those issues, use google docs viewer.

<a href="https://docs.google.com/viewer?url=[url-to-pdf-file]" title="View PDF " target="_blank">View PDF Online</a>

I think it’s much safer than opening the file on your local computer.

Do I Need a CSS Reset?

Lately I’ve been getting quite a few emails asking me if they should include a CSS reset stylesheet in their projects. Basically each time I answer these emails, my response is always yes. Not everyone thinks it is necessary to include a reset stylesheet, but I find it can’t hurt by including one. So people will say that it will slow your site down as there is more code to use, but with the speed of the internet these days, that argument is not really valid any more.

In all of the projects I do, I will always include a CSS reset, for the main reason that it will reduce the inconsistencies in the variety of different browsers that people use. Some of the quirks in different browsers are: line heights, margins, paddings and font sizes for headings, by including a reset stylesheet you are reducing the chances of the webpages displaying differently in each browser, unfortunately even using a CSS reset, you will still get inconstancies between the most popuplar browsers.

Currently there are five popular choices with CSS reset, they are:

  • Eric Meyer’s ‘Reset CSS’ v2.0
  • Yahoo! (YUI 3) Reset CSS
  • HTML5 Doctor CSS Reset
  • Universal Selector ’*’ Reset
  • Normalize.css 1.0

From the list above, the most popular one would be Eric Meyer’s CSS Reset, but I would recommend that you experiment with the different files to find the one that suits your web layouts the best. All of the reset stylesheets have been released in the public domain, which means you are free to use them for both personal and commercial work.

Eric Meyer’s ‘Reset CSS’ v2.0

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}

Yahoo! (YUI 3) Reset CSS

html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea,select{*font-size:100%}legend{color:#000}#yui3-css-stamp.cssreset{display:none}

HTML5 Doctor CSS Reset

html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}nav ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent}ins{background-color:#ff9;color:#000;text-decoration:none}mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold}del{text-decoration:line-through}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}table{border-collapse:collapse;border-spacing:0}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}input,select{vertical-align:middle}

Universal Selector ’*’ Reset

*{margin:0;padding:0;}

Normalize.css 1.0

article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.75em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:75%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}

CSS Resets are nice, but the thing I dislike about them is that they kill margins on elements that really should have them.

One of my intentions is to, at some point change the CSS reset I use so the elements still behave in the default manner, but also in a standardized manner on all web browsers. I like my paragraphs having margins, and my bullets working like bullets. CSS Resets usually break these, I plan to simply standardize them. There are other things, but those are just two off the top of my head.

It’s often better to tame the beast rather than kill it.