HTML5 datalist tag is not populating in Safari

2020-01-28 03:49发布

问题:

I have a datalist tag which allows my users to have a suggestion box. However, I've noticed that this feature is not supported in safari. Is there a workaround to this issue?

Here is my code - I'm actually populating my values with an ajax method but this is what it would look like after it's populated:

<datalist id="languages">
    <option value="HTML">
    <option value="CSS">
    <option value="JavaScript">
    <option value="Java">
    <option value="Ruby">
    <option value="PHP">
    <option value="Go">
    <option value="Erlang">
    <option value="Python">
    <option value="C">
    <option value="C#">
    <option value="C++">
</datalist>

Search: 
<input type="text" list="languages">

I also have a fiddle here

回答1:

Datalist elements are not supported in Safari. http://caniuse.com/#feat=datalist



回答2:

HTML5 datalist workaround for Safari and/or older browsers

Update, Jan 2017

Both iOS or desktop Safari still do not support datalist, and there's no sign so far of this changing. So this is a hack making it appear to get around the issue. Chris Coyier also had a go at a datalist polyfill back in 2011. Let's hope Safari implements the existing W3C Recommendation in future.

Original post:

You can use a select element inside the datalist, and duplicate the option tag values as readable text in these. For example:

<!DOCTYPE html>
<html>
<head>
  <title>test</title>
  <style>
    input[list="languages"] {
      width: 12em;
      border: none;
      background: #eee;
    }
    select {
      width: 12em;
      margin: 0;
      margin-left: -12.75em;
    }
  </style>
</head>
<body>

Choose: <input type="text" list="languages">
<label for="languages">
  <datalist id="languages">
    <select>
      <option value="JavaScript">JavaScript</option>
      <option value="Haskell">Haskell</option>
      <option value="Ruby">Ruby</option>
      <option value="Go">Go</option>
      <option value="Python">Python</option>
      <option value="etc">etc</option>
    </select>
  </datalist>
</label>
</body>
</html>

Supporting browsers will just display the datalist, Safari and older browsers will show the option tags' innerHTML. The input tag has a default border, which in Safari looks bad behind the select element, but with a little styling as shown in this example, you can get around Safari's lack of support and keep the same functional appearance. No need for Javascript and/or polyfills.



回答3:

I realize its a bit late, but, for those who want a solution that mimics datalist on Safari, rather than replacing it with a select:

https://github.com/Fyrd/purejs-datalist-polyfill

Basically a short and sweet .js and .css that you can include in your html and it makes datalists linked inputs behave the same on Safari and Opera mini as they do on Chrome, Firefox and Android Browser.



回答4:

As of Safari 12.1, datalist is now finally supported. Please see the Apple release notes.

It seems that the developer of the mdn recommended polyfill stays quite up to date:

Update: Safari TP supports the datalist element at least basically, and its functionality will be included within the next release of Safari both for iOS and MacOS X. Yeah !!! Exciting news! I'm planning to release a new major version soon to both cheer as well as accommodate their implementation



回答5:

First, thank you George for you script that work again today. For those which get trouble cause your options are display in the top left hand corner (like iamse7en) you should modify these lines in datalist.polyfill.js :

56 :

document.body.appendChild( fakeList ); document.getElementById("myIdDiv").appendChild( fakeList );

Bescause in the exemple on the github project it was only one div in the body so it was not a problem.

110 :

input.value = item.innerText; input.value = item.innerHTML;

To click anywhere on the item and not only on the text.

And finaly add the <script src="/static/js/datalist.polyfill.js"></script> on your html file but not the version datalist.polyfill.min.js



回答6:

Further to what Mianto said regarding iamse7en's issue, in order to bind your datalist to a dynamic DIV (the example Mianto gave and then Moritz edited is hard-coded), change the following at line 51:

function convert(input, datalist, listItems) {
    var fakeList = document.createElement('ul');
    var visibleItems = null;
    fakeList.id = listId;
    fakeList.className = LIST_CLASS;
    document.body.appendChild( fakeList );

to:

function convert(input, datalist, listItems) {
    var fakeList = document.createElement('ul');
    var visibleItems = null;
    fakeList.id = listId;
    fakeList.className = LIST_CLASS;
    input.parentNode.style.position = "relative";
    input.parentNode.appendChild( fakeList );