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/).
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.
In HTML4 options are removed, if they are not a child of select or optgroup.
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!!!!
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!!!
There are 4 ways to declare value/label of an option element:
<option value="option 1" />
<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 supports only 1 and 2.
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.
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.
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
Use same technique as rd's implementation, but use offset instead of position.
no keyboard interaction, no list filter, no support for long datalists
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.
use event delegation
you don't see a list initially, only if a user interacts with the input, so be more lazy!
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.
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.
No, problem. I think, rd datalist could be a really good markup polyfill.
In fact, it renders all examples, but in case of 3 and 4 the label (explicit/implicit) has to be shown to the user.
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.
dont need a polyfill for boxshadow. more deets on datalist. fixes #18