I was in the console trying something when i saw that the .$ can be used along with the document object to access the elements. But i don't know what it actually does.
example :-
After some detective work, my guess it is a special Polymer component property:
Automatic node finding
Polymer automatically builds a map of statically created instance nodes in its local DOM, to provide
convenient access to frequently used nodes without the need to query
for them manually. Any node specified in the element's template with
an id is stored on the this.$ hash by id.
I am not familiar with Polymer, and it is very difficult to find (recent) documentation on this property.
However I believe my guess is correct based on the description above and the screen shot below. As you can see, if you add another . after the $ you get a list of suggested properties. These are all ids in the DOM:
I guess that may be any global object under jquery. Exactly, I don't have any experience with .$ but surf the official docs of Jquery, it may help or another possibility is that it is something coming from backend of from database. There may be a lot of reason. Hope, it helps..
This should be a property added to the element but is not anything special.
An example would be like
let a = {};
a.$ = {
b: 1,
c: 2
};
console.log(a.$);
This will also give you the object properties of $ in a.
A bonus fun fact is, in Javascript, emoji is also valid as property name, and therefore
let a = {};
a.$ = {
"😍": 1,
"😎": 2
};
console.log(a.$["😍"]);
also works
Related
In my app, I have a number of jQuery objects which are kept in memory. That is, they don't get regenerated by another selector search. Also, they are local to the module.
const jQthing = $('#thing');
Is there any reason not to add custom properties to this object?
jQthing.title = 'All Things';
I know I can use the data dictionary but this looks a bit clumsy, especially
when retrieving a method. Would this be a bad design, or bad style?
Thanks
You can definitely do this, but you just need to be careful that the property that you add does not clash with any properties or functions that the jquery object would have. And that is why I wouldn't recommend that.
Instead, you would probably be better served wrapping the jquery object in an object and then make your own properties off of that. So for example something like below would do what you want, plus avoid any possible collisions.
var objectWrapper = {
jQthing: $('#thing'),
title: 'All Things'
}
So now you can use it like this objectWrapper.jQthing.fadeIn() or objectWrapper.title, without any worries.
I know understand more about how jQuery stores data.
Is there any advantage to doing one or the other of these:
$('#editCity').data('href', "xx");
var a = $('#editCity').data('href');
or
$('#editCity').attr('data-href', "xx");
var a = $('#editCity').attr('data-href');
One more related question.
If I have this:
var modal = { x: 'xx', y: 'yy' };
Can I also store this using .data( .. ) ?
Storing property values directly on DOM elements is risky because of possible memory leaks. If you're using jQuery anyway, the .data() mechanism is a wonderful and safe way to keep track of per-element information. It allows for storage of arbitrary JavaScript data structures too, not just strings.
edit — when your HTML markup contains data-foo attributes, those are implicitly read when the keys are accessed. That is, if your HTML looks like this:
<div id="div1" data-purpose="container">
Then in jQuery:
alert( $('#div1').data('purpose') ); // alerts "container"
Furthermore, jQuery will also do some "smart" analysis of the attribute values. If a value looks like a number, jQuery will return a number, not a string. If it looks like JSON, it de-serializes the JSON for you.
edit — here's a good trick: in the Chrome developer console (the "Console" view), you can type JavaScript expressions and have them evaluated. The evaluation is always done in the context of the page you're working on. If you select an element from the "Elements" view, then in the console the JavaScript symbol $0 will refer to that selected DOM element. Thus you can always inspect the "data" map for an element by going to the console and typing something like:
$($0).data("something");
The .data() function, if called with no parameters, returns all the key/value pairs:
$($0).data();
The most interesting point about the data function is that you can add any kind of object, for example your modal. And jQuery, as stated in the documentation, take care of avoiding memory leaks when the DOM changes :
The jQuery.data() method allows us to attach data of any type to DOM
elements in a way that is safe from circular references and therefore
free from memory leaks.
For strings, memory leaks aren't possible but the main difference is that the first solution is cleaner (more coherent if you might store other data than strings in other parts of your application), clearer (the intent is evident), and doesn't force CSS calculation (DOM isn't changed).
They both have advantages... That said, 99% of the time you should be using .data('whatever', value)
Advantages of using .data('whatever', value):
less apt to cause memory leaks because it's not using the DOM.
Slightly faster to pull data from memory than from the DOM.
Can put any type of object in it without serializing it to JSON first.
Advantages of using .attr('data-whatever', value):
compatible with .data('whatever')
allows you to select the element by the value: $('[data-whatever=foo]')
You can put any object in it, but it will need to serialize if it's a complex type.
function eegetdropdownvalue_str(ctl){return ctl.selectedIndex>=0&&ctl[ctl.selectedIndex]?ctl[ctl.selectedIndex].value:''}
The above function is called with
co.p1A10=eegetdropdownvalue_str(document.formc.p1A10);
I want to switch the call over to jQuery to drop the document.form reference however doing this
co.p1A10=eegetdropdownvalue_str($('p1A10'));
Does not reference the control correctly - How should I do this?
There's two things wrong with your code.
First, $('p1A10') references nothing.
jQuery selectors work almost identically (if not completely identically) to the way css works.
So, just ask yourself how you would reference the object(s) in question in CSS and you're half way there.
I'm assuming that p1A10 is the name or id of an object. Since we're using CSS/jQuery syntax, this should be an id, although you can select by other attributes such as $("select[name='p1A10']") .
To reference an object by ID we use the # character (again, just like in CSS). So we can select your node via $('#p1A10').
The second problem is that your function is expecting a DOM object not a jQuery object. To keep your code intact, we need to say $('#p1A10')[0] where 0 is the first element within the collection of jQuery elements.
I've provided two examples to explain this a little better. One uses your existing infrastructure and one replaces it.
http://jsfiddle.net/TD6Uu/5/
Hope it helps.
Given a form with id formc and a select with name p1A10 you could e.g. use:
o.p1A10 = eegetdropdownvalue_str($('#formc select[name="p1A10"]').get(0));
If this doesn't do it, please provide use with the exact HTML structure
I have recently been using the title tag in various HTML elements to store data in JSON format in the DOM.
Is this a bad approach (I am assuming it is)? What is the correct way to accomplish this that works well with jQuery? By "works well" I mean
$("myButton").click(function (e) {
var myData;
eval("myData=" + $(this).attr("title"));
});
Works pretty well but again I am assuming there is a better way to do this no?
PS: BTW how does the title tag of HTML elements actually work? I cant seem to find where it actually ends up getting used?
PSS: Can I also get a jQuery based and Non jQuery response? (Sorry to be fussy)
eval("myData=" + $(this).attr("title"));
This is almost a legal reason to slap you! (j/k)
You should use your own namespace object to store data "globally". In that context, globally means only global in your application code and not using the global object (window in a browser).
var my_application = {};
$('myButton').click(function() {
my_application.myData = $(this).attr('title');
});
This is a very basic strategy of course. In your particular case, you can also use jQuery's .data() method to attach data to a DOM node.
$('myButton').click(function() {
$.data(this, 'myData', this.title);
});
Ref.: .data(), jQuery.data()
In your example, I'd suggest doing the following which does not expose you to the security risks of 'eval':
myData = JSON.decode($(this).attr("title"));
In general it's a valid approach to holding non-secure data. You have a number of other options too:
Use JQuery's .data() methods:
myData = $this.data("foo");
In HTML5 you now can use custom data attributes (Eg "") as an attribute on any element. http://html5doctor.com/html5-custom-data-attributes/
You could use Local Storage if you know it is available. http://dev.w3.org/html5/webstorage/
You could use Backbone.js on top of Jquery to give you a more abstracted way of handling your data as Models. http://documentcloud.github.com/backbone/
use jquery data()
The jQuery.data() method allows us to
attach data of any type to DOM
elements in a way that is safe from
circular references and therefore free
from memory leaks. jQuery ensures that
the data is removed when DOM elements
are removed via jQuery methods, and
when the user leaves the page. We can
set several distinct values for a
single element and retrieve them
later:
jQuery.data(document.body, 'foo', 52);
In the jQuery world it is usually said to be a best practice to use the metadata plugin as it is an official jQuery plugin and also supports HTML5 data attributes. For more info you could look at this http://docs.jquery.com/Plugins/Metadata/metadata
In this link: http://css-tricks.com/snippets/jquery/jquery-plugin-template/ it has a line of code that says
// Add a reverse reference to the DOM object
base.$el.data("yourPluginName", base);
what does the "reverse reference to the DOM object" mean?
Assuming that you know the jQuery data function:
It's storing a reference to the instance of the class in the data cache of jQuery, meaning that the stored instance can be used to access the initial base object if it in the current context is not available.
This way, the class instance can be used later. However, the use of the prototype keyword upon the initial class that the instance were created from will modify the instance.
EDIT:
Ooops, it seems that Anurag is right, and I was giving wrong information.
Sorry, the information I gave in initial answer was not completely correct. I've updated the answer, so it now tells the truth.
In the comments you're asking:
so you mean its storing the current state of "base" in the data cache but if we make changes to "base" later on then the one in the data wont be affected? so if for some reason we needed to get the original one again we can do data('yourPluginName') to retrieve it? can you give me an example of when this would be helpful?
It seems that none of the statements are correct.
As I did obviously not remember adequately, the thing stored in data is only a reference to the object:
var obj = {};
obj.hello = "Hello";
$("#someElement").data("object", obj);
obj.world = " world.";
alert(
obj.hello +
$("#someElement").data("object").world
); // alerts "Hello world."
BTW, JavaScript variables with names like this base-thing (but, more often seen as that or similar) are typically used to represent the current context, accessed through the this keyword, which on many occasions is more easy to store in another variable due to scoping/context changes, that will make the current context and therefore this, change.
Also due to issues with context, the stored value in data could be used to access the specific object instance from another context (that is, when this represents something else), instead of the version of the base object that was continually used after a copy of it was stored.
I hope this answered you questions :D
The technique and the problem it solves is general and not specific to jQuery plugins. There may be cases where a Javascript object corresponds to a DOM element, and wraps logic specific to that DOM element. This object might be interested in listening to events such as clicks that happen within that DOM element. The information we get in those callbacks is the element that triggered it, and not the associated object. You could use jQuery's data API or any type of map in general to retrieve the corresponding object, and do something with it.