jQuery inside - attributes, properties, these

mercredi 23 janvier 2013

The last of the New Year holidays, but not the last in this series of articles on internal jQuery. was a very fast and small, but the interest habrazhiteley to the subject, according to the survey "should I go on?" which hang in every post for some time after its creation not lost.

Topic for today's post is big enough and I will talk about it more interesting and not too shallow. We now consider a method attr , Prop and Data .

The last of these - the most interesting and we postpone it for last.

All three functions are working through the service access .


jQuery.access


This feature resembles domManip from the previous chapter and is necessary for the preparation of arguments passed to the function, and then - to perform the specified callback'a. In our case, this callback - just those functions that will operate with the attributes, properties, and data.

For a start, the function checked our arguments, and if - the object, it will be "deployed" and each key access will be called separately. Metaphorically, these two options - the same:
 $('.user-avatar').attr( { 'alt': 'Аватар', 'title': function(idx, value) { return 'Пользователь ' + value + ' (' + $(this).data('id') + ')'; } } ); 
 $('.user-avatar') .attr('alt', 'Аватар') .attr('title', function(idx, value) { return 'Пользователь ' + value + ' (' + $(this).data('id') + ')'; } ); 
Next to each item in our jQuery-object is called callback for the current key and value. As the example above, the functions in the value are also supported in this situation, the callback will be determined in the specified function to be called in the context of the element in the settings to get her number and the current value of the specified attribute.

Attributes and Properties


jQuery.fn.attr

The first thing the function checks the type of the element , so cut off trying to get or set the attribute in ATTRIBUTE_NODE , COMMENT_NODE , TEXT_NODE .

Next there is a check on the existence of a function with a given key name in jQuery.fn , but this check is triggered only when a call jQuery.attr from init . The first article was an example on this subject and I promised to talk about it yet. So, the code on the left will be "deployed" in the code on the right:
 $('<span>', { 'title': 'Пользователь', 'text': 'Содержимое ноды', 'appendTo': document.body } ); 
 $('<span>') .attr('title', 'Пользователь') .text('Содержимое ноды') .appendTo(document.body); 
Do not recommend doing so with appendTo simply because it is not very nice. However, it is possible for any function that we can find in jQuery.fn . In this case, attr will feature text and appendTo and call them instead cont. their work.

If the item does not exist at this method as getAttribute , it will be called jQuery.prop with the same key and value. This case is quite narrow and is manifested, according to bug reports , only in old IE at work than with HTML, and with XML-document, which comes from the ajax-request, for example.

If the attribute value is passed to the function and is equal to null , will be called jQuery.removeAttr , which will remove the attribute (or attributes if they have been listed by a space) and put the Harmonised boolean-property, if any, in the value of false .

Further attribute is set with the corresponding hook (if it exists) or conventional setAttribute , or will be received by hook or getAttribute .

jQuery.fn.prop

Linger on this function will not, because it works much the same as attr , only sets the element properties directly and simultaneously normalize the names of properties. Normalization is a service object jQuery.propFix , which, again, is not documented and is not advisable to use it, however:

 jQuery.propFix.validMsg = 'validationMessage'; // результаты будут равны $('input:first').prop('validMsg') === $('input:first').prop('validationMessage'); 

Hooks

Hooks to attr ( jQuery.attrHooks ) and prop ( jQuery.propHooks ) - these are ordinary objects that can be a feature set and / or get . They were engaged in the task and have a certain value. On the example will be more clear:

 <span class="user user-male">Игорь</span> <span class="user user-male">Дарья</span><!-- male - намеренно !--> <script src="http://code.jquery.com/jquery-1.8.3.js"></script> <script> var SEX_MALE = 0, SEX_FEMALE = 1, sexClassesMap = { 'user-male': SEX_MALE, 'user-female': SEX_FEMALE }; jQuery.propHooks.usersex = { get: function(elem) { var elementClasses = elem.className.split(/\s+/), i = elementClasses.length; for (; i > 0; i--) { if ('undefined' !== typeof sexClassesMap[elementClasses[i]]) { return sexClassesMap[elementClasses[i]]; } } }, set: function(elem, value) { var $element = $(elem), i; for (className in sexClassesMap) { $element.toggleClass( className, sexClassesMap[className] === value ); } } } // пройдет через хук и вернет male if (SEX_MALE === $('.user:first').prop('userSex')) { console.log('первый - мужчина!'); } // а так мы - можем поменять $('.user:last').prop('userSex', SEX_FEMALE); </script> 

Thing may be convenient, but not documented. Do not use it without extreme need.

For attr is an interesting set of hooks boolHook , it is automatically applied to all pre-defined boolean attributes . He needed to do this:

 > $('<input>').attr('disabled', true) [<input disabled=​"disabled">​] 

In this case, an additional hook and will set the properties of disabled to true .

There's also a set of nodeHook , but this kind of a set of crutches, which is replenished during the initialization of jQuery, in tests of the browser (for example, here .) In modern browsers, it is empty.

Data


To begin with, you Big mistaken if you think that jQuery knows something of such a thing as a dataset , which came to us along with HTML5. No idea, it is not used anywhere in the library, all done by hand. However, the properties specified by dataset available through jQuery.data (only if it is not an object). But if some of the jQuery set through jQuery.data , available through the dataset , it will not be, because the library all the set value is stored in its cache. All in good time, and even divide head slightly.

namespace

Casually mention that in jQuery 1.8.3 jQuery.fn.data can work with so-called namespace for the data. This possibility has been marked as deprecated in 1.7, and in 1.9 it's gone completely. So if you use something, then I have bad news for you:

 $('sometag').on('changeData.users', function(e) { console.dir(e); } ); // бабах, тут мы увидим, что обработчик события выполнился $('sometag').data('id.users', 10); // а вот тут - данные зададутся, а тот обработчик уже не вызовется $('sometag').data( { 'id.users': 10 } ); 

Neymspeysy in events not going away and we will definitely consider in the future.

acceptData

data does not work with anything that moves, but only to what is being tested function acceptData . Only nodes without embed , applet , or object (in this case, with the exception of Flash, the definition is on the classid ).

jQuery.cache

JQuery cache in use not only data . In our case, the data in the cache item gets something when you set some value to some key. Object jQuery.cache is a standard numbered object, where key - value expando -element attribute. jQuery.expando - unique identifier determined randomly initialize the library. As soon as we want to write something in the cache, the element stands out for his number (increment global counter jQuery.guid ) in the cache, which is stored in a property element. At the appropriate number element cache in section «data» will be placed the value itself. On the example will be more clear:

 var $span = $('<span>'), spanElement = $span[0]; // уникальный идентификатор, после рефреша страницы будет уже другим console.log(jQuery.expando); // jQuery18302642508496064693 console.log(spanElement[jQuery.expando]); // undefined // задаем данные по ключу id $span.data('id', 10); console.log(spanElement[jQuery.expando]); // 1 console.dir(jQuery.cache[1]); /* Object { data: Object { id: 10 } } */ $span.remove(); console.dir(jQuery.cache[1]); // undefined console.dir(jQuery.deletedIds); // [ 1 ] 

Remember briefly mentioned cleanData in the previous article? It just cleans the cache by deleting elements, and the deleted sequence number resets to jQuery.deletedIds , to then take the next number from there instead of generating a new one.

What is interesting, the cache with the data for the node is not set right within the library and in this case will not have to worry about cleaning. This internal object cache simultaneously given an empty method toJSON , so he did not get in the output when serialized in JSON:

 var $strangeObject = $( { 'test': 123 } ), strangeObject = $strangeObject[0]; $strangeObject.data('id', 10); console.dir(strangeObject); /* Object { jQuery18309172190900426358: Object { data: Object { id: 10 } toJSON: function () {} } test: 123 } */ console.log(JSON.stringify(strangeObject, null, 4)); /* { "test": 123 } */ 

camelCase

All the keys for data converted to camelCase as reading and writing to (by the way, dataset that can not boast, for the keys to the dash it will complain):

 $('<span>').data('test-me', 10).data('testMe') // 10 $('<span>').data('testMe', 10).data('test-me') // 10 

Write data

To record from a key library first tries to allocate the namespace (that after a point), for use later in the call to the event, which we have mentioned above.

Then, through the same accessData (recall the value from support functions, etc.) is trying to call an event handler setData to the item record data in the cache (generally jQuery.data - just a sheet to work with keshom, on which we have already learned a little above) and is trying to call an event handler changeData .

To record multiple data at the object for each key-value twitches jQuery.data , then there is a record, bypassing accessData and recall of the events that most likely a bug in the library (must call yourself, jQuery.fn.data ). Mend nothing, 1.9 rewrote this piece.

Reading

Reading element also passes through accessData . First the data library is trying to find the cache, and if not found, it tries to find a data-element attribute that might have had to be set manually.

In this case, the key antikemeliziruetsya (uh what is the word, but the point is that testMe will be transformed into test-me) and it is trying to be obtained by the value of the corresponding data-attribute (data-test-me for an example of the previous brackets) and, if is found, it is parsed. If the value - null or boolean, then it will be converted to the native (non-string), but if the attribute value begins with an open brace, the library will try to call jQuery.jsonParse . Please note that long (more than 20 characters) may return as a number, and as a line (thanks for the tip Silver_Clash ), in the event that, after the conversion to a number and back to the comparison with the original will not be passed. The resulting value will be written into the cache and returned to the developer.

Getting the entire set of data again separated from accessData and, again, will not cause the event handler getData . In this case, you receive all of the cache plus the library will run on all the attributes of an element, whose name begins with the «data-» and just write it in the cache itself, simultaneously exposing the cache box parsedAttrs , to receive the next full re all attributes not disassemble.

Conclusion


Perhaps, data should consider a separate article on the attributes and properties, but then the article on them would have been quite small. And so - the thing is, to begin his first day of work after a long weekend. I like to get the article, so it happened that I was terribly interested in such kovyryatya. I hope, like you, too.

0 commentaires:

Enregistrer un commentaire

 
© Copyright 2010-2011 GARMOBI All Rights Reserved.
Template Design by Herdiansyah Hamzah | Published by Borneo Templates | Powered by Blogger.com.