jquery data manipulate api - a source code dissecting journey

36
jQuery Data Manipulate http://thefronts.com/ http://deanyan.com/ http://www.linkedin.com/in/deanyan/ Dean Yan A source code dissecting journey

Upload: dean-yan

Post on 10-May-2015

1.622 views

Category:

Technology


0 download

DESCRIPTION

Represent major data manipulate API in jQuery 1.6; such as .data(), removeData(), index(), globalEval() and so no. Also, HTML5 data-* attributes. I will walk you through with diving into jQuery source code and find out the killing techniques used in jQuery.

TRANSCRIPT

Page 1: jQuery Data Manipulate API - A source code dissecting journey

jQuery Data Manipulate

http://thefronts.com/ http://deanyan.com/

http://www.linkedin.com/in/deanyan/

Dean Yan

A source code dissecting journey

Page 2: jQuery Data Manipulate API - A source code dissecting journey

HTML5 data-* Attributes

<li class="user" data-name="John Resig" data-city="Boston"data-lang="js" data-food="Bacon">    <b>John says:</b> <span>Hello, how are you?</span></li>

var user = document.getElementsByTagName("li")[0];var pos = 0, span = user.getElementsByTagName("span")[0];

var phrases = [  {name: "city", prefix: "I am from "},  {name: "food", prefix: "I like to eat "},  {name: "lang", prefix: "I like to program in "}];

user.addEventListener( "click", function(){  var phrase = phrases[ pos++ ];  // Use the .dataset property  span.innerHTML = phrase.prefix + user.dataset[ phrase.name ];}, false);

REF> http://ejohn.org/blog/html-5-data-attributes/

Page 3: jQuery Data Manipulate API - A source code dissecting journey

HTML5 data-* Attributes

span.innerHTML = phrase.prefix +  user.getAttribute("data-" + phrase.name )

The .dataset property behaves very similarly to the the .attributes property (but it only works as a map of key-value pairs)

Page 4: jQuery Data Manipulate API - A source code dissecting journey

HTML5 data-* AttributesWhile I firmly believe that useful data should be made visible to users,

there are circumstances where data-* attributes make sense. For instance, including data-lat and data-lng attributes in an element containing a street address would allow for easily adding markers to a Google Map on the page:

<span

data-lat="38.8951" data-lng="-77.0363">

    1600 Pennsylvania Ave.    Washington, DC

</span>

REF> http://www.viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution/

Page 5: jQuery Data Manipulate API - A source code dissecting journey

HTML5 data-* AttributesTaking a step back, we can use data-* attributes on the body

element to provide an indication of where we are within an application:

<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">

 <body data-controller="users" data-action="show">

The above code will yield something like:

REF> http://www.viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution/

Page 6: jQuery Data Manipulate API - A source code dissecting journey

.data()/jQuery.data()

.data( key, value ).data( key, value ) .data( obj )

.data( key ).data( key ) .data()

Page 7: jQuery Data Manipulate API - A source code dissecting journey

.data()/jQuery.data()<div>    The values stored were     <span></span>    and    <span></span></div>

$("div").data("test", { first: 16, last: "pizza!" });$("span:first").text($("div").data("test").first);$("span:last").text($("div").data("test").last);

<div data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div>

$("div").data("role") === "page";$("div").data("lastValue") === 43;$("div").data("hidden") === true;$("div").data("options").name === "John";

Page 8: jQuery Data Manipulate API - A source code dissecting journey

.data()/jQuery.data()var myObj = {};$(myObj).data("city", "Springfield");

myObj.city = "Springfield"

var progressBar = {};

$(progressBar).bind('setData', function(e, key, value) {    switch (key) {    case "percent":        $("#progress").width(value + "%");        $("#percentText").text(value + "%");        break;

    case "color":        $("#progress").css("color", value);        break;

    case "enabled":        $('#progress').toggleClass("active", value);        break;    }});

$(progressBar).data("enabled", true).data("percent", 21).data("color","green");

// You also have easy access to the current values:console.log(progressBar.enabled); // true

Page 9: jQuery Data Manipulate API - A source code dissecting journey

.data()/jQuery.data()

getData – triggered before data is read from the object.

changeData – triggered whenever data is set or changed. It is used in the jQuery datalink plugin .

Page 10: jQuery Data Manipulate API - A source code dissecting journey

. removeData()/ jQuery.removeData()

.removeData( [ name ] )

<div>value1 before creation: <span></span></div><div>value1 after creation: <span></span></div><div>value1 after removal: <span></span></div>

$("span:eq(0)").text("" + $("div").data("test1"));

$("div").data("test1", "VALUE-1");$("div").data("test2", "VALUE-2");

$("span:eq(1)").text("" + $("div").data("test1"));$("div").removeData("test1");

$("span:eq(2)").text("" + $("div").data("test1"));$("span:eq(3)").text("" + $("div").data("test2"));

Page 11: jQuery Data Manipulate API - A source code dissecting journey

jQuery.hasData()

jQuery.hasData( element )

The primary advantage of jQuery.hasData(element) is that it does not create and associate a data object with the element if none currently exists. In contrast, jQuery.data(element) always returns a data object to the caller, creating one if no data object previously existed.

Page 12: jQuery Data Manipulate API - A source code dissecting journey

jQuery.hasData()

$(function(){  var $p = jQuery("p"), p = $p[0];

  $p.append(jQuery.hasData(p)+" "); /* false */  jQuery.data(p, "testing", 123);

  $p.append(jQuery.hasData(p)+" "); /* true*/  jQuery.removeData(p, "testing");

  $p.append(jQuery.hasData(p)+" "); /* false */});

Page 13: jQuery Data Manipulate API - A source code dissecting journey

Utilities

jQuery.isEmptyObject()

jQuery.trim()

jQuery.isFunction()

jQuery.each()

jQuery.globalEval()

jQuery.merge()jQuery.proxy()

jQuery.extend()

Page 14: jQuery Data Manipulate API - A source code dissecting journey

Utilities

// Populate the class2type mapjQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {    class2type["[object " + name + "]"] =name.toLowerCase();});

type: function(obj) {    return obj == null ? String(obj) :class2type[toString.call(obj)] || "object";},

// See test/unit/core.js for details concerning isFunction.// Since version 1.3, DOM methods and functions like alert// aren't supported. They return false on IE (#2968).isFunction: function(obj) {    return jQuery.type(obj) === "function";},

jQuery.isFunction()

Page 15: jQuery Data Manipulate API - A source code dissecting journey

Utilities

// Use native String.trim function wherever possibletrim: trim ?function(text) {    return text == null ? "" : trim.call(text);} :

// Otherwise use our own trimming functionality

function(text) {    return text == null ? "" :text.toString().replace(trimLeft,"")

.replace(trimRight, "");},

jQuery.trim()

Page 16: jQuery Data Manipulate API - A source code dissecting journey

Utilities

isEmptyObject: function(obj) {    for (var name in obj) {        return false;    }    return true;},

jQuery.isEmptyObject()

Page 17: jQuery Data Manipulate API - A source code dissecting journey

Utilities

isPlainObject: function(obj) {    // Must be an Object.    // Because of IE, we also have to check the presence of the constructor property.    // Make sure that DOM nodes and window objects don't pass through, as well    if (!obj || jQuery.type(obj) !== "object" ||obj.nodeType || jQuery.isWindow(obj)) {        return false;    }

    // Not own constructor property must be Object    if (obj.constructor && !hasOwn.call(obj,"constructor") 

&&!hasOwn.call(obj.constructor.prototype,"isPrototypeOf")) {        return false;    }

    // Own properties are enumerated firstly, so to speed up,    // if last one is own, then all properties are own.    var key;    for (key in obj) {}

    return key === undefined || hasOwn.call(obj,key);},

jQuery.isPlainObject()

Page 18: jQuery Data Manipulate API - A source code dissecting journey

Utilities

globalEval: function(data) {    if (data && rnotwhite.test(data)) {        // We use execScript on Internet Explorer        // We use an anonymous function so that context is window        // rather than jQuery in Firefox        (window.execScript ||        function(data) {            window["eval"].call(window, data);        })(data);    }},

jQuery.globalEval()

Page 19: jQuery Data Manipulate API - A source code dissecting journey

Utilities// Bind a function to a context, optionally partially applying any// arguments.proxy: function(fn, context) {    if (typeof context === "string") {        var tmp = fn[context];        context = fn;        fn = tmp;    }

    // Quick check to determine if target is callable, in the spec    // this throws a TypeError, but we will just return undefined.    if (!jQuery.isFunction(fn)) {        return undefined;    }

    // Simulated bind    var args = slice.call(arguments, 2),        proxy = function() {            return fn.apply(context,args.concat(slice.call(arguments)));        };

    // Set the guid of unique handler to the same of original handler, so it can be removed    proxy.guid = fn.guid = fn.guid || proxy.guid ||jQuery.guid++;

    return proxy;},

jQuery.proxy()

Page 20: jQuery Data Manipulate API - A source code dissecting journey

UtilitiesjQuery.each()

// args is for internal usage onlyeach: function(object, callback, args) {    var name, i = 0,        length = object.length,        isObj = length === undefined || jQuery.isFunction(object);

    if (args) {        if (isObj) {            for (name in object) {                if (callback.apply(object[name], args) === false) {                    break;                }            }        } else {            for (; i < length;) {                if (callback.apply(object[i++], args) === false) {                    break;                }            }        }

Page 21: jQuery Data Manipulate API - A source code dissecting journey

UtilitiesjQuery.each()

      // A special, fast, case for the most common use of each    } else {        if (isObj) {            for (name in object) {                if (callback.call(object[name], name, object[name]) ===false) {                    break;                }            }        } else {            for (; i < length;) {                if (callback.call(object[i], i, object[i++]) === false) {                    break;                }            }        }    }

    return object;},

Page 22: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

.index()

.map()

.get()

.toArray()

.slice()

Page 23: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous.index()

.index( selector )

selector A selector representing a jQuery collection in which to look for an element.

.index( element )

element The DOM element or first element within the jQuery object to look for.

Page 24: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

<span>Click a div!</span><div>First div</div><div>Second div</div><div>Third div</div><script>   

$("div").click(function () {        // this is the dom element clicked

        var index = $("div").index(this);        $("span").text("That was div index #" + index);

    });</script>

.index()

On click, returns the index (based zero) of that div in the page.

Page 25: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

<ul>    <li id="foo">foo</li>    <li id="bar">bar</li>    <li id="baz">baz</li></ul><div></div><script>$('div').html('Index: ' +  $('#bar').index('li') );</script>

.index()

Returns the index for the element with ID bar in relation to all <li> elements.

Page 26: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

toArray: function() {    return slice.call(this, 0);}

Reversed - <span></span>

<div>One</div><div>Two</div><div>Three</div><script>function disp(divs) {    var a = [];    for (var i = 0; i < divs.length; i++) {        a.push(divs[i].innerHTML);    }    $("span").text(a.join(" "));}

disp($("div").toArray().reverse());</script>

toArray()

Page 27: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous.map().map( callback(index, domElement) )callback(index, domElement)A function object that will be invoked for each element in the current set.

Page 28: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

<input type="button" value="equalize div heights">

<div style="background:red; height: 40px; "></div><div style="background:green; height: 70px;"></div><div style="background:blue; height: 50px; "></div>

<script>    $.fn.equalizeHeights = function(){

     return this.height( Math.max.apply(this, $(this).map(function(i,e){ return $(e).height() }).get() ) )    }

    $('input').click(function(){     $('div').equalizeHeights();    });</script>

.map()Equalize the heights of the divs.

Page 29: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

map: function(callback) {    return this.pushStack(jQuery.map(this, function(elem, i) {        return callback.call(elem, i, elem);    }));},

.map()

Page 30: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous// arg is for internal usage onlymap: function(elems, callback, arg) {    var value, key, ret = [],        i = 0,        length = elems.length,        // jquery objects are treated as arrays        isArray = elems instanceof jQuery || length !== undefined &&typeof length === "number" && ((length > 0 && elems[0] && elems[length -1]) || length === 0 || jQuery.isArray(elems));

    // Go through the array, translating each of the items to their    if (isArray) {        for (; i < length; i++) {            value = callback(elems[i], i, arg);

            if (value != null) {                ret[ret.length] = value;            }        }

        // Go through every key on the object,    } else {        for (key in elems) {            value = callback(elems[key], key, arg);

            if (value != null) {                ret[ret.length] = value;            }        }    }

    // Flatten any nested arrays    return ret.concat.apply([], ret);},

.map()

Page 31: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous// Take an array of elements and push it onto the stack// (returning the new matched element set)pushStack: function(elems, name, selector) {    // Build a new jQuery matched element set    var ret = this.constructor();

    if (jQuery.isArray(elems)) {        push.apply(ret, elems);

    } else {        jQuery.merge(ret, elems);    }

    // Add the old object onto the stack (as a reference)    ret.prevObject = this;

    ret.context = this.context;

    if (name === "find") {        ret.selector = this.selector + (this.selector ? " " : "") +selector;    } else if (name) {        ret.selector = this.selector + "." + name + "(" + selector +")";    }

    // Return the newly-formed element set    return ret;},

.map()

Page 32: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

// Determine the position of an element within// the matched set of elementsindex: function(elem) {    if (!elem || typeof elem === "string") {        return jQuery.inArray(this[0],        // If it receives a string, the selector is used        // If it receives nothing, the siblings are used        elem ? jQuery(elem) : this.parent().children());    }    // Locate the position of the desired element    return jQuery.inArray(    // If it receives a jQuery object, the first element is used    elem.jquery ? elem[0] : elem, this);},

.index()

Page 33: jQuery Data Manipulate API - A source code dissecting journey

Miscellaneous

// Get the Nth element in the matched element set OR// Get the whole matched element set as a clean arrayget: function(num) {    return num == null ?

    // Return a 'clean' array    this.toArray() :

    // Return just the object    (num < 0 ? this[this.length + num] : this[num]);},

.get()

Page 34: jQuery Data Manipulate API - A source code dissecting journey

General Attributes

.attr()

.removeAttr()

.prop()

.removeProp()

Page 35: jQuery Data Manipulate API - A source code dissecting journey

General Attributes

attr: function(name, value) {    return jQuery.access(this, name, value, true, jQuery.attr);},

removeAttr: function(name) {    return this.each(function() {        jQuery.removeAttr(this, name);    });},

.attr() .removeAttr()

Page 36: jQuery Data Manipulate API - A source code dissecting journey

General Attributes

prop: function(name, value) {    return jQuery.access(this, name, value, true, jQuery.prop);},

removeProp: function(name) {    return this.each(function() {        // try/catch handles cases where IE balks (such as removing a property on window)        try {            this[name] = undefined;            delete this[name];        } catch (e) {}    });},

.prop() .removeProp()