Skip to content
This repository

datalist polyfills review #18

Closed
aFarkas opened this Issue December 31, 2011 · 2 comments

3 participants

Alexander Farkas Paul Irish Chris Coyier
Alexander Farkas

This is a short review of the current recommended datalist polyfill's. I think, those issues has to be fixed, before these scripts should be recommended.

ping @chriscoyier and @miketaylr

Additionally, I have created 3 fiddles (those two polyfills + webshims implementation) , to simply test those implementations (http://jsfiddle.net/trixta/3Yu9X/).

feature detection:

rd's implementation:

The main code of rd's implementation has no feature detection. Instead the demos are using the following feature detection:

if (!Modernizr.input.list || (parseInt($.browser.version) > 400))

While there is no problem using browser sniffing against past versions, it's not possible to sniff against future versions. This code breaks as soon as webkit has implemented the datalist element!!!

Use the following featuredetection:

if (!Modernizr.input.list || !('HTMLDataListElement' in window))

To foolproof the script. The script itself has to use feature detection, so that a developer does not has to wrap his code invocation...

Note: This detection will be fixed with next Modernizr update.

options removed (X-browser???)

In HTML4 options are removed, if they are not a child of select or optgroup.

rd's demo

The demo does not use a select element and does not shiv the datalist-element. All options are removed, so that the demo doesn't even work with IE9. Please fix!!!!

mt's demo

This implementation adds a select element using conditional comments for IE. Due to the fact, that all older "HTML4-browser" remove option elements and not only IEs, it is recommended, that the demo should always wrap the options in a select element!!!

option parsing:

There are 4 ways to declare value/label of an option element:

<option value="option 1" />
<option>option 2</option>
<option value="option value 3">option label 3</option>
<option value="option value 4" label="option label 4" />

At least 1 and 4 has to be supported.

rd's implementation

rd's implementation supports only 1 and 2.

mt's implementation

Is dependent from browser. Only 4. option syntax can be used with similiar results in all browsers. Use $.fn.val to also support first option syntax in IE7.

datalist[-overlay] placement

rd's implementation

rd's implementation appends the list to the body and uses $.fn.position to calculate the position of the input element. This is wrong and fails in a lot of cases. This fails as soon as the input element has an offsetParent (position: relative!!!), which is not html / body.

To make this right, $.fn.offset has to be used.

mt's implementation

This implementation is extremley obtrusiv and also fails in many cases. mt's implementation wraps the input element and the generated list inside of a div with relative position to place the datalist. This fails, in many ways, because

  • it heavily modifys the structure of the document (selector do not match anymore or selectors which should not match start to match...)
  • it's not possible to use overflow: hidden, auto, scroll on an ancestor of input[list] anymore

Use same technique as rd's implementation, but use offset instead of position.

user interaction

mt's implementation

no keyboard interaction, no list filter, no support for long datalists

rd's implementation

  • keyboard interaction: select from list with enter submits form
  • select is on click, but should be on left mousedown
  • list disappears, if user wants to scroll with mouse in a long list

performance

mt's and rd's implementation [too much DOM operations]

Both implementations are creating one (rd) or three (mt) new elements per option. While rd's implementation should be fast enough in webkit, it's a really bad technique for creating a list of elements in IE7 and IE8. mt's implementation should be too slow in all browsers.

Instead of creating new elements per option. The implementations should create a string and let jQuery create the DOM at once using the fast DocumentFragment technique.

rd's implementation [event delegation]

use event delegation

mt's and rd's implementation [be lazy]

you don't see a list initially, only if a user interacts with the input, so be more lazy!

rd's implementation [resize event]

rd's implementation is realigning all datalists on the resize event even if the datalist isn't visible. The eventhandler doesn't use debouncing or throttling.

Chris Coyier

Thanks for the research!

Couple notes on "rd" (Relevant Dropdowns).

My intention is to leave feature detection using Modernizr. Modernizr has beefed up their detection for datalists (Modernizr.input.list) so that browser sniffing bit can be removed. (You were a part of that discussion: Modernizr/Modernizr#146)

For option parsing, I'm pretty sure Respnsive Dropdowns supports your #1, #3, and #4, but I just opened your demo of it in IE 7 and it supported #2 as well, so maybe it's just IE 6 that can't handle #2. I personally think that's a fine level of support.

For performance, Responsive Dropdowns uses the document fragment thing already. Maybe more can fit into the document fragment before adding?

There is a couple of other small things too like using offset and using mousedown. That's all fine with me, just shoot over a pull request and I'm happy to take a look and merge it.

Alexander Farkas

@chriscoyier

No, problem. I think, rd datalist could be a really good markup polyfill.

About the parsing problem.

In fact, it renders all examples, but in case of 3 and 4 the label (explicit/implicit) has to be shown to the user.

document fragement

Yes, I saw that you are using this technique. But I mean the following line, wich means, that you are creating one li-dom-object per option. If you would concat those li's to a string including the parent ul and simply use jQuery to create the DOM. jQuery would use one DOM-operation to create all li-elements at once.

Paul Irish paulirish closed this in 4094e9f January 22, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.