web-dev-qa-db-fra.com

Comment convertir une liste non ordonnée en une liste déroulante <select> joliment stylée en utilisant jQuery?

Comment convertir une liste non ordonnée dans ce format

<ul class="selectdropdown">
    <li><a href="one.html" target="_blank">one</a></li>
    <li><a href="two.html" target="_blank">two</a></li>
    <li><a href="three.html" target="_blank">three</a></li>
    <li><a href="four.html" target="_blank">four</a></li>
    <li><a href="five.html" target="_blank">five</a></li>
    <li><a href="six.html" target="_blank">six</a></li>
    <li><a href="seven.html" target="_blank">seven</a></li>
</ul>

dans une liste déroulante dans ce format

<select>
    <option value="one.html" target="_blank">one</option>
    <option value="two.html" target="_blank">two</option>
    <option value="three.html" target="_blank">three</option>
    <option value="four.html" target="_blank">four</option>
    <option value="five.html" target="_blank">five</option>
    <option value="six.html" target="_blank">six</option>
    <option value="seven.html" target="_blank">seven</option>
</select>

en utilisant jQuery?

Éditer: Lorsque vous sélectionnez une entrée dans la liste déroulante Sélectionner /, le lien devrait s'ouvrir automatiquement dans une nouvelle fenêtre ou un nouvel onglet. Je veux aussi pouvoir le personnaliser comme suit: http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/

16
Jitendra Vyas
$('ul.selectdropdown').each(function() {
    var select = $(document.createElement('select')).insertBefore($(this).hide());
    $('>li a', this).each(function() {
        var a = $(this).click(function() {
            if ($(this).attr('target')==='_blank') {
                window.open(this.href);
            }
            else {
                window.location.href = this.href;
            }
        }),
        option = $(document.createElement('option')).appendTo(select).val(this.href).html($(this).html()).click(function() {
            a.click();
        });
    });
});

En réponse à votre dernier commentaire , je l'ai modifié un peu mais je ne l'ai pas testé. Faites le moi savoir.

$('ul.selectdropdown').each(function() {
    var list = $(this), select = $(document.createElement('select')).insertBefore($(this).hide());

    $('>li a', this).each(function() {
        var target = $(this).attr('target'),
        option = $(document.createElement('option'))
            .appendTo(select)
            .val(this.href)
            .html($(this).html())
            .click(function(){
                if(target==='_blank') {
                    window.open($(this).val());
                }
                else {
                    window.location.href = $(this).val();
                }
            });
    });
    list.remove();
});
13
czarchaic
$(function() {
    $('ul.selectdropdown').each(function() {
        var $select = $('<select />');

        $(this).find('a').each(function() {
            var $option = $('<option />');
            $option.attr('value', $(this).attr('href')).html($(this).html());
            $select.append($option);
        });

        $(this).replaceWith($select);
    });
});

MODIFIER

Comme pour tout code jQuery que vous souhaitez exécuter au chargement de la page, vous devez l'envelopper dans le bloc $(document).ready(function() { ... }); ou dans sa version plus courte $(function() { ... });. J'ai mis à jour la fonction pour montrer ceci.

MODIFIER

était un bogue dans mon code aussi, a essayé de prendre href de l'élément li.

20
Tatu Ulmanen

Cette solution fonctionne également dans IE et utilise l'élément sélectionné (dans la balise d'ancrage).

$('ul.selectdropdown').each(function(){
var list=$(this),
    select=$(document.createElement('select')).insertBefore($(this).hide()).change(function(){
  window.location.href=$(this).val();
});
$('>li a', this).each(function(){
  var option=$(document.createElement('option'))
   .appendTo(select)
   .val(this.href)
   .html($(this).html());
  if($(this).attr('class') === 'selected'){
    option.attr('selected','selected');
  }
});
list.remove();
});
2
Radim

J'ai récemment créé une solution où le ul transformé, imite presque complètement le select.

De plus, il recherche les options de la sélection et prend en charge l'état actif. Ajoutez simplement une classe avec le nom actif et cette option sera sélectionnée.

Il gère la navigation au clavier.

Regardez le code ici: Code GitHub

Et un exemple en direct ici: Exemple de code

La liste non ordonnée doit être sous la forme:

<ul id="...">
  <li><a href="...">...</a></li>
  <li><a href="...">...</a></li>
  <li><a class="active" href="...">...</a></li>
  ...
</ul>

Pour convertir le ul de sélectionner simplement appeler:

$(window).on("load resize", function() {
  ulToSelect($("ul#id"), 767);
});

Où #id est un identifiant pour la liste non numérotée et 767 est la largeur minimale de la fenêtre pour la convertion avoir lieu. Ceci est très utile si vous souhaitez que la conversion ait lieu uniquement pour mobile ou tablette.

0
q81

Merci à tous pour poster les codes. Mon scénario est similaire, mais ma situation concerne, pour Réactivité, que, pour la taille x, il basculerait vers une liste déroulante, puis, si ce n’est pas le cas, en utilisant csswatch pour rechercher les propriétés "display" d’un élément comportant certains éléments. quantité de largeur définie (par exemple: 740px). Pensé que je partage cette solution pour quiconque est intéressé. C'est ce que j'ai combiné avec les codes de Tatu. Au lieu de remplacer le code HTML, j'ai créé, puis masqué le nouveau code HTML, puis ne l'ajoutez que si nécessaire:

var $list = $('ul.list');
(listFunc = function(display){

    //Less than x-size turns it into a dropdown list
    if(display == 'block'){
        $list.hide();
        if($('.sels').length){
            $('.sels').show();
        } else {
            var $select = $('<select class="sels" />');

            $list.find('a').each(function() {
                var $option = $('<option />');
                $option.attr('value', $(this).attr('href')).html($(this).html());
                $select.append($option);
            });

            $select.insertAfter($list);

            $('.sels').on('change', function(){
                window.location = this.value;
            });
        }
    } else {
        $('.sels').hide();
        $list.show();
    }
})(element.css('display'));
element.csswatch({
    props: 'display'
}).on('css-change', function (event, change) {
    return listFunc(change.display);
});
0
Mon