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

jQuery Data Manipulate API - A source code dissecting journey

May 10, 2015

Download

Technology

Dean Yan

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.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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()