I would like to replicate jQuery's addClass function using plain javascript
So far, I have made this function:
function addClass(el,cl){
el.className+=(el.className?' ':'')+cl
}
It works well, but It uses this syntax:
addClass(element,class)
I want it to use this syntax:
element.addClass(class)
How can I do that?
thanks :)
There is no perfectly safe way to make element.addClass() work for all elements when element is a DOM element (not your own object like a jQuery object) in all browsers. Some frameworks have done this in the past and they have run into enough problems that some are moving away from doing that. I would not recommend doing it this way.
You are not in the business of browser compatibility or framework creation (not do you want to be) so even though it seems cleaner to extend the DOM objects, I would not recommend it. jQuery and YUI do not do it this way. They make a wrapper object that contains both the method and the DOM element reference.
If you want to read of some of the perils, here's a good reference on the subject: What's wrong with Extending the DOM?.
You can make it a prototype to extend the Element class.
Element.prototype.addClass = function(cl) {
this.className+=(this.className?' ':'')+cl;
}
example
As minitech pointed out though, this won't work reliably in all browsers (namely IE).
Related
I want to set so many attributes for multiple elements. Javascript always give better performance when comparing to jquery.
i want to know which one gives better performance when settling multiple attributes via jquery and javascript.
Jquery multiple attribute setter:
$(element).attr({'id': 'id1', 'index':1, 'value':10,'check':'checked'});
using javascript setAttribute :
element.setAttribute('id','id1');
element.setAttribute('index','1');
..................................
when am using javascript i need to write multiple lines. otherwise need to create custom function for this.
can anyone explain which one gives better performance ? and why ?
Thanks,
Siva
Here is a jsperf which tests setting of attributes. I'm not sure that it covers your situation but as the others said - pure javascript is a lot faster then using a library. (I'm not even sure that the jsperf is a valid one. I mean if it test what you need).
http://jsperf.com/aaa-setting-attribute
jQuery version is 66% slower then the pure javascript variant.
Computers cost much less than programmers.
Let's say:
Using pure js will make code run for 1ms, and programmer work 3 hours.
Using jQuery will make code run for 2ms and programmer work 1 minute
See profit?
You should probably be setting properties, not attributes, as they are more consistent across browsers and have a more consistent effect on DOM elements (sometimes setting an attribute affects the property, sometimes it doesn't). Setting the property nearly always has the desired affect (e.g. setting a checkbox to checked), setting the related attribute doesn't always.
You can also use a small function if you want to set multiple properties on an element:
function setProperties(element, props) {
for (var prop in props) {
if (props.hasOwnProperty(prop)) {
element[prop] = props[prop];
}
}
}
I can't see that it would be any slower than jQuery.
jQuery is a library, so I think it better than pure javascript. It help you to use javascript easier. I supposed that!
You can see the same question here
If you want to get all of attributes of element, you can see here also.
I'm aware there are many ways you can do a DOM query inside a view:
$(view.el).find("#element");
$(“#element”, view.el);
view.$("#element");
Which one is the best way to go, and why?
Bakcbone keeps a reference to the the el of the view, so the last one will be the shorthand version of view.$el.find('#element');
view.$("#element"); /// is like I said is just the same that :
view.$el.find('#element');
I think this means the last one is the fastest as its only looking into the el and not in the entire DOM and still uses find.
take a look at this link. http://pivotallabs.com/shorthand-for-searching-a-view-s-dom-in-backbone/
Always use find over context selector.
" It’s true, where possible you should always try to run your selections based on a context however it’s useful just to bare in mind that when you’re passing a context to the jQuery constructor, it creates an extra unnecessary extra function call.
jQuery’s insides run content.find(selector) anyway, so you can technically skip that step if you’re working in a page structure that may not benefit greatly from using context. Below you can see an example of what I’m talking about. "
Source : 8 jQuery Performance & Optimization Tips You Need In 2010 (Tip #6)
Yes the article is old, but it is still true.
TL;DR version : Context selector call the .find() function. Using .find() directly reduce the number of call.
Hi I need Mootools for my chronoforms, prototype for my lightbox 2 (I think) and maybe also some jQuery in the future.
When I enable Mootools, lightbox 2 is not working in IE, when I disable it, lightbox works fine but I get errors on my page from my chronoforms form.
Is there a good and easy way to make sure you don't get any problems using all three together?
And something like JQuery.noConflict() is not an easy solution.
You cannot have MooTools and Prototype co-exist.
This is because they both change (extend) native host objects (Types) like Element (MooTools) and Array, Function, String, Number (both). You can't noConflict this for the life of you, each method can be defined once.
It's going to be pot luck when you reference "foo".contains('oo') and it goes to String.prototype.contains (for instance) if you get Prototype's, Mootools or ES5's implementations (MooTools 1.5.1+).
Time to reconsider what you use as you really should go to a single framework - they all can do what you need individually.
You can also have MooTools + jQuery or Prototype + jQuery, however
A jQuery best practices question.
I am writing a very jQuery intensive web page. I am new to jQuery and notice its power, but as I come with heavy javascript experience and knowledge, my question is: What should be done in jQuery and what in plain javascript.
For example, there are callbacks that send a plain DOM object as an argument. Should I use that or should I wrap it ( like $(this)).
Does it matter if I do this.x=y or $(this).attr("x", y).
If your function receives a DOM object and you don't need any jQuery functionality for that DOM object, then there is no need to make convert it to a jQuery object. For instance, if you receive a checkbox object, you can examine the checked property without any use of jQuery.
However, if you need to navigate to a different element from that checkbox, it might be worthwhile to convert it:
function yourCallback(cb) {
cb = $(cb);
var sel = $(cb).closest('td').next().find('select');
// For example, update the options in a neighboring select field
...
}
jQuery (as do other libraries) blend in smoothly with native JS. If you need extra functionality, augment the object in question.
As for your last question: You might find the data function useful to avoid nonstandard DOM attributes. If your property x in your question is in fact a valid DOM attribute, you can write either this.x = y or $(this).attr('x', y), IMO it does not matter much. However, if x is not a DOM attribute, use
$(this).data('key', value)
That way, you can store arbitrary key-value pairs with the DOM element, where value can be an arbitrary primitive value or object.
I think it's a judgement call. Use your common sense.
For instance, if you have 1000 div's on the page, you probably wouldn't want to wrap it inside $(..)
$('div').click(function() {
this.id = Random.guid(); // instead of $(this).attr('id', Random.guid());
});
As for other assignments, as long as you understand what jQuery is doing, you can stick with it just for consistency, but be aware of performance issues like in the above example.
As #colinmarc mentions, at times jQuery blurs the distinction between element attributes and object properties which can be misleading and buggy.
When your using jQuery, it always returns an instance of jQuery unless obv your using a function like val();
the reason we use $(this).value instead of this.value is to make sure that this is an instance of jQuery.
if somewhere in your code you set a variable called my_link witch is equal a DOM Object and not a jQuery function.. further in your application my_link.val() would result into an error, but by doing $(my_link).val() will assure you that the function val will be available. as $() returns an instance of jquery.
Sorry for the miss understanding in my previous post.
Since jQuery objects have richer functionality than nature JS DOM nodes, if you're on the fence, you might as well wrap in jQuery. JQuery is so lightweight, there's not really much reason not to use jQuery objects.
Does it matter if I do this.x=y or $(this).attr("x", y).
The native will be slightly faster, but you'll probably spend more time in other code-- DOM traversal or building. In this specific example, the former is more concise, so I'd choose that. Since jQuery is so lightweight, I tend to switch back and forth fluidly.
Here are other guidelines we follow:
For callbacks, like a click handler, you'll need to follow the API-- usually a DOM node. Code you write that is similar should probably just take DOM nodes as well. But if you have a list of items, always use a jQuery object.
For most code, I try to see if you can structure the code as a jQuery plugin-- applying some transformation to a set of DOM nodes. If you can do that, you'll gain some guidance from the plugin architecture.
I use jQuery's bind/trigger mechanism as it is quite flexible and low-coupling.
To keep code straight, I'd recommend name prefixing jQuery objects with a dollar sign. For example, var $this = $(this);. Although it's really no big deal to call $() excessively, it does end up looking a sloppy if you call it too much.
Hope this helps.
Following up on my question about jQuery.get() I was wondering if there is a list of DOM properties and methods that aren't available in jQuery that can only be accessible if you were working with the raw DOM object (i.e. $("#someID").get().scrollHeight; )
I haven't encountered a list but if one existed it would probably be quite lengthy. In addition to browser-specific (proprietary) properties there's a bunch of other less useful properties and methods not currently abstracted by jQuery. But then, I don't really see this as a problem, or even a valid point of discussion because jQuery IS JavaScript; if you need access to something beyond what jQuery provides then you can use get() or access a specified element within one of your "jQuery collections" like an array:
jQuery(elem)[0].someDOMProperty;
Plus jQuery provides absolutely no support for non-element nodes within the DOM. If, for whatever reason, you need direct access to comment nodes, text nodes etc. then you'll need to use the "raw" DOM.
I don't know of a compiled list of DOM operations/properties that are NOT available in jQuery (and a quick google search didn't turn anything up), but if you go to http://api.jquery.com/ you can see the entire API, and even download it as an Adobe AIR app in case you don't have internet when you need it.
No. JQuery is just JavaScript. If you can do it in JavaScript, you can do it in jQuery. Some properties and methods are overwritten in the context of a jQuery object and that's where you would want to us the get() method--to 'get' (i.e. access) the standard property/method.
That's really as complicated as it is.
Every attribute of every element is accessible through the attr() function. If you could do a document.getElementById() on that element and then access a property, you can also do it using the attr() function. However, some properties are accessed more easily in other ways when using jquery. For example, to see if an element is hidden or visible, you could do:
var isVisible=$("#el").is(":visible");
instead of using the attr() method. Similarly, you can find the selectedIndex of dropdowns and the text of the selected option, in easier ways than using the attr() method. This pdf outlines some of these easier approaches.
To access a css property, you are better off doing:
var fontWeight=$("#el").css("fontWeight");
rather than using get() or attr(). You can also set the css properties in this way, e.g:
$("#el").css("fontWeight","bold");
I could be wrong, but I think you can access any properties via the attr method.