The Semantic Zoom control in WinJS, as you probably know, is basically a control that provides a switching effect between two other controls. Any control that implements the IZoomable interface will work, though in WinJS the only two that do this are the ListView and the Hub. (Implementing the interface is not difficult, though; refer to the HTML SemanticZoom for custom controls sample in the SDK.)

When hosting ListView controls (the most common case), the question can arise about how to size and position the zoomed out view, primarily because the ListView is hosted inside the SemanticZoom control, which sets the position of the ListView itself.

The trick in this case is to have the SemanticZoom control sized to 100% of the desired space, and then use the margins of the .win-surface style on the ListView. The SemanticZoom will honor those margins in its positioning work. Be sure, also, to adjust the height of the .win-surface style as well to prevent scrollbars from appearing when you set the margins.

 


In Windows 8 and WinJS 1.0 it was exceedingly difficult (though not impossible) to create a custom layout object for the WinJS ListView control. As such it was one area of WinJS that I never investigated!

What made it difficult was that the ListView worked entirely on absolute CSS positioning, which meant that the location of every item had to be individually calculated within the layout object’s code. This also caused various performance issues as well.

For WinJS 2.0 on Windows 8.1, the WinJS team rewrote the layout engine of the ListView to leverage relative positioning such that it could let the app host’s layout engine do most of the work. This both improved performance and made it orders of magnitude more easy to write a custom layout. In fact, the simplest layout object hardly needs to do anything at all, because the default behavior (via flexbox with block elements) produces a simple vertical layout just like you get when throwing a bunch of div’s into an HTML page.

From there you can start to build out other behaviors you want:

  • Non-vertical layouts
  • Virtualization support
  • Keyboard support
  • Drag and drop general visual indicators
  • Drag and drop reordering and positional indicators
  • Animations

To explore all the details, I have 17 pages in Appendix B, “WinJS Extras” in my free ebook’s second edition (preview), which includes a minimal vertical layout, a minimal horizontal layout, two dimensional layouts, and non-linear layouts. For the latter I borrowed some code from Mike Mastrangelo of the WinJS team that was used in a short demo at //build 2013. The appendix also includes a short video demonstration of this.

B-3 (circle layout)


One of the areas that has seen the most change between Windows 8 and Windows 8.1 is the WinJS ListView control. The whole control was basically overhauled from its WinJS 1.0 incarnation. It’s WinJS 2.0 version is much more performant, supports drag and drop, used CSS grid/flexbox for layout rather than absolute positioning, supports more built-in layouts, makes it easy to write custom layouts, and improves keyboard support.

In writing the chapter on collection controls for the second edition of Programming Windows Store Apps with HTML, CSS, and JavaScript, I didn’t want to burden the chapter with describing all the changes–I made the decision early on that the book would really present the state of the platform in Windows 8.1 and talk very little about changes or migration. A blog is better for that!

Toward that end, this post is summarizes all the changes that are documented or that I’ve encountered in writing the book chapter.

First of all, here’s the list of ListView 1.0 features that are deprecated in ListView 2.0, and what replaces them:

  • Incremental loading properties. Incremental loading is handled either through the data source or the item rendering function. The new HTML ListView incremental loading behavior sample (http://code.msdn.microsoft.com/windowsapps/ListView-loading-behaviors-718a4673) shows how, by adding more items to the Binding.List in the item renderer.
    • loadingBehavior=’incremental’
    • automaticallyLoadPages
    • loadMorePages
    • pagesToLoad
  • Backdrops were a feature added late for ListView 1.0 as a band-aid for its performance on ARM devices. Given that ListView 2.0 performs so much better, this feature is often no longer needed, but even so, it’s handled through CSS now. So the following properties are obsolete in favor of the win-backdrop CSS selector in WinJS 2.0:
    • ListLayout: backdropColor, disableBackdrop
    • GridLayout: backdropColor, disableBackdrop
  • The GridLayout’s new orientation property obsoletes its earlier horizontal property. A GridLayout supports both vertical and horizontal orientations.
  • The ListLayout’s vertical property is obsolete in favor of the orientation property, which supports both vertical and horizontal.
  • Cell spanning happens how through the CellSpanningLayout class, obsoleting the GridLayout’s earlier cell-spanning features:
    • itemInfo, groupInfo, and maxRows. In the CellSpanningLayout you’ll find itemInfo, groupInfo, and maximumRowsOrColumns.
  • The ListView’s resetItem and resetGroupHeader methods are deprecated because the control no longer recycles items. In WinJS 1.0, as a performance optimization, a rendering function could receive a second parameter that was an already-created item element tree, in which you’d replace the data. These properties let you centralize the cleanout process, but as recycling is no longer used, these methods do nothing.
  • The earlier IListLayout and related interfaces for custom layouts, which were really never documents, are obsolete. Layout has been overhauled from an absolute positioning model (which introduced many performance issues) to one based on pure CSS. As a result, the custom layout model for WinJS 2.0 is much simpler, using the IListLayout2 and related interface. The HTML ListView custom layout sample shows this (http://code.msdn.microsoft.com/windowsapps/HTML-ListView-custom-9676a187).

It’s good to note that WinJS.Binding.Template controls are compiled by default in WinJS 2.0. If you find a problem with that, the Template object has an option called disableOptimizedProcessing that, when set to true, will impose the WinJS 1.0 interpreted template model.

Other changes to the ListView for WinJS 2.0 introduce new features and capabilities:

  • Invocable headers: groupHeaderTapBehavior and headerInvoked properties.
  • Drag and drop: itemDrag* events, itemsDraggable, itemsReorderable properties.
  • ListView uses maxDeferredItemCleanup property instead of 1000 as the default.
  • ListView implements the WinJS standard dispose pattern and triggerDispose
  • CSS-based layout, which enables easier custom layouts, improves performance quite a bit.

 



I received this reader comment for a note on page 210 of my book:

On page 210 you mention, “…I’m building most of the element by using the root div.innerHTML property instead of calling create element and appendChild and setting individual properties explicitly. Except for very simply structures, setting innerHTML on the root element is more efficient because we minimize the number of DOM API calls.” This sounded a little strange to me so I ran some tests in IE10 desktop mode since Win8 Apps run on IE and I found the opposite seemed to be true. Performing an equivalent operation using innerHTML and the createElement/appendChild, I found on my own computer that for IE10 innerHTML took almost 60 times as long. Am I missing something?

The reader also shared the test code, which looped through some test functions using both the DOM API and innerHTML assignments, which indeed showed a clear advantage of teh DOM API over innerHTML. What made the difference, however, was that the tests were making additions to innerHTML using += rather than straight assignments using =.

Here’s what I wrote for the response (edited a little)

This note about optimization is aimed specifically at rendering an item in a ListView, where the rendering function as a whole might be called thousands of times over, each time building up a specificc DOM structure for that item. As such, we want to minimize the execution time of that particular function.

In your test, the timing differences you’re seeing are entirely due to the fact that you’re using element.innerHTML += rather than just element.innerHTML =. The effect of this is that there is that the whole of innerHTML is reparsed each time through your loop, because the code keeps adding to the overall string. This is entirely the reason for the apparently slow performance. If, on the other hand, you simply do an assignment (=) with a string that contains around three to four elements, you’ll find that innerHTML performs faster than the equivalent series of createElement/appendChild calls.

The simple reason for this is that in that one assignment to innerHTML you’re having a piece of highly-optimized C++ code parse the string and effectively make the same createElement/appendChild calls internally as you’d make from JavaScript. For just a few elements, the difference is hardly noticeable. However, once you get above about 4 element—as our performance testing has shown—those extra round trips between the JS engine and the DOM API start to add up and become significant. For instance, if you’re building up a ListView item with, say, 20 items, we’ve definitely seen that building up a string and making a single assignment to innerHTML performs much better than lots of distinct calls from JavaScript.

Be clear, again, that you want to make a single assignment to innerHTML rather than doing a bunch of += assignments, as the latter will, as you’ve found, perform slower. I’ll make sure to clarify this in the next rev of the book and on my blog (as I’m doing here).

Again, the optimization here is primarily aimed at ListView item rendering. For building up DOM dynamically (e.g. trying to render a complex page), then using the DOM API is better than repeatedly making innerHTML += calls.


Though my primary focus is on Windows Store apps written in HTML, CSS, and JavaScript, I do see plenty of C#/XAML material cross my inbox. In this case, there’s a helpful template available in the Visual Studio Code Gallery that closes the gap between the HTML/CSS and XAML presentation layers, namely doing variable-sized items in a collection control, otherwise known as cell-spanning. This is built into the WinJS ListView control but takes a little more work in a XAML GridView.

The template found on http://visualstudiogallery.msdn.microsoft.com/da65cc08-c4bf-4824-b483-9c8f53fb063c?SRC=Home helps close that gap. To quote the description: “VariableGridView is a subclass of GridView that supports variable sized children. When using the template, there should be no need to modify this class.”

 


Recently I was scribbling out some for a ListView control and wrote out a WinJS.Binding.Template in default.html. I misspelled data-win-control, leaving off the ‘l’ at the end:

<div id=”entryTemplate” data-win-contro=”WinJS.Binding.Template”>

The result of this was a curious exception way down in WinJS: (for the benefit of search engines, the error text is “Exception is about to be caught by JavaScript library code at line 20074, column 9 in ms-appx://microsoft.winjs.1.0/js/ui.js … 0x800a138f – JavaScript runtime error: Object expected”)

Spelling data-win-control correctly fixed the problem, but I wanted to make a note of what caused this error with a WinJS.Binding.Template. Basically because I’d misspelled the attribute name, a template control never got created, thus the non-existent object.