天天看點

深入學習jquery源碼之data()

深入學習jquery源碼之data()

jQuery.data(element,[key],[value])

概述:

在元素上存放資料,傳回jQuery對象。

注意:這是一個底層方法。你應當使用.data()來代替。

此方法在jQuery 1.8中删除,但你仍然可以通過$._data(element, "events")調試事件資料。請注意,這是不支援的公共接口;實際的資料結構可能會改變從版本之間不相容。

參數:

element,key,value String,String,Any

element:要關聯資料的DOM對象

key:存儲的資料名

value:将要存儲的任意資料

element,key String,String

element:要查詢資料的DOM對象

key:存儲的資料名

element String

要查詢資料的DOM對象

jQuery.data(document.body, 'foo', 52);
jQuery.data(document.body, 'bar', 'test');
           

data([key],[value])

概述:

在元素上存放資料,傳回jQuery對象。

如果jQuery集合指向多個元素,那将在所有元素上設定對應資料。 這個函數不用建立一個新的expando,就能在一個元素上存放任何格式的資料,而不僅僅是字元串。

V1.4.3 新增用法NEW data(obj) 可傳入key-value形式的資料。

參數:

key String

存儲的資料名.

key,value  String,Any

key:存儲的資料名

value:将要存儲的任意資料

obj object

一個用于設定資料的鍵/值對

data()

說明:

在一個div上存取資料

<div></div>
           
$("div").data("blah");  // undefined
$("div").data("blah", "hello");  // blah設定為hello
$("div").data("blah");  // hello
$("div").data("blah", 86);  // 設定為86
$("div").data("blah");  //  86
$("div").removeData("blah");  //移除blah
$("div").data("blah");  // undefined
           

在一個div上存取名/值對資料

<div></div>
           
$("div").data("test", { first: 16, last: "pizza!" });
$("div").data("test").first  //16;
$("div").data("test").last  //pizza!;
           

removeData([name|list])

概述:

在元素上移除存放的資料與$(...).data(name, value)函數作用相反

參數:

[name] String

存儲的資料名

[list] Array,String

移除數組或以空格分開的字元串

說明

從元素中删除之前添加的資料:

$("#btn2").click(function(){
  $("div").removeData("greeting");
  alert("Greeting is: " + $("div").data("greeting"));
});
           

測試:

data() 方法向被選元素附加資料,或者從被選元素擷取資料。

$("#btn1").click(function(){
  $("div").data("greeting", "Hello World");
});
$("#btn2").click(function(){
  alert($("div").data("greeting"));
});
           
(function ($) {
    function init(target) {
        var t = $(target),
            state = $.data(target, 'gridsub'),
            key = state.options.key;
        var editIndex = undefined;
        function endEditing() {
            if (editIndex == undefined) { return true }
            if (t.datagrid('validateRow', editIndex)) {
                var ed = t.datagrid('getEditor', { index: editIndex, field: key });
                t.datagrid('endEdit', editIndex);
                editIndex = undefined;
                return true;
            } else {
                return false;
            }
        }
        t.datagrid({
            title: state.options.title,
            width: state.options.width,
            onClickRow: function (index) {
                if (endEditing()) {
                    t.datagrid('selectRow', index)
                        .datagrid('beginEdit', index);
                    editIndex = index;
                } else {
                    t.datagrid('selectRow', editIndex);
                }
            },
            rownumbers: state.options.rownumbers,
            singleSelect: state.options.singleSelect,
            toolbar: state.options.toolbar,
            pagination: state.options.pagination,
            columns: state.options.columns,
            data: state.options.data,
        });
        $(state.options.toolbar).find("a.add").on("click", function (e) {
            if (endEditing()) {
                t.datagrid('appendRow', {});
                editIndex = t.datagrid('getRows').length - 1;
                t.datagrid('selectRow', editIndex).datagrid('beginEdit', editIndex);
            }
        });
        $(state.options.toolbar).find("a.save").on("click", function (e) {
            if (t.datagrid('validateRow', editIndex)) {
                var ed = t.datagrid('getEditor', { index: editIndex, field: key });
                t.datagrid('endEdit', editIndex);
                t.datagrid('acceptChanges');
                var rows = t.datagrid('getSelected');
                t.datagrid("updateRow", rows);
            }
        });
        $(state.options.toolbar).find("a.del").on("click", function (e) {
            var rows = t.datagrid('getSelected');
            var editIndex = t.datagrid("getRowIndex", rows);
            if (!rows) {
                $Core.UI.message.warning("請選擇一條資料"); return false;
            }
            t.datagrid('cancelEdit', editIndex).datagrid('deleteRow', editIndex);
            editIndex = undefined;
        });
        $(state.options.toolbar).find("a.cancel").on("click", function (e) {
            var row = t.datagrid('getSelected');
            t.datagrid('endEdit', editIndex)
            // if (!state.options.key) {
            //     t.datagrid('deleteRow', editIndex);
            // }
            editIndex = undefined;
        });
    }
    // 插件的定義     
    $.fn.gridsub = function (options, param) {
        if (typeof options == 'string') {
            var method = $.fn.gridsub.methods[options];
            if (method) {
                return method(this, param);
            }
        }
        return this.each(function () {
        	debugger;
            var state = $.data(this, "gridsub");
            if (state) {
                $.extend(state.options, options);
            } else {
                $.data(this, "gridsub",
                    {
                        options: $.extend(true, {}, $.fn.gridsub.defaults, options)
                    });
            }
            init(this);
        });
    };


    $.fn.gridsub.methods = {
        getRows: function (jq) {
            return $(jq[0]).datagrid("getRows");
        },
        load: function (jq, value) {
            return $(jq[0]).datagrid({ data: value });
        }
    };
    // 插件的defaults     
    $.fn.gridsub.defaults = {
        title: '',
        width: 300,
        //onClickRow: state.onClickRow,
        rownumbers: false,
        singleSelect: false,
        // toolbar: state.toolbar,
        pagination: false,
        columns: [],
        data: [],
    };
    // 閉包結束     
})(jQuery);
           
$("#dglist2").gridsub({
		    title: '裝置',
		    width: 1200,
		    key: "id",
		    rownumbers: false,
		    singleSelect: true,
		    toolbar: ".btn_tool2",
		    pagination: false,
		    columns: [[ ]],
		});
           
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()

this中沒有gridsub的屬性,通過$.data向元素附加資料

深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()

.jquery target()     event.target

target 屬性規定哪個 DOM 元素觸發了該事件。

$("p, button, h1, h2").click(function(event){
  $("div").html("Triggered by a " + event.target.nodeName + " element.");
});

<p></p>

<button></button>

<h1></h1>

<h2></h2>

//當點選p标簽的時候顯示:點選事件由 P 元素觸發
           
drawPoint.type["onClick"] = function(point, e){
								Leak.showInfoWindow(point)
							}

			marker = new AMap.Marker(pointOpitons);
			mPoint.marker = marker;
			if(mPoint.type.onClick && $.isFunction(mPoint.type.onClick)) {
				
				marker.on('click',function(e){
					
					mPoint.type.onClick(e.target.getExtData(),null);
				});  //點事件的擷取
			}
           
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()
深入學習jquery源碼之data()

jquery源碼

function dataAttr(elem, key, data) {
        // If nothing was found internally, try to fetch any
        // data from the HTML5 data-* attribute
        if (data === undefined && elem.nodeType === 1) {

            var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();

            data = elem.getAttribute(name);

            if (typeof data === "string") {
                try {
                    data = data === "true" ? true :
                        data === "false" ? false :
                        data === "null" ? null :
                        // Only convert to a number if it doesn't change the string
                        +data + "" === data ? +data :
                        rbrace.test(data) ? jQuery.parseJSON(data) :
                        data;
                } catch (e) { }

                // Make sure we set the data so it isn't changed later
                jQuery.data(elem, key, data);

            } else {
                data = undefined;
            }
        }

        return data;
    }



    function internalData(elem, name, data, pvt /* Internal Use Only */) {
        if (!jQuery.acceptData(elem)) {
            return;
        }

        var ret, thisCache,
            internalKey = jQuery.expando,

            // We have to handle DOM nodes and JS objects differently because IE6-7
            // can't GC object references properly across the DOM-JS boundary
            isNode = elem.nodeType,

            // Only DOM nodes need the global jQuery cache; JS object data is
            // attached directly to the object so GC can occur automatically
            cache = isNode ? jQuery.cache : elem,

            // Only defining an ID for JS objects if its cache already exists allows
            // the code to shortcut on the same path as a DOM node with no cache
            id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;

        // Avoid doing any more work than we need to when trying to get data on an
        // object that has no data at all
        if ((!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string") {
            return;
        }

        if (!id) {
            // Only DOM nodes need a new unique ID for each element since their data
            // ends up in the global cache
            if (isNode) {
                id = elem[internalKey] = deletedIds.pop() || jQuery.guid++;
            } else {
                id = internalKey;
            }
        }

        if (!cache[id]) {
            // Avoid exposing jQuery metadata on plain JS objects when the object
            // is serialized using JSON.stringify
            cache[id] = isNode ? {} : { toJSON: jQuery.noop };
        }

        // An object can be passed to jQuery.data instead of a key/value pair; this gets
        // shallow copied over onto the existing cache
        if (typeof name === "object" || typeof name === "function") {
            if (pvt) {
                cache[id] = jQuery.extend(cache[id], name);
            } else {
                cache[id].data = jQuery.extend(cache[id].data, name);
            }
        }

        thisCache = cache[id];

        // jQuery data() is stored in a separate object inside the object's internal data
        // cache in order to avoid key collisions between internal data and user-defined
        // data.
        if (!pvt) {
            if (!thisCache.data) {
                thisCache.data = {};
            }

            thisCache = thisCache.data;
        }

        if (data !== undefined) {
            thisCache[jQuery.camelCase(name)] = data;
        }

        // Check for both converted-to-camel and non-converted data property names
        // If a data property was specified
        if (typeof name === "string") {

            // First Try to find as-is property data
            ret = thisCache[name];

            // Test for null|undefined property data
            if (ret == null) {

                // Try to find the camelCased property
                ret = thisCache[jQuery.camelCase(name)];
            }
        } else {
            ret = thisCache;
        }

        return ret;
    }

    function internalRemoveData(elem, name, pvt) {
        if (!jQuery.acceptData(elem)) {
            return;
        }

        var thisCache, i,
            isNode = elem.nodeType,

            // See jQuery.data for more information
            cache = isNode ? jQuery.cache : elem,
            id = isNode ? elem[jQuery.expando] : jQuery.expando;

        // If there is already no cache entry for this object, there is no
        // purpose in continuing
        if (!cache[id]) {
            return;
        }

        if (name) {

            thisCache = pvt ? cache[id] : cache[id].data;

            if (thisCache) {

                // Support array or space separated string names for data keys
                if (!jQuery.isArray(name)) {

                    // try the string as a key before any manipulation
                    if (name in thisCache) {
                        name = [name];
                    } else {

                        // split the camel cased version by spaces unless a key with the spaces exists
                        name = jQuery.camelCase(name);
                        if (name in thisCache) {
                            name = [name];
                        } else {
                            name = name.split(" ");
                        }
                    }
                } else {
                    // If "name" is an array of keys...
                    // When data is initially created, via ("key", "val") signature,
                    // keys will be converted to camelCase.
                    // Since there is no way to tell _how_ a key was added, remove
                    // both plain key and camelCase key. #12786
                    // This will only penalize the array argument path.
                    name = name.concat(jQuery.map(name, jQuery.camelCase));
                }

                i = name.length;
                while (i--) {
                    delete thisCache[name[i]];
                }

                // If there is no data left in the cache, we want to continue
                // and let the cache object itself get destroyed
                if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
                    return;
                }
            }
        }

        // See jQuery.data for more information
        if (!pvt) {
            delete cache[id].data;

            // Don't destroy the parent cache unless the internal data object
            // had been the only thing left in it
            if (!isEmptyDataObject(cache[id])) {
                return;
            }
        }

        // Destroy the cache
        if (isNode) {
            jQuery.cleanData([elem], true);

            // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
            /* jshint eqeqeq: false */
        } else if (support.deleteExpando || cache != cache.window) {
            /* jshint eqeqeq: true */
            delete cache[id];

            // When all else fails, null
        } else {
            cache[id] = null;
        }
    }

    jQuery.extend({
        cache: {},

        // The following elements (space-suffixed to avoid Object.prototype collisions)
        // throw uncatchable exceptions if you attempt to set expando properties
        noData: {
            "applet ": true,
            "embed ": true,
            // ...but Flash objects (which have this classid) *can* handle expandos
            "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        },

        hasData: function (elem) {
            elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando];
            return !!elem && !isEmptyDataObject(elem);
        },

        data: function (elem, name, data) {
            return internalData(elem, name, data);
        },

        removeData: function (elem, name) {
            return internalRemoveData(elem, name);
        },

        // For internal use only.
        _data: function (elem, name, data) {
            return internalData(elem, name, data, true);
        },

        _removeData: function (elem, name) {
            return internalRemoveData(elem, name, true);
        }
    });


    jQuery.fn.extend({
        data: function (key, value) {
            var i, name, data,
                elem = this[0],
                attrs = elem && elem.attributes;

            // Special expections of .data basically thwart jQuery.access,
            // so implement the relevant behavior ourselves

            // Gets all values
            if (key === undefined) {
                if (this.length) {
                    data = jQuery.data(elem);

                    if (elem.nodeType === 1 && !jQuery._data(elem, "parsedAttrs")) {
                        i = attrs.length;
                        while (i--) {

                            // Support: IE11+
                            // The attrs elements can be null (#14894)
                            if (attrs[i]) {
                                name = attrs[i].name;
                                if (name.indexOf("data-") === 0) {
                                    name = jQuery.camelCase(name.slice(5));
                                    dataAttr(elem, name, data[name]);
                                }
                            }
                        }
                        jQuery._data(elem, "parsedAttrs", true);
                    }
                }

                return data;
            }

            // Sets multiple values
            if (typeof key === "object") {
                return this.each(function () {
                    jQuery.data(this, key);
                });
            }

            return arguments.length > 1 ?

                // Sets one value
                this.each(function () {
                    jQuery.data(this, key, value);
                }) :

                // Gets one value
                // Try to fetch any internally stored data first
                elem ? dataAttr(elem, key, jQuery.data(elem, key)) : undefined;
        },

        removeData: function (key) {
            return this.each(function () {
                jQuery.removeData(this, key);
            });
        }
    });