HTML5的数据列表标签在Safari中没有填充。

29

我有一个datalist标签,它允许我的用户获得建议框。但是,我注意到这个功能在Safari浏览器中不受支持。这个问题有解决办法吗?

这是我的代码 - 实际上我是用ajax方法填充我的值,但这是在填充后它看起来像什么:

<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">

我也有一个示例 在这里

6个回答

28

HTML5 datalist在Safari和/或旧浏览器中的解决方法

更新,2022年6月

Safari(未经我测试)现在支持datalist标签-请参阅下面的答案。不过,Firefox存在一些问题,详见caniuse

更新,2017年1月

无论是iOS还是桌面版Safari仍不支持datalist,目前也没有迹象表明会有所改变。因此,这是一个hack,使其看起来绕过了这个问题。Chris Coyier在2011年也尝试过datalist polyfill。希望Safari将现有的W3C推荐在未来实现。

原始帖子:

你可以在 datalist 中使用 select 元素,并将 option 标签的值复制为可读文本。例如:

<!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>

支持的浏览器将只显示datalist,而Safari和旧版浏览器将显示option标签的innerHTML。 input标签具有默认边框,在Safari中在select元素后面看起来很糟糕,但是通过像这个示例中所示的一些样式,您可以避免Safari的不支持并保持相同的功能外观。无需使用JavaScript和/或polyfills。

3
为了澄清,Safari会在输入框前显示一个选择元素。它的行为不同于datalist,您不能输入任意文本或从建议列表中选择。 - IceCreamYou
1
不幸的是,对于Safari或其他不支持<datalist>的浏览器的用户来说,这种解决方案完全排除了输入其他值的可能性,因为<select>元素只允许选择内容,而不允许输入。因此,对于所有这些用户来说,行为的一部分以不可替代的方式死亡...实际上,对于他们来说,示例的工作方式就像<input type="text" list="languages">根本不存在。 - willy wonka
4
在我看来,(对于未来的HTML 6?)最好的方式是只使用**<select>标签,并加入一个新属性,比如editable="true"以允许编辑,再加上一个新属性filterable="true"以在键入时进行过滤。而<datalist>标签将有助于在多个选择框之间共享选项。但这只是另一个故事,只是对w3c html 6标准未来发展的希望……实际上,<select>标签是具有可选择选项的列表中“逻辑/一致/自然”的标签。使用<input type="text">**并不是正确的方法。 - willy wonka
1
我遇到了相同的问题。我认为苹果的HTML参考:datalist被他们的浏览器支持...或者这是因为2017年的一些变化而新出现的。 - Joe Platano
Joe,我在文档中看到了这个引用,但似乎在Safari 10.1中无法使用。有人已经让它正常工作了吗? 这是我的示例:<html> <head> <title>测试</title> </head> <body> <form> <input name="state" list="states"> <datalist id="states"> <option>阿拉巴马州</option> <option>阿拉斯加州</option> <option>怀俄明州</option> </datalist> </form> </body> </html> - Elliott

22

有没有解决这个问题的方法?我只找到了一种将数据列表转换为下拉列表的方式,但那不是我想要的。谢谢。 - DannyD
不容易。一个技巧是,您可以创建一个带有顶部或底部的“其他”选项的选择框。当选择“其他”时,您可以显示一个文本框,供用户输入不在列表中的内容。 - Tim Dearborn
有没有一种类似于 Safari 中自动完成的 CSS 和 JavaScript 模拟方法? - DannyD
9
这个工具 https://github.com/thgreasi/datalist-polyfill 可能会有所帮助。看起来这段代码支持那些不支持 datalist 的浏览器。 - Tim Dearborn
是的,我在你发帖之前就看到了。那应该能很好地工作。谢谢! - DannyD

10
自Safari 12.1起,datalist终于得到支持,请参阅Apple发布说明
看起来mdn推荐填充方案的开发人员保持了相当及时的更新:
引用:

更新:至少基本上,Safari TP支持datalist元素,其功能将包含在Safari的下一个版本中,适用于iOS和MacOS X。是的!!! 激动人心的消息!我计划很快发布一个新的重大版本,既可以庆祝,又可以适应它们的实现


8

我知道有点晚了,但是对于那些想要在Safari上模拟datalist而不是用select替代的人们,可以使用以下解决方案:

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

其实这只是一个简短而简洁的.js和.css文件,您可以将它们包含在html中,并使datalist链接输入在Safari和Opera mini上的行为与Chrome、Firefox和Android浏览器相同。


我们选择了这个来支持Safari上的数据列表。感谢您的推荐。 - eerne
它运行得非常完美。我进行了一些美学上的修改。在链接中查看它。 - tdolphin
1
我在使用Safari时遇到了问题...但在iOS Chrome上运行得很好。 - Peter Sun
在我的iOS Safari上无法工作(iPhone X 11.2),而在Mac OS High Sierra Safari中表现奇怪:一旦开始输入,自动完成数据列表就会出现,但只出现在浏览器的左上角。 - iamse7en

1

首先,感谢George的脚本,今天它又起作用了。对于那些因为你的选项显示在左上角而遇到麻烦的人(比如iamse7en),你应该修改datalist.polyfill.js中的这些行:

56:

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

因为在Github项目的示例中,只有一个div在body中,所以这不是问题。

110:

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

可以点击项目的任何位置,而不仅仅是文本。

最后,在您的html文件中添加<script src="/static/js/datalist.polyfill.js"></script>,但不是版本datalist.polyfill.min.js。


感谢提供的Polyfill工具,非常有效!我创建了一个CodePen链接,供需要的人查看:https://codepen.io/arlevi/pen/gEqvRb - Ricky Levi

0

关于iamse7en的问题,根据Mianto所说,为了将您的数据列表绑定到动态DIV(Mianto给出的示例然后由Moritz编辑是硬编码的),请更改第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 );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接