In this and the next few posts I want to bring up a few of the more obscure features of APIs of WinJS and give a little more explanation about them, or at least just make you aware that they exist!
The first ones in these posts are simple wrappers around a few common DOM operations.
WinJS.Utilities.QueryCollection is a class that wraps an element.querySelectorAll or document.querySelectorAll with a number of useful methods. An instance of this class is created by calling WinJS.Utilities.query(<query>[, ]) where <query> is a usual DOM query string and the optional <element> scopes the query. That is, if you provide <element>, the instance wraps element.querySelectorAll(<query>); if you omit <element>, the instance uses document.querySelectorAll(<query>). Similarly, WinJS.Utilities.id(<id>) does a document.getElementById(<id>), then passes the result to new WinJS.Utilities.QueryCollection. WinJS.Utilities.children creates a QueryCollection that contains children of a specified element.
Anyway, once you have a QueryCollection instance, it provides methods to work with its collection, that is, with the results of the DOM query that in and of itself is just an array. As such, you’d normally be writing plenty of loops and iterators to work with the items in the array, and that’s exactly what QueryCollection provides as a convenience. It follows along with other parts of WinJS, which are utilities that most developers end up writing anyway, so it might as well be in a library!
We can see this in what the individual methods do:
- forEach: calls Array.prototype.forEach.apply on the collection using the given callback function and this argument.
- get: returns  from the array
- setAttribute: iterates the collection and calls setAttribute for each item.
- getAttribute: gets an attribute for the first item in the collection.
- addClass, hasClass, removeClass, toggleClass: iterates the collection and calls WinJS.Utilities.addClass, hasClass, removeClass, or toggleClass for each item, respectively.
- listen, removeEventListener: iterates the collection calling addEventListener or removeEventListener for each item
- setStyle, clearStyle: iterates the collection setting a given style to a value or “”, respectively.
- include: adds other items to this collection. The items can be in an array, a document fragment (DOM node), or a single item.
- query: executes a querySelectorAll on each item in the collection and calls include for each set of results. This could be used, for instance, to extract specific children of the items in the collection and add them to the collection.
- control: given the name of a control constructor (a function) and an options object (as WinJS controls typically use), creates an instance of that control and attaches it to each item in the collection. It’s allowable to call this method with just an options object as the first argument, in which case the method calls WinJS.UI.process on each item in the collection followed by WinJS.UI.setOptions for each control therein. This allows the collection to basically contain elements that have WinJS control declarations (data-win-control attributes) that have not yet been instantiated.
- template: renders a template element that is bound to the given data and parented to the elements included in the collection. If the collection contains multiple elements, the template is rendered multiple times, once at each element per item of data passed.
As for WinJS.Utilities.addClass, WinJS.Utilities.removeClass, WinJS.Utilities.hasClass, and WinJS.Utilities.toggleClass, as used above, these are helper functions that simply add one or more classes (space delimited) to an element, removes a single class from an element, checks if an element has a class, and adds or removes a class from an element depending on whether it’s already applied. While these operations sound simple, the implementation is actually quite non-trivial. Take a look at the WinJS source code (in base.js) to see what I mean! Good code that you don’t have to write.