Re: [whatwg/dom] Add convenient, ergonomic, performant API for sorting siblings (#586)

To clarify, @domenic, you're suggesting that the accessor function/attribute would need to return an integer index? Or at least numeric? (That seems more useful than string comparison, which is what I was thinking was meant by using an attribute value.)

With a numeric key, an author could map the child elements to an array, sort that with custom JS comparators, and then save the resulting array indices on the elements.  Which is no worse, from an authoring perspective, than any existing options for sorting elements. Although it does mean that the sorting is happening twice: once in JS, to generate the index values, and then once in the DOM method, to sort the actual elements by the indices. But for a table-sorting use case, where data in the table isn't changing, you would only need to calculate the sort order for each key once.

Could the method be overloaded, so that if the sort key parameter is a function, it gets called for each element, otherwise it's used as the name of an attribute to parse? Or is that too much of a JS thing for a DOM API?

What about the idea of taking a list of different keys, for tie-breaker values (so that, for static content like a data table, you could calculate out the sort order for each key separately, and store in different element attributes/properties)?  And/or having an easy built-in way to reverse the sort order? 

____________________________________

Per @AnneVK's question, What Would JS Libraries Do?

- [D3's selection.sort](https://github.com/d3/d3-selection/blob/master/README.md#selection_sort) takes a generic comparator function, although the comparator function runs on the bound data objects rather than the elements themselves.  (D3 also includes [ready to use ascending/descending comparators](https://github.com/d3/d3-array/blob/master/README.md#ascending) for simple data types.)

- JQuery doesn't have a built in method of sorting selections, nor any official plug-ins. Most examples I found just use JS array sort & then re-insert the elements into their parent container one at a time.

- [This utility library, TinySort](http://tinysort.sjeiti.com/) (which came up when searching for JQuery plug-ins, although it's dependency free) is interesting because it doesn't require the author to specify comparator functions. Instead, it takes complex customization objects describing which value to use for comparing (including an optional selector to select a child element from each element in the list, before extracting an attribute or text content or certain other properties).  The number of options would probably make it overly complex for a DOM API, though.

- Angular has an [`orderBy` directive](https://docs.angularjs.org/api/ng/filter/orderBy) for `ngRepeat` components. It takes the name of a data property (you're sorting the array of data objects used to fill out the template, not the final elements) _or_ an accessor function _or_ an array of names/functions. By default, it sorts according to data type (e.g., numeric vs string), but you can also set a custom comparator function.  I don't know if it reorders existing elements on update or if it keeps the elements in order & modifies their content to match the new data (probably the second).

- Vue.js requires you to sort your data array before updating a list of components defined by a [`v-for` directive](https://vuejs.org/v2/guide/list.html), _but_ it allows you to specify a key for matching existing elements with data, forcing a true DOM re-order instead of modifying elements in place.

- React doesn't seem to have any standard built-in approach to sorting a list of components; lots of different examples/plug-ins come up in a search. I suspect they're all using JS array sorting somewhere under the hood.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/586#issuecomment-371701772

Received on Friday, 9 March 2018 03:24:02 UTC