茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    jQuery中數(shù)據(jù)緩存$.data的用法及源碼完全解析
    來源:易賢網(wǎng) 閱讀:1051 次 日期:2016-07-06 11:34:30
    溫馨提示:易賢網(wǎng)小編為您整理了“jQuery中數(shù)據(jù)緩存$.data的用法及源碼完全解析”,方便廣大網(wǎng)友查閱!

    這篇文章主要介紹了jQuery中的數(shù)據(jù)緩存$.data的用法及源碼完全解析,深入解讀了jQuery對緩存對象的讀寫和移除的實現(xiàn),需要的朋友可以參考下

    一、實現(xiàn)原理:

    對于DOM元素,通過分配一個唯一的關(guān)聯(lián)id把DOM元素和該DOM元素的數(shù)據(jù)緩存對象關(guān)聯(lián)起來,關(guān)聯(lián)id被附加到以jQuery.expando的值命名的屬性上,數(shù)據(jù)存儲在全局緩存對象jQuery.cache中。在讀取、設(shè)置、移除數(shù)據(jù)時,將通過關(guān)聯(lián)id從全局緩存對象jQuery.cache中找到關(guān)聯(lián)的數(shù)據(jù)緩存對象,然后在數(shù)據(jù)緩存對象上執(zhí)行讀取、設(shè)置、移除操作。

    對于Javascript對象,數(shù)據(jù)則直接存儲在該Javascript對象的屬性jQuery.expando上。在讀取、設(shè)置、移除數(shù)據(jù)時,實際上是對Javascript對象的數(shù)據(jù)緩存對象執(zhí)行讀取、設(shè)置、移除操作。

    為了避免jQuery內(nèi)部使用的數(shù)據(jù)和用戶自定義的數(shù)據(jù)發(fā)生沖突,數(shù)據(jù)緩存模塊把內(nèi)部數(shù)據(jù)存儲在數(shù)據(jù)緩存對象上,把自定義數(shù)據(jù)存儲在數(shù)據(jù)緩存對象的屬性data上。

    二、總體結(jié)構(gòu):

    // 數(shù)據(jù)緩存 Data

    jQuery.extend({

       // 全局緩存對象

       cache: {},

       // 唯一 id種子

       uuid:0,

       // 頁面中每個jQuery副本的唯一標(biāo)識

       expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),

       // 是否有關(guān)聯(lián)的數(shù)據(jù)

       hasData: function(){},

       // 設(shè)置、讀取自定數(shù)據(jù)或內(nèi)部數(shù)據(jù)

       data: function(elem, name, data, pvt) {},

       // 移除自定義數(shù)據(jù)或內(nèi)部數(shù)據(jù)

       removeData: function(elem, name, pvt) {},

       // 設(shè)置、讀取內(nèi)部數(shù)據(jù)

       _data: function(elem, name, data) {},

       // 是否可以設(shè)置數(shù)據(jù)

       acceptData: function(elem){}

    });

    jQuery.fn.extend({

       // 設(shè)置、讀取自定義數(shù)據(jù),解析HTML5屬性data-

       data: function(key,value){},

       // 移除自定義數(shù)據(jù)

       removeData: function(key){}

    });

    // 解析HTML5屬性 data-

    function dataAttr(elem,key,data){}

    // 檢查數(shù)據(jù)緩存對象是否為空

    function isEmptyDataObject(obj){}

    jQuery.extend({

       // 清空數(shù)據(jù)緩存對象

    cleanData: function(elems){}

    });

    三、$.data(elem, name, data), $.data(elem, name)

    $.data(elem, name, data)的使用方法:

    如果傳入?yún)?shù)name, data, 則設(shè)置任意類型的數(shù)據(jù)

    <!doctype html>

    <html lang="en">

    <head>

     <meta charset="utf-8">

     <title>jQuery.data demo</title>

     <style>

     div {

      color: blue;

     }

     span {

      color: red;

     }

     </style>

     <script src="http://code.jquery.com/jquery-1.10.2.js"></script>

    </head>

    <body>

    <div>

     The values stored were

     <span></span>

     and

     <span></span>

    </div>

    <script>

    var div = $( "div" )[ 0 ];

    jQuery.data( div, "test", {

     first: 16,

     last: "pizza!"

    });

    $( "span:first" ).text( jQuery.data( div, "test" ).first );

    $( "span:last" ).text( jQuery.data( div, "test" ).last );

    </script>

    </body>

    </html>

    $.data(elem, name)的使用方法:

    如果傳入key, 未傳入?yún)?shù)data, 則讀取并返回指定名稱的數(shù)據(jù)

    <!doctype html>

    <html lang="en">

    <head>

     <meta charset="utf-8">

     <title>jQuery.data demo</title>

     <style>

     div {

      margin: 5px;

      background: yellow;

     }

     button {

      margin: 5px;

      font-size: 14px;

     }

     p {

      margin: 5px;

      color: blue;

     }

     span {

      color: red;

     }

     </style>

     <script src="http://code.jquery.com/jquery-1.10.2.js"></script>

    </head>

    <body>

    <div>A div</div>

    <button>Get "blah" from the div</button>

    <button>Set "blah" to "hello"</button>

    <button>Set "blah" to 86</button>

    <button>Remove "blah" from the div</button>

    <p>The "blah" value of this div is <span>?</span></p>

    <script>

    $( "button" ).click( function() {

     var value,

      div = $( "div" )[ 0 ];

     switch ( $( "button" ).index( this ) ) {

     case 0 :

      value = jQuery.data( div, "blah" );

      break;

     case 1 :

      jQuery.data( div, "blah", "hello" );

      value = "Stored!";

      break;

     case 2 :

      jQuery.data( div, "blah", 86 );

      value = "Stored!";

      break;

     case 3 :

      jQuery.removeData( div, "blah" );

      value = "Removed!";

      break;

     }

     $( "span" ).text( "" + value );

    });

    </script>

    </body>

    </html>

    $.data(elem, name, data), $.data(elem, name) 源碼解析:

    jQuery.extend({

     // 1. 定義jQuery.data(elem, name, data, pvt)

     data: function( elem, name, data, pvt /* Internal Use Only */ ) {

      // 2. 檢查是否可以設(shè)置數(shù)據(jù)

      if ( !jQuery.acceptData( elem ) ) {

       return; // 如果參數(shù)elem不支持設(shè)置數(shù)據(jù),則立即返回

      }

      // 3 定義局部變量

      var privateCache, thisCache, ret,

       internalKey = jQuery.expando,

       getByName = typeof name === "string",

       // 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, // elem是否是DOM元素

       // 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, // 如果是DOM元素,為了避免javascript和DOM元素之間循環(huán)引用導(dǎo)致的瀏覽器(IE6/7)垃圾回收機制不起作用,要把數(shù)據(jù)存儲在全局緩存對象jQuery.cache中;對于javascript對象,來及回收機制能夠自動發(fā)生,不會有內(nèi)存泄露的問題,因此數(shù)據(jù)可以查收存儲在javascript對象上

       // 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,

       isEvents = name === "events";

      // Avoid doing any more work than we need to when trying to get data on an

      // object that has no data at all

      // 4. 如果是讀取數(shù)據(jù),但沒有數(shù)據(jù),則返回

      if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {

       return;

       // getByName && data === undefined 如果name是字符串,data是undefined, 說明是在讀取數(shù)據(jù)

       // !id || !cache[id] || (!isEvents && !pvt && !cache[id].data 如果關(guān)聯(lián)id不存在,說明沒有數(shù)據(jù);如果cache[id]不存在,也說明沒有數(shù)據(jù);如果是讀取自動以數(shù)據(jù),但cache[id].data不存在,說明沒有自定義數(shù)據(jù)

      }

      // 5. 如果關(guān)聯(lián)id不存在,則分配一個

      if ( !id ) {

       // Only DOM nodes need a new unique ID for each element since their data

       // ends up in the global cache

       if ( isNode ) {

        elem[ internalKey ] = id = ++jQuery.uuid; // 對于DOM元素,jQuery.uuid會自動加1,并附加到DOM元素上

       } else {

        id = internalKey; // 對于javascript對象,關(guān)聯(lián)id就是jQuery.expando

       }

      }

      // 6. 如果數(shù)據(jù)緩存對象不存在,則初始化為空對象{}

      if ( !cache[ id ] ) {

       cache[ id ] = {};

       // Avoids exposing jQuery metadata on plain JS objects when the object

       // is serialized using JSON.stringify

       if ( !isNode ) {

        cache[ id ].toJSON = jQuery.noop; // 對于javascript對象,設(shè)置方法toJSON為空函數(shù),以避免在執(zhí)行JSON.stringify()時暴露緩存數(shù)據(jù)。如果一個對象定義了方法toJSON(),JSON.stringify()在序列化該對象時會調(diào)用這個方法來生成該對象的JSON元素

       }

      }

      // An object can be passed to jQuery.data instead of a key/value pair; this gets

      // shallow copied over onto the existing cache

      // 7. 如果參數(shù)name是對象或函數(shù),則批量設(shè)置數(shù)據(jù)

      if ( typeof name === "object" || typeof name === "function" ) {

       if ( pvt ) {

        cache[ id ] = jQuery.extend( cache[ id ], name ); // 對于內(nèi)部數(shù)據(jù),把參數(shù)name中的屬性合并到cache[id]中

       } else {

        cache[ id ].data = jQuery.extend( cache[ id ].data, name ); // 對于自定義數(shù)據(jù),把參數(shù)name中的屬性合并到cache[id].data中

       }

      }

      // 8. 如果參數(shù)data不是undefined, 則設(shè)置單個數(shù)據(jù)

      privateCache = 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;

      }

      // Users should not attempt to inspect the internal events object using jQuery.data,

      // it is undocumented and subject to change. But does anyone listen? No.

      // 9. 特殊處理events 

      if ( isEvents && !thisCache[ name ] ) { // 如果參數(shù)name是字符串"events",并且未設(shè)置過自定義數(shù)據(jù)"events",則返回事件婚車對象,在其中存儲了事件監(jiān)聽函數(shù)。

       return privateCache.events;

      }

      // Check for both converted-to-camel and non-converted data property names

      // If a data property was specified

      //10. 如果參數(shù)name是字符串,則讀取單個數(shù)據(jù)

      if ( getByName ) {

       // First Try to find as-is property data

       ret = thisCache[ name ]; // 先嘗試讀取參數(shù)name對應(yīng)的數(shù)據(jù)

       // Test for null|undefined property data

       if ( ret == null ) { // 如果未取到,則把參數(shù)name轉(zhuǎn)換為駝峰式再次嘗試讀取對應(yīng)的數(shù)據(jù)

        // Try to find the camelCased property

        ret = thisCache[ jQuery.camelCase( name ) ];

       }

      } else { // 11. 如果未傳入?yún)?shù)name,data,則返回數(shù)據(jù)緩存對象

       ret = thisCache;

      }

      return ret;

     },

     // For internal use only.

     _data: function( elem, name, data ) {

      return jQuery.data( elem, name, data, true );

     },

    });

    四、.data(key, value), .data(key)

    使用方法:

    $( "body" ).data( "foo", 52 ); // 傳入key, value

    $( "body" ).data( "bar", { myType: "test", count: 40 } ); // 傳入key, value

    $( "body" ).data( { baz: [ 1, 2, 3 ] } ); // 傳入key, value

    $( "body" ).data( "foo" ); // 52 // 傳入key

    $( "body" ).data(); // 未傳入?yún)?shù)

    HTML5 data attriubutes:

    <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";

    .data(key, value), .data(key) 源碼解析

    jQuery.fn.extend({ // 1. 定義.data(key, value)

     data: function( key, value ) {

      var parts, attr, name,

       data = null;

      // 2. 未傳入?yún)?shù)的情況

      if ( typeof key === "undefined" ) {

       if ( this.length ) { // 如果參數(shù)key是undefined, 即參數(shù)格式是.data(), 則調(diào)用方法jQuery.data(elem, name, data, pvt)獲取第一個匹配元素關(guān)聯(lián)的自定義數(shù)據(jù)緩存對象,并返回。

        data = jQuery.data( this[0] );

        if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {

         attr = this[0].attributes;

         for ( var i = 0, l = attr.length; i < l; i++ ) {

          name = attr[i].name;

          if ( name.indexOf( "data-" ) === 0 ) {

           name = jQuery.camelCase( name.substring(5) );

           dataAttr( this[0], name, data[ name ] );

          }

         }

         jQuery._data( this[0], "parsedAttrs", true );

        }

       }

       return data;

      // 3. 參數(shù)key 是對象的情況,即參數(shù)格式是.data(key),則遍歷匹配元素集合,為每個匹配元素調(diào)用方法jQuery.data(elem, name, data,pvt)批量設(shè)置數(shù)據(jù)

      } else if ( typeof key === "object" ) {

       return this.each(function() {

        jQuery.data( this, key );

       });

      }

      // 4. 只傳入?yún)?shù)key的情況 如果只傳入?yún)?shù)key, 即參數(shù)格式是.data(key),則返回第一個匹配元素的指定名稱數(shù)據(jù)

      parts = key.split(".");

      parts[1] = parts[1] ? "." + parts[1] : "";

      if ( value === undefined ) {

       data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);

       // Try to fetch any internally stored data first

       if ( data === undefined && this.length ) {

        data = jQuery.data( this[0], key );

        data = dataAttr( this[0], key, data );

       }

       return data === undefined && parts[1] ?

        this.data( parts[0] ) :

        data;

      // 5. 傳入?yún)?shù)key和value的情況 即參數(shù)格式是.data(key, value),則為每個匹配元素設(shè)置任意類型的數(shù)據(jù),并觸發(fā)自定義事件setData, changeData

      } else {

       return this.each(function() {

        var self = jQuery( this ),

         args = [ parts[0], value ];

        self.triggerHandler( "setData" + parts[1] + "!", args );

        jQuery.data( this, key, value );

        self.triggerHandler( "changeData" + parts[1] + "!", args );

       });

      }

     },

     removeData: function( key ) {

      return this.each(function() {

       jQuery.removeData( this, key );

      });

     }

    });

    // 6. 函數(shù)dataAttr(elem, key, data)解析HTML5屬性data-

    function dataAttr( elem, key, data ) {

     // If nothing was found internally, try to fetch any

     // data from the HTML5 data-* attribute

     // 只有參數(shù)data為undefined時,才會解析HTML5屬性data-

     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 :

        jQuery.isNumeric( data ) ? parseFloat( 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;

    }

    五、$.removeData(elem, name),.removeData(key)

    使用方法:

    <!doctype html>

    <html lang="en">

    <head>

     <meta charset="utf-8">

     <title>jQuery.removeData demo</title>

     <style>

     div {

      margin: 2px;

      color: blue;

     }

     span {

      color: red;

     }

     </style>

     <script src="http://code.jquery.com/jquery-1.10.2.js"></script>

    </head>

    <body>

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

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

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

    <div>value2 after removal: <span></span></div>

    <script>

    var div = $( "div" )[ 0 ];

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

    jQuery.data( div, "test1", "VALUE-1" );

    jQuery.data( div, "test2", "VALUE-2" );

    $( "span:eq(1)" ).text( "" + jQuery.data( div, "test1" ) ); // VALUE-1

    jQuery.removeData( div, "test1" );

    $( "span:eq(2)" ).text( "" + jQuery.data( div, "test1" ) ); // undefined

    $( "span:eq(3)" ).text( "" + jQuery.data( div, "test2" ) ); // value2

    </script>

    </body>

    </html>

    <!doctype html>

    <html lang="en">

    <head>

     <meta charset="utf-8">

     <title>removeData demo</title>

     <style>

     div {

      margin: 2px;

      color: blue;

     }

     span {

      color: red;

     }

     </style>

     <script src="http://code.jquery.com/jquery-1.10.2.js"></script>

    </head>

    <body>

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

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

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

    <div>value2 after removal: <span></span></div>

    <script>

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

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

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

    $( "span:eq(1)" ).text( "" + $( "div").data( "test1" ) ); // VALUE-1

    $( "div" ).removeData( "test1" );

    $( "span:eq(2)" ).text( "" + $( "div" ).data( "test1" ) ); // undefined

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

    </script>

    </body>

    </html>

    $.removeData(elem, name),.removeData(key) 源碼解析:

    $.extend({

      // jQuery.removeData(elem,name,pvt)用于移除通過jQuery.data()設(shè)置的數(shù)據(jù)

     removeData: function( elem, name, pvt /* Internal Use Only */ ) {

      if ( !jQuery.acceptData( elem ) ) {

       return;

      }

      var thisCache, i, l,

       // Reference to internal data cache key

       internalKey = jQuery.expando,

       isNode = elem.nodeType,

       // See jQuery.data for more information

       cache = isNode ? jQuery.cache : elem,

       // See jQuery.data for more information

       id = isNode ? elem[ internalKey ] : internalKey;

      // If there is already no cache entry for this object, there is no

      // purpose in continuing

      if ( !cache[ id ] ) {

       return;

      }

        // 如果傳入?yún)?shù)name, 則移除一個或多個數(shù)據(jù)

      if ( name ) {

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

       if ( thisCache ) { // 只有數(shù)據(jù)緩存對象thisCache存在時,才有必要移除數(shù)據(jù)

        // 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( " " );

          }

         }

        }

        // 遍歷參數(shù)name中的數(shù)據(jù)名,用運算符delete逐個從數(shù)據(jù)緩存對象thisCache中移除

        for ( i = 0, l = name.length; i < l; 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 : jQuery.isEmptyObject )( thisCache ) ) {

         return;

        }

       }

      }

      // See jQuery.data for more information

      // 刪除自定義數(shù)據(jù)緩存對象cache[id].data

      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;

       }

      }

      // Browsers that fail expando deletion also refuse to delete expandos on

      // the window, but it will allow it on all other JS objects; other browsers

      // don't care

      // Ensure that `cache` is not a window object #10080

      // 刪除數(shù)據(jù)緩存對象cache[id]

      if ( jQuery.support.deleteExpando || !cache.setInterval ) {

       delete cache[ id ];

      } else {

       cache[ id ] = null;

      }

      // We destroyed the cache and need to eliminate the expando on the node to avoid

      // false lookups in the cache for entries that no longer exist

      // 刪除DOM元素上擴展的jQuery.expando屬性

      if ( isNode ) {

       // IE does not allow us to delete expando properties from nodes,

       // nor does it have a removeAttribute function on Document nodes;

       // we must handle all of these cases

       if ( jQuery.support.deleteExpando ) {

        delete elem[ internalKey ];

       } else if ( elem.removeAttribute ) {

        elem.removeAttribute( internalKey );

       } else {

        elem[ internalKey ] = null;

       }

      }

     }

    });

    jQuery.fn.extend({

      removeData: function( key ) {

       return this.each(function() {

        jQuery.removeData( this, key );

       });

      }

    });

    // checks a cache object for emptiness

    function isEmptyDataObject( obj ) {

     for ( var name in obj ) {

      // if the public data object is empty, the private is still empty

      if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {

       continue;

      }

      if ( name !== "toJSON" ) {

       return false;

      }

     }

     return true;

    }

    六、$.hasData(elem)

    使用方法:

    <!doctype html>

    <html lang="en">

    <head>

     <meta charset="utf-8">

     <title>jQuery.hasData demo</title>

     <script src="http://code.jquery.com/jquery-1.10.2.js"></script>

    </head>

    <body>

    <p>Results: </p>

    <script>

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

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

    $.data( p, "testing", 123 );

    $p.append( jQuery.hasData( p ) + " " ); // true

    $.removeData( p, "testing" );

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

    $p.on( "click", function() {} );

    $p.append( jQuery.hasData( p ) + " " ); // true

    $p.off( "click" );

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

    </script>

    </body>

    </html>

    $.hasData(elem) 源碼解析:

    $.extend({

      hasData: function( elem ) {

       elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];

       return !!elem && !isEmptyDataObject( elem );

       // 如果關(guān)聯(lián)的數(shù)據(jù)緩存對象存在,并且含有數(shù)據(jù),則返回true, 否則返回false。 這里用兩個邏輯非運算符! 把變量elem轉(zhuǎn)換為布爾值

     }

    });

    更多信息請查看網(wǎng)絡(luò)編程
    由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

    2026上岸·考公考編培訓(xùn)報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
    云南網(wǎng)警備案專用圖標(biāo)
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
    云南網(wǎng)警報警專用圖標(biāo)