web-dev-qa-db-fra.com

La balise datalist HTML5 ne se trouve pas dans Safari

J'ai une balise datalist qui permet à mes utilisateurs d'avoir une boîte à suggestions. Cependant, j'ai remarqué que cette fonctionnalité n'est pas prise en charge par Safari. Existe-t-il une solution de contournement à ce problème?

Voici mon code - En fait, je renseigne mes valeurs avec une méthode ajax, mais voici à quoi il ressemblerait une fois rempli:

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

J'ai aussi un violon ici

22
R Doolabh

Les éléments Datalist ne sont pas pris en charge dans Safari. http://caniuse.com/#feat=datalist

21
Tim Dearborn

Solution palliative HTML5 pour les navigateurs Safari et/ou anciens

Mise à jour, janvier 2017

Que ce soit sur iOS ou sur un ordinateur de bureau Safari ne prend toujours pas en charge datalist , et rien n’indique pour autant que cela change. Donc, c’est un hack qui fait apparaître pour contourner le problème. Chris Coyier s'est également essayé à un datalist polyfill en 2011 . Espérons que Safari applique la recommandation existante du W3C à l'avenir.

Message original:

Vous pouvez utiliser un élément select à l'intérieur de datalist et dupliquer les valeurs de la balise option en tant que texte lisible dans ces éléments. Par exemple:

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

Les navigateurs qui prennent en charge n’afficheront que la variable datalist, les navigateurs plus anciens Safari afficheront le code innerHTML des balises option. La balise input a une bordure par défaut qui, dans Safari, a l'air mal derrière l'élément select, mais avec un style similaire à celui illustré dans cet exemple, vous pouvez pallier le manque de support de Safari et conserver la même apparence fonctionnelle. Pas besoin de Javascript et/ou de polyfills.

26
Dave Everitt

Je réalise que c'est un peu tard, mais pour ceux qui veulent une solution qui imite Datalist sur Safari, plutôt que de la remplacer par un select:

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

En bref, un fichier .js et .css court et agréable que vous pouvez inclure dans votre code HTML et qui permet aux entrées liées des datalistes de se comporter de la même manière sur Safari et Opera mini que sur Chrome, Firefox et le navigateur Android.

9
George

Tout d’abord, merci George pour votre scénario qui fonctionne encore aujourd’hui. Pour ceux qui rencontrent des problèmes car vos options sont affichées dans le coin supérieur gauche (comme iamse7en), vous devez modifier ces lignes dans datalist.polyfill.js:

56:

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

À titre d'exemple dans le projet github, il n'y avait qu'une seule div dans le corps, donc ce n'était pas un problème.

110:

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

Pour cliquer n'importe où sur l'élément et pas seulement sur le texte.

Et ajoutez enfin le <script src="/static/js/datalist.polyfill.js"></script> sur votre fichier html mais pas la version datalist.polyfill.min.js

0
Mianto

Suite à ce que Mianto a dit à propos du problème d'iamse7en, afin de lier votre dataliste à une DIV dynamique (l'exemple donné par Mianto, puis modifié par Moritz, est codé en dur), modifiez ce qui suit à la ligne 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 );

à:

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 );
0
EvilJordan