As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
This question is about conventions.
Let's say I have an object Basket that store various items in some private property (Basket._items). Now, I want to have a couple of methods for adding, removing and getting items.
Each method can take either a single item or a list of items as an argument, or with no arguments, in the case of removing and getting, may remove or return all items.
How should I name my methods?
addItem or addItems
removeItem or removeItems
getItem or getItems
(They don't all have to be the same form; for instance, maybe only the last one should be plural.)
EDIT: Generic names like add and get don't fly since semantically I'm not adding or getting Baskets; also the object is used to hold other stuff as well. I'd consider using something like Basket.items.add(), but it's not optimal since the actual item objects also has to be stored and Basket.items._items or Basket.items._contents look bad. I'd still like to get more answers on my original question.
First guideline is to use conventions that match code you've already written for the project in question.
Second guideline is to choose names that make the best intuitive sense for the most common use of the method. If the default/common/no-parameter use is to retrieve a single item, then go with the singular name instead of plural.
Third guideline is to match the other code conventions you're already using in third-party libraries. For example, if you know that people using your library are using jQuery, then their conventions might be good to follow.
Since Javascript is such a dynamic language, it is typical to be 'lazy' in your method signatures. So you could use:
Basket.addItem(n); // add a single item
Basket.addItem([n, m]); // add multiple items
Basket.getItem(); // retrieve a single item
Basket.getItem(5); // retrieve an array of up to 5 items
Basket.removeItem(); // remove a single item
Basket.removeItem(2); // remove up to two items
Basket.emptyItems(); // remove them all
Unless you're already using add(), get(), remove(), of course.
If the argument is a list (array), then it's obvious that you are adding several elements. If the argument is a single instance of the element you are adding, the same thought applies.
add( Array elements):
foreach element e
_items[lastindex] = e
add( Element element):
_item[lastindex]= e
That is my opinion. For reference you have:
Java List interface
and
Java coding conventions
Different languages have different conventions, but the conventions outlined here are generally sane for other languages too (although, it doesn't quite answer your question).
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
There are countless articles on writing clean HTML/CSS.
What I haven't found though is advice on organising class names and IDs that are used for different purposes (design vs jQuery vs Selenium testing).
For any given class name and ID, it's difficult to tell what it's being used for. In 2+ person teams, there also seems to be a tendency to keep adding more and more IDs and classes, and avoiding cleaning up those that are already there, in fear of breaking things.
Are there patterns, conventions, tools, or pearls of wisdom that would help?
I have not come across any tools to help with this situation. But I have used the conventions below with moderate success. None of them are an exact science though.
Regarding IDs:
Because IDs are the faster lookup, I tend to use them whenever I'm wanting to address a specific part of my HTML, regardless of how I'm using it (styling/jQuery/testing/etc).
However, because each element can only have a single ID, there's not really an opportunity to use a naming convention or style for different uses. And I have found that if I've wanted to address an element for one reason, there's a good chance I'll want it again for a different reason.
For example: if I have a button on a page and find it using jQuery (by ID) to attach an event handler, then chances are I'll also want to find that button to test its behaviour.
So because an ID can be used for multiple reasons, it should be named in a general way, ideally describing what the element is or represents, rather than how it will be used. It should then make sense however it is used.
But as you say, for a given ID
it's difficult to tell what it's being used for
I agree, and generally don't try to find out unless I have to. Other team members can't add additional IDs to an element that already has one, and should be encouraged to re-use an existing ID if it fits their purpose.
Using this approach, existing IDs should not be updated or removed, and become a permanent feature of the HTML. (But like any rule, it can be broken if need be and the risk is worth it)
This way everyone should be comfortable to reuse existing IDs without having their code being broken by someone else changing them, and the ID names should make sense for all uses. This should lead to not having too many "extra" IDs.
Regarding Classes:
In 2+ person teams, there also seems to be a tendency to keep adding more and more ... and avoiding cleaning up those that are already there, in fear of breaking things.
My experiences match yours; people tend to add a new class rather than reuse an existing one. This can also sometimes lead to developers being more comfortable to remove a class if they think they've deleted the only code that used it. This in turn bites anyone who did reuse the class, and they think "next time I'll just add my own new class to be safe". A good example of a vicious cycle.
I try to treat classes in the same way as IDs (described above) and:
Use non-use-specific names
Reuse an existing class if there's one already there that "makes sense" by its name
Discourage changing or removing existing classes (to increase confidence with reuse)
With additional thought, an exception could be made for classes added for only "external" reasons, such as testing, by having classes with a common prefix such as "tst". I would consider this approach if the use:
Will create a large number of classes (noise)
Is expected to be changed a lot (as the usage is bedded down)
Expected to possibly be replaced in future with a difference approach
Is controlled by an external group to the development team
But using any kind of naming convention is only as good as the people who follow it (or don't). Testing is really the only way to know if something has been broken when there isn't a compiler to tell you that there's a bad reference hanging around.
tldr;
So, in general I don't try to organise my IDs and Classes by how they are used, and I try to maximise their reuse and minimise their changes. But I have an open mind if more compelling answers are given to this question!
I would say: classes (and targeting HTML elements directly or in combination) for styling, id's for behaviour (and Selenium), "do not repeat yourself/others" thinking - cascading styles, and that is about it.
If everyone follows this concept - common goal to keep clean code is achieved but at the same time it can also mean more problems - for example multiple event delegations (not using "proper" object oriented concepts) and CSS class chains on same element can cause even less readability and more time to handle.
So - actually it is very hard to have a general rule - especially if people have different views and code-styles. But I still think - classes for styling and id's for behaviour applies...
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
When using JavaScript in the web browser is there any performance difference between the following:
Existing getElementById
document.getElementById("elem");
Query Selector using #id
document.querySelector("#elem");
Query Selector using [id=elem]
document.querySelector("[id=elem]");
I'm assuming the first one will be fastest (only has to lookup elements with an ID). Also the final one looks like bad practice. I like the second one as using querySelector for everything makes the code easy to read.
Any suggestions?
Firstly,
document.querySelector("#elem");
Has an advantage in the fact that, unlike document.getElementId, it can return classes. However, the usefulness of this is far diminished by the fact that it only returns the first object with that class name, so you might as well just use an id if you're not specifically looking for the first object with that classname. if you use,
document.querySelectorAll
However, I believe (I may be wrong), it returns all items with that classname as an array, where regular querySelector is equivalent to querySelectorAll[0]. One more advantage, is that you can run css3 queries through it, which can be quite useful.
Secondly,
document.getElementById("elem");
Has a very good advantage over queryselector in the sense that it is almost 5 times faster, so if you're sitting there with several thousand lines of code and you want to optimise said code, then getElementById is the way to go.
Lastly,
document.querySelector("[id=elem]");
I, personally, don't see the need to use this in any situation. If you needed a querySelector, why not just use a # ? This is exactly equivalent to your first example of querySelector, however it has a lot of useless charaters.
Edit: Just to be clear, in summary, you're probably better off using document.getElementById.
You can test it yourself. getElementById is a fastest method
is there any performance difference
Probably, since they are different functions. querySelector at least needs to parse the selector before detecting that it's equal to getElementById. And I doubt this optimisation takes place for the attribute selector at all, no one uses it. So I share your assumptions; and tests confirm them (thanks to #Silver_Clash).
Personally I do not like the second one, as it is more ambiguous and awful to use with dynamic id values. Explicitly using getElementById is just more concise.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
We are in need of a DOM parser, that will be able to run a bunch of patterns and would store the results. For this we are looking for libraries that are open and we can start on,
able to select elements by regexp (for example grab all elements that contain "price" either in class, id, other attributes like meta attributes),
should have a lot of helpers like: remove comments, iframes, etc
and be pretty fast.
can be run from browser extensions.
Ok, I'll say it :
You can use jQuery.
ups :
it is a very good dom parser
it is very good at manipulating the dom (removing/adding/editing elements)
it has a great and intuitive api
it has a big & great community => lots of answers to any jquery related question
it works in browser extensions (tested it myself in chrome and it apparently works in ff extensions too : How to use jQuery in Firefox Extension)
it is lightweight (About 31KB in size - minified and gzipped)
it is cross-browser
it is definitely open source
downs :
it doesn't rely on regex (although this is a very good thing - as dda already mentioned), but regex can be used to filter the elements
dont know if it can access/manipulate comments
Here's an example of some jquery action :
// select all the iframe elements with the class advertisement
// that have the word "porn" in their src attribute
$('iframe.advertisement[src*=porn]')
// filter the ones that contains the word "poney" in their title
// with the help of a regex
.filter(function(){
return /poney/gi.test((this.title || this.document.title).test()));
})
// and remove them
.remove()
// return to the whole match
.end()
// filter them again, this time
// affect only the big ones
.filter(function(){
return $(this).width() > 100 && $(this).height() > 100;
})
// replace them with some html markup
.replaceWith('<img src="harmless_bunnies_and_kitties.jpg" />');
node-htmlparser can parse HTML, provides a DOM with a number of utils (also supports filtering by functions) and can be run in any context (even in WebWorkers).
I forked it a while back, improved it for better speed and got some insane results (read: even faster than native libexpat bindings).
Nevertheless, I would advice you to use the original version, as it supports browsers out-of-the-box (my fork can be run in browsers using browserify, which adds some overhead).
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Can someone think of an actual use case whereby we will ever require the use of getAttributeNode and/or getAttributeNodeNS?
As far as I know, getAttribute and/or getAttributeNS settles all use cases, hence this question.
It lets you obtain the item as a Node, which is an interface shared by other DOM components like elements, processing instructions, comments, etc., so you could treat it similarly to other items. Not sure why, but u could... :)
For example:
<button id="choose_attr">choose attribute node</button>
<button id="choose_text">choose text node</button>
<button id="getchosennodevalue">get chosen node's value</button>
<script>
var chosenNode;
document.getElementById('choose_attr').addEventListener('click', function (e) {
chosenNode = e.target.getAttributeNode('id'); // Attribute node
}, false);
document.getElementById('choose_text').addEventListener('click', function (e) {
chosenNode = e.target.firstChild; // Text node
}, false);
document.getElementById('getchosennodevalue').addEventListener('click', function () {
alert(chosenNode.nodeValue); // We can get the value with a shared property, no matter if it is a text node, comment node, element, attribute node, etc.
}, false);
</script>
Even if you will only use the variable for storing attribute nodes, one might prefer to have it already pre-built into a special object distinct from other types like strings.
Although your question was about getAttributeNode*, as far as the use of attribute nodes in general, I think it might be more handy with the likes of document.createAttribute where you can create and then pass around such a node to set it on an element later. But getting an existing attribute indeed seems of less general utility (though one could imagine a situation where you were passing around attribute nodes, sometimes created anew without an element, and sometimes retrieved from an existing element--using getAttributeNode allows you to avoid building your own object which has getters and setters and handle them with the same interface).
It's true there's rarely a reason to use getAttributeNode(). However, I've found it useful in the past as a workaround to Internet Explorer's getAttribute and setAttribute bugs. For instance, take the following HTML:
<div id="test" onclick="alert()">
and the following code:
var test = document.getElementById("test");
alert(typeof test.getAttribute("onclick"));
Internet Explorer 7 and lower will report function in the alert, unlike newer versions and other browsers which correctly report string. The workaround involves getAttributeNode():
alert(typeof test.getAttributeNode("onclick").nodeValue);
Correctly outputs string in all browsers, albeit at a small performance cost. The same problem applies to boolean and other non-string properties that can be set via attributes. Sure, this wouldn't be necessary if IE didn't have the bug, but it makes me thankful there's an alternative to getAttribute().
I've set up an example for you to test and play around with — http://jsfiddle.net/PVjn5/. There's also a ticket I filed over at jQuery.com about it.
You'd use them in a situation where you needed to encapsulate the attribute name and value (and namespace, if applicable) in a single object. Use cases for doing this when manipulating a HTML user interface via JavaScript are likely to be rare. However, browsers implement the DOM specification and those methods must be provided to meet the spec. The are plenty of use cases for the DOM when it is not being used to manipulate HTML-based user interfaces.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have often heard that jQuery has made some poor API decisions. Although jQuery is not my favourite library it's the library I've used most often and I find it hard to point out specific mistakes in the API design or how it could have been improved.
What parts of jQuery's API could have been done better, how could it have been implemented different and why would that different implementation be better?
The question extends to both low level individual details of the API and high level details of the API. We are only talking about flaws in the API rather then flaws in the high level design / purpose of the library, jQuery is still a DOM manipulation library centred around a selector engine.
Because of the necessity of API freezing in popular libraries, jQuery is stuck in it's current state and the developers are doing a great job. As can be seen by the recent .attr vs .prop change the developers do not have the flexibility to change any of their design decisions (which is a shame!).
One specific example I can think of would be
$.each(function(key, val) { })
vs
$.grep(function(val, key) { })
which is confusing enough that I have to double check what the parameters are frequently.
Please do not compare the jQuery library to full fledged frameworks like dojo and YUI and complain about lack of features.
.load() is overloaded with entirely different behavior depending on the arguments passed
.toggle() is overloaded with entirely different behavior depending on the arguments passed
too much overloading of the jQuery() function perhaps.
the .attr() you mentioned. The distinction from properties should have been immediate IMO.
.map( key,val ) but $.map( val,key ), and the this values are different.
non-standard selectors ought to have been kept out of Sizzle IMO. Javascript based selector engines should become obsolete in a number of years, and people hooked on the proprietary selectors will have a more difficult transition
poor method naming of methods like .closest() or .live(). What exactly do they do?
I recently discovered that you can't set the standard width and height attributes via the props argument when creating a new element. jQuery runs its own width and height methods instead. IMO, the spec attributes should have been given priority, especially since width and height can be set via css.
$('<img/>', {
css:{width:100, height:100},
width:100, // <-- calls method, why?
height:100, // <-- calls method, why?
});
$.get() and .get() are entirely different.
.get() and .toArray() are identical when passing no arguments
toArray() and $.makeArray() do effectively the same thing. Why didn't they give them the same name like .each() and $.each()?
two different event delegation methods. .delegate() the sensible one, and .live() the magical "wow, it just works!" one.
.index() is overloaded with 3 behaviors, but their differences can be confusing
// v---get index v---from collection (siblings is implied)
$('selector').index();
// v---from collection v---get index
$('selector').index(element);
// v---get index v---from collection
$('selector').index('selector');
The first one is understandable if you remember that it only operates on the first element
The second one makes the most sense since jQuery methods usually operate on an entire collection.
The third one is entirely confusing. The method gives no indication of which selector is the collection and which selector represents the element whose index you want from the collection.
Why not just eliminate the third one, and have people use the second one like this:
// v---from collection v---get index
$('selector').index( $('selector') );
This way it fits more closely with the rest of jQuery where .index() operates on the entire collection.
Or at least reverse the meaning of the selectors to fit in better:
// v---from collection v---get index
$('selector').index('selector');
Here's another to think about anyway.
I have some concerns with jQuery's event handling/data storage system. It is praised because it doesn't add functions to on[event] properties that can close around other elements, creating memory leaks in IE. Instead it places a lightweight expando property, which maps to an entry in jQuery.cache, which holds handlers and other data.
I believe it then attaches a handler with in turn invokes the handler that you assigned. Or something like that.
Whatever the system is doesn't really matter. The point is that the connection between the element(s) and the jQuery.cache is that expando.
Why is that a big deal? Well philosophically jQuery is not a framework; it is a library. It would seem that as a library you should be able to use or not use the jQuery functions without concern for negative effects. Yet if you go outside jQuery when removing elements from the DOM, you've orphaned any handlers and other data associated with those elements via the expando, creating a nice and fully cross-browser memory leak.
So for example, something as simple as el.innerHTML = '' could be very dangerous.
Couple this with the jQuery.noConflict() feature. This enables developers to use jQuery with other libraries that utilize the $ global namespace. Well what if one of those libraries deletes some elements? Same problem. I have a feeling that the developer that needs to use a library like Prototypejs along side jQuery probably doesn't know enough JavaScript to make good design decisions, and will be subject to such a problem as I've described.
In terms of improvements within the intended philosophy of the library, as far as I know, their philosophy is "Do more, write less" or something. I think they accomplish that very well. You can write some very concise yet expressive code that will do an enormous amount of work.
While this is very good, in a way I think of it as something of a negative. You can do so much, so easily, it is very easy for beginners to write some very bad code. It would be good I think if there was a "developer build" that logged warnings of misuse of the library.
A common example is running a selector in a loop. DOM selection is very easy to do, that it seems like you can just run a selector every time you need an element, even if you just ran that selector. An improvement I think would be for the jQuery() function to log repeated uses of a selector, and give a console note that a selector can be cached.
Because jQuery is so dominant, I think it would be good if they not only made it easy to be a JavaScript/DOM programmer, but also helped you be a better one.
The way jQuery handles collections vs single elements can be confusing.
Say if we were to update some css property on a collection of elements, we could write,
$('p').css('background-color', 'blue');
The setter will update the background color of all matching elements. The getter, however, assumes that you are only interested in retrieving the value of the first element.
$('p').css('background-color')
MooTools would return an array containing the background colors of each matching element, which seems more intuitive.
The naming conventions for jQuery promote conciseness instead of clarity. I like Apple's strategy in naming things:
It's better to be clear than brief.
And here's an example of a method name from a mutable array class (NSMutableArray) in Objective-C.
removeObjectAtIndex:(..)
It's not trying to be clever about what's getting removed or where it's getting removed from. All the information you need to know is contained in the name of the method. Contrast this with most of jQuery's methods like after and insertAfter.
If somebody can intuitively figure out what after or insertAfter does without reading the docs or the source code, then that person is a genius. Unfortunately, I'm not one - and to-date, I still have to go to the documentation to figure out what the hell gets placed where when using these two methods.
patrick dw hit most of the points in his (fantastic) answer. Just to add to his collection with a few other examples.
An API is supposed to be consistent; and jQuery succeeds in a lot of areas (being very consistent for returning a jQuery object/ get value, as expected in a lot of cases). In other situations however, it doesn't do so well.
Method Names
As already pointed out by patrick; closest() is a crap method name. prev(), and next() appear to most as if they do the job prevAll() and nextAll() actually provide.
delay() confuses a lot of people: In the following example, which do you expect to happen? (what actually happens?)
$('#foo').hide().delay(2000).slideDown().text('Hello!').delay(2000).hide();
Method Arguments
A lot of the tree traversal functions are inconsistent with what they accept; they all accept a mixture of selectors, jQuery objects and elements, but none are consistent; which is bad considering they all do similar jobs. Check out closest(), find(), siblings(), parents(), parent() and compare the differences!
Internally, the "core" of jQuery originally contained lots of intertwined methods, that the dev team have struggled to split up (and done really well to), over the past releases. Internal modules such as css, attributes, manipulation and traversing all used to be bundled in the same big package.
Included in jquery:
.post()
.get()
.getScript()
.getJSON()
.load()
Not in jQuery:
$.getXML();
$.headXML();
$.postXML();
$.putXML();
$.traceXML();
$.deleteXML();
$.connectXML();
$.getJSON();
$.headJSON();
$.postJSON();
$.putJSON();
$.traceJSON();
$.deleteJSON();
$.connectJSON();
$.headScript();
$.postScript();
$.putScript();
$.traceScript();
$.deleteScript();
$.connectScript();
$.getHTML();
$.headHTML();
$.postHTML();
$.putHTML();
$.traceHTML();
$.deleteHTML();
$.connectHTML();
$.getText();
$.headText();
$.postText();
$.putText();
$.traceText();
$.deleteText();
$.connectText();
$.head();
$.put();
$.trace();
$.delete();
$.connect();
Why does this bother me? Not because we don't have the above methods in the library, that's just dumb and I'd hate if we ever did (plus, most won't work with browsers), but what I hate is these short-hand methods all over the place: $.post(); Sends an ajax request via post.
Know what covers off everything in this list? The one function that isn't short-hand, $.ajax, it's full featured and covers off everything, you can even configure it to store defaults and in essence create all of these short-hands. You can create your own methods if you wish to call that call to ajax (which is what these all do).
Here's where it's really REALLY annoying.
Somebody writes all their code using shorthand:
$.getJSON(
'ajax/test.html',
function(data) {
$('.result').html(data);
}
);
Okay, oh wait, we want to change that to an XML feed we get from a post, also we need to make something happen before and after post. Oh, lets just switch to the non-short-hand method
$.ajax({
type: 'POST',
url: url,
data: data,
success: success
dataType: dataType
});
Oh wait, I can't just replace the word, the whole structure is all over the place.
This, and especially for things like $.load(), cross lines into why PHP has such a hated API, they're trying to do things they shouldn't do.
To extend this beyond AJAX calls, look at the animation portion. We have calls to slideUp, slideDown, fadeIn, fadeOut, fadeToggle, show, and hide. Why? Where's my slide left, slide right, slide in, slide out, teleport, and every other thing we can think up? Why not just stick to $.animate() and let someone write a plugin if we want those effects. Infact, someone did write a plugin, jQueryUI extends animations. This is just crazy, and leads to people not knowing that some effects create CSS rules on their divs that end up goofing up what they want to do later on.
Keep it pure, keep it simple.