DOM Manipulation jQuery
// WAYS TO SELECT DIFFERENT DOM ELEMENTS
// SELECT A TAG
$("p")
$("span")
$("h1")
// SELECT An ID
$("#my_id")
// SELECT A CLASS
$(".navigation")
$("p.b") // select all <p> tags that have class "b"
// FILTERS
// :first and :last
$( "tr:first" ) // select the first <tr> tag found
$( "tr:last" ) // select the last <tr> tag found
// :eq &.eq()
// select an element at a specified index from a list of matched elements
/*
eq - Reduce the set of matched elements to the one at the specified index
Providing a negative number indicates a position starting from the end of the set,
rather than the beginning.
$( "li" ).eq( -2 ) selects the second last element
:eq vs .eq
They do the same thing, but one is significantly slower
:eq() is not a CSS pseudo-selector, which makes the first selector a jQuery selector.
Therefore, it has to be parsed by the Sizzle selector library, which is written in JavaScript.
The second one is a regular CSS selector and will be passed directly into document.querySelectorAll,
which is implemented natively and will end up running much faster.
*/
$( "li" ).eq( 2 ) // find the 3rd <li> element
$("li:eq(2)") // find the 3rd <li> element
// :even & :odd
$("p:even") // select all <p> tags with even index in the array
// :gt()
$("p:gt(1)") // return <p> tags, with index greater than 1 in the array
// :lt()
$("p:lt(5)") // return <p> tags, with index less than 5 in the array
// :focus
// :animated
// :not(expr)
$("p:not(p:eq(2))") // select all <p> tags except the one with index 2
// ADVANCE FILTERS
//attribute filter
$("p[class]") // look for <p> tags that have a 'class' attribute (we don't care about value here)
$("p[data=para1]") // look for <p> tags that have 'data' attribute with value 'para1'
$("p[data^=para]") // look for <p> tags that have 'data' attribute & value starts with 'para'
// look for <p> tags that have 'data' attribute that starts with 'para'
// and lang attribute that contains text 'en-'
$("p[data^=para][lang*=en-]")
// CONTENT FILTERS - filtering by examination of the actual content of the elements
$("p:contains('hello')") // select <p> tags that contains text 'hello'
$("p:parent") // select <p> tags that are Parents i.e. have at least one child
// child can be even a text node
$("div:has(p[data=hello])")
// select <div> tag that have at leas one <p> tag with attribute 'data' with value 'hello'
// CHILD FILTERS
$("div p:first-child") // select <p> tags that are first child of <div>
// While :first matches only a single element,
// the :first-child selector can match more than one: one for each parent.
$("div p:last-of-type") // select <p> tags that are last of its type in <div>
$("div p:nth-child(3)") // select <p> tags that 3rd child of <div> (1 based index)
$("div p:nth-child(2n)") // select <p> child (every 2nd) of <div>
// PARENT CHILD selectors
$("div > p") // select <p> tag only if it is an immediate descendant(child) of <div> tag
$("div p") // 'space' is called a 'descendant' selector, it returns all <p> tags that are descendant
// of <div>, not just immediate children of <div>
$("ul + div") // select all <div> as long as it is next/prev to <ul>
// '+' is called next adjacent selector (prev + next)
$("#id ~ p") // next sibling selector
// select all sibling <p> tags that come after "id" element
// TRAVERSING DOM
// .next()
// .prev()
// .parent()
// .parents()
// .parentsUntil()
// .children()
// .find()
// .each()
// CREATE NEW CONTENT
var newElement = $("<span> hello world </span>"); // creates a <span> tag & saves it into a variable
$("#para1").html(newElement);
/* method: html()
Get the HTML contents of the first element in the set of matched elements or set the HTML contents
of every matched element
This method uses the browser's innerHTML property.
*/
$("p").html();
$("p").html("Hello <b>world</b>!");
$("div").html("<p> Hello World </p>"); // created a <p> tag & replaced the <div> contents with it
/* method: text()
Get the combined text contents of each element in the set of matched elements,
including their descendants ((HTML markup will be removed)),
or set the text contents of the matched elements.
The .text() method cannot be used on form inputs or scripts.
To set or get the text value of input or textarea elements, use the .val() method.
To get the value of a script element, use the .html() method.
*/
$( "p" ).text()
$("p").text("Hello world!");
/* method: $(document).ready()
a function to execute when the DOM is fully loaded.
While JavaScript provides the load event for executing code when a page is rendered,
this event does not get triggered until all assets such as images have been completely received.
In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed.
The handler passed to .ready() is guaranteed to be executed after the DOM is ready,
so this is usually the best place to attach all other event handlers and run other jQuery code.
In cases where code relies on loaded assets (for example, if the dimensions of an image are required),
the code should be placed in a handler for the load event instead
All three of the following syntaxes are equivalent:
$( document ).ready( handler )
$().ready( handler ) (this is not recommended)
$( handler )
*/
$( document ).ready(function() {
console.log( "ready!" );
});
// INSERT CONTENT
/* method: append()
Insert content, specified by the parameter, to the end of each element in the set of matched elements
The .append() method inserts the specified content as the last child of each element in the jQuery
collection
To insert it as the first child, use .prepend().
*/
$("p").append("<b>Appended text</b>");
//You can create content and insert it into several elements at once:
$( ".inner" ).append( "<p>Test</p>" );
// You can also select an element on the page and insert it into another:
$( ".container" ).append( $( "h2" ) );
/*
If an element selected this way is inserted into a single location elsewhere in the DOM,
it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned:
If there is more than one target element, however, cloned copies of the inserted element
will be created for each target except the last,
and that new set (the original element plus clones) is returned.
This applies to appendTo method as well.
*/
// comparison of code written by append() in jQuery with JavaScript
//jQuery
$("document").ready(function() {
$("body").append("<p>The page just loaded!</p>");
});
//JavaScript
window.addEventListener("DOMContentLoaded", function(evt) {
var elem = document.getElementsByTagName("body")[0];
var para = document.createElement("p");
var text = document.createTextNode("The page just loaded!");
para.appendChild(text);
elem.appendChild(para);
});
// you can see how easy it is to write jQuery code comparing with JavaScript
/* method: appendTo()
The .append() and .appendTo() methods perform the same task.
The major difference is in the syntax-specifically, in the placement of the content and target.
With .append(), the selector expression preceding the method is the container into
which the content is inserted.
With .appendTo(), on the other hand, the content precedes the method,
either as a selector expression or as markup created on the fly,
and it is inserted into the target container.
inserts the specified content as the last child of each element
*/
$( "<p>Test</p>" ).appendTo( ".inner" ); // 'Test' paragraph is added to the element with 'inner' class
// We can also select an element on the page and insert it into another:
$( "h2" ).appendTo( $( ".container" ) ); // append h2 to element with class 'container'
// .prepend()
// .before() -- add contents before the specified tag (as siblings, not child)
// .after()
// .insertAfter() // works similar to appendTo() but as siblings
// .insertBefore() // // works similar to prependTo() but as siblings
// ALTERING PAGE CONTENT
// .wrap -- allows you to wrap content around existing content
$("#exam1 p").wrap("<div> </div>"); // <p> tags will be wrapped by a <div>
/*
Note: when dealing with variables ---
jquery .wrap() returns the INNER element back to you, so it looks like nothing changed.
$("<span>").wrap('<div>')
returns ===> [<span></span>]
which looks like it didn't work.
but:
$("<span>").wrap('<div>').parent()
returns ===> [<div></div>]
so, use .parent() to get the outer element
*/
// .wrapAll -- instead of wrapping the individual elements (<p>) with <div>
// we wrap the whole selection with <div>
// .empty() -- empty a container
// .remove() -- removes the element & its contents including any data or attached event handlers
// .detach() -- remove the element from the but maintains the data & event handlers
// so, if the element is reattched in the DOM, it will have its data & event handlers
// .replaceAll() -- content of <p> in #example will be replaced by <div>
$("<div> replaced content </div>").replaceAll("#example p")
// .replaceWith() -- same but different style of writing
("#example p").replaceWith("<div> replaced content </div>");
// you can also pass a callback function in replaceWith instead of static content
// MANIPULATING ATTRIBUTES
// .attr()
$("a").attr("title", "hello world"); // added a title attribute to <a> tags
$("a").attr("title"); // retrieves value of title attribute
$("a").attr("target", "_blank"); // added 'target' attribute to open link in a new tab
$("img").attr({src: "blah.png", title: "blah"}); // dealing with multiple attributes
// .removeAttr()
$("a").removeAttr("href") // removes href attribute
// WORKING WITH CSS
// .css()
// .css(propName) -- return the value of the css property
// .css(propName, value) -- sets the value of the property
// .css(propName, fn()) -- sets the value of the property to output of fn()
// .css(properties) -- set multiple properties with JavaScript object (name value pairs)
// .css(prop1,val1).css(prop2, val2) // chaining also possible but JavaScript object better option
$("p").css("font-size", "+=1") // increase font-size by 1
// .hasClass(className) -- checks if the element has this class
// .addClass(className)
// .removeClass(className)
// .toggleClass(className)
// POSITIONING WITH CSS
// .height()
$("#example").height() // get height
$("#example").height(200) //set height
// .width()
// .innerHeight()
// .innerWidth()
// .outerHeight()
// .outerWidth()
// .offset()
// .offset().top
// .offset().left
// .position()
// .position().top
// .position().left
// note: values can be decimal, and slightly different in different browsers
// EMBEDDING CUSTOM DATA
// .data() -- used to store & retrieve data on an element via data attributes
// .data(key, value) - set data
// .data(obj) -- use javascript object to set data
// .data (key) -- return data for the key
// .data() -- return javascript object containing all data
// <div data-type="veg">
$("div").data("type") // return veg
// .removeData()
$("div").removeData("key2") // removes 'data-key2' attribute
$("div").removeData() // removes all data attributes
/* method: on() & off()
.on( events [, selector ] [, data ], handler )
Attach an event handler function for one or more events to the selected elements
As of jQuery version 1.7, the on() method is the new replacement for the bind(), live() and delegate() methods
To remove event handlers, use the off() method
To attach an event that only runs once and then removes itself, use the one() method
The majority of browser events bubble, or propagate, from the deepest, innermost element (the event target)
in the document where they occur all the way up to the body and the document element.
A handler can prevent the event from bubbling further up the document tree
(and thus prevent handlers on those elements from running) by calling event.stopPropagation()
Similarly, a handler can call event.preventDefault() to cancel any default action that the browser
may have for this event;
for example, the default action on a click event is to follow the link
Returning false from an event handler will automatically call event.stopPropagation()
and event.preventDefault().
A false value can also be passed for the handler as a shorthand for function(){ return false; }.
So, $( "a.disabled" ).on( "click", false ); attaches an event handler to all links with class
"disabled" that prevents them from being followed when they are clicked and also stops the event
from bubbling.
If selector (parameter) is omitted or is null, the event handler is referred to as direct or directly-bound.
The handler is called every time an event occurs on the selected elements,
whether it occurs directly on the element or bubbles from a descendant (inner) element.
When a selector is provided, the event handler is referred to as delegated.
The handler is not called when the event occurs directly on the bound element,
but only for descendants (inner elements) that match the selector.
jQuery bubbles the event from the event target up to the element where the handler is attached
(i.e., innermost to outermost element) and runs the handler for any elements along that path
matching the selector
Delegated events have the advantage that they can process events from descendant elements
that are added to the document at a later time.
In addition to their ability to handle events on descendant elements not yet created,
another advantage of delegated events is their potential for much lower overhead when many elements
must be monitored. On a data table with 1,000 rows in its tbody,
this example attaches a handler to 1,000 elements:
$( "#dataTable tbody tr" ).on( "click", function() {
console.log( $( this ).text() );
});
An event-delegation approach attaches an event handler to only one element, the tbody,
and the event only needs to bubble up one level (from the clicked tr to tbody):
$( "#dataTable tbody" ).on( "click", "tr", function() {
console.log( $( this ).text() );
})
*/
// event delegation and this, event.target, event.currentTarget
// suppose you have a table with ID #all_airports and one <a> tag in each row (100 rows)
// now if we attach event directly to the table (and execute when event bubbles to table)
jQuery("#all_airport").on("click", function(event) {
alert(jQuery(event.target).text()); // text of <a> tag
alert(jQuery(this).text()); // text of #all_airport
alert(jQuery(event.currentTarget).text()); // text of #all_airport
});
// however, if you still use event bubbling but provide <a> tag in the .on method
jQuery("#all_airport").on("click", "a", function(event) {
alert(jQuery(event.target).text()); // text of <a> tag
alert(jQuery(this).text()); // text of <a> tag
alert(jQuery(event.currentTarget).text()); // text of <a> tag
});
// Attach a click event to the <p> element:
$("p").on("click", function(){
alert("The paragraph was clicked.");
});
// Attach a click event and pass a named function
function notify() {
alert( "clicked" );
}
$( "button" ).on( "click", notify );
// Attach multiple events
$("p").on("mouseover mouseout", function(){
$(this).toggleClass("intro");
});
// Pass data to the event handler, which is specified here by name:
function myHandler( event ) {
alert( event.data.foo );
}
$( "p" ).on( "click", { foo: "bar" }, myHandler );
// Cancel a form submit action and prevent the event from bubbling up by returning false:
$( "form" ).on( "submit", false );
// Cancel only the default action by using .preventDefault().
$( "form" ).on( "submit", function( event ) {
event.preventDefault();
});
// Stop submit events from bubbling without preventing form submit, using .stopPropagation().
$( "form" ).on( "submit", function( event ) {
event.stopPropagation();
});
// Attach multiple event handlers simultaneously using a plain object.
$( "div.test" ).on({
click: function() {
$( this ).toggleClass( "active" );
}, mouseenter: function() {
$( this ).addClass( "inside" );
}, mouseleave: function() {
$( this ).removeClass( "inside" );
}
});
// Click any paragraph to add another after it. Note that .on() allows a click event on any paragraph
//--even new ones--since the event is handled by the ever-present body element after it bubbles to there.
var count = 0;
$( "body" ).on( "click", "p", function() {
$( this ).after( "<p>Another paragraph! " + (++count) + "</p>" );
});
// General advice when using .on()
// try to bind the event listener to the most precise element, to avoid useless event handling
// That is, if you're adding an element of class b to an existing element of id a, then don't use
$(document.body).on('click', '#a .b', function(){});
//instead use
$('#a').on('click', '.b', function(){});