Domanda

I use msDropDown to convert the <select> to <ul> list for languages switcher. But the problem is that with this jQuery plugin, the select takes a long time to load after page loaded.

So, how can I use a ul list rather than select?

This is my select code:

<select name="lang" class="language" onchange="location.href='index.php?lang='+this.value+''.$trackpage.'">
    <option name="lang" data-image="style/lang/de.png" value="de">Deutsch</option>
    <option name="lang" data-image="style/lang/en.png" value="en" selected="selected">English</option>
    <option name="lang" data-image="style/lang/es.png" value="es">Espanol</option>
    <option name="lang" data-image="style/lang/fr.png" value="fr">Francais</option>
    <option name="lang" data-image="style/lang/it.png" value="it">Italiano</option>
</select>

I tried with:

<ul onchange="location.href='index.php?lang='+this.value+'">
    <li>
        <a href="" name="lang" data-image="style/lang/de.png" value="de">English</a>
    </li>
</ul>

but value and onchange is not supported by ul and a.
Is there a way to make ul works with the select attributes?

Thank you! And sorry for my bad English!

È stato utile?

Soluzione

Updated Answer 2015

As this question is still visited very often and due to some requests in the comments, I've revisit my code. You can still find my original answer below.

HTML

<button class="language_selector">Choose Language</button>
<ul class="languages">
    <li><a href="/en">English</a></li>
    <li><a href="/de">Deutsch</a></li>
</ul>

<article>
    <h1>More Content</h1>
</article>

JavaScript

var trigger = $('.language_selector');
var list = $('.languages');

trigger.click(function() {
    trigger.toggleClass('active');
    list.slideToggle(200);
});

// this is optional to close the list while the new page is loading
list.click(function() {
    trigger.click();
});

CSS

.language_selector {
    width: 200px;
    background: #222;
    color:  #eee;
    line-height: 25px;
    font-size: 14px;
    padding: 0 10px;
    cursor: pointer;
}

.languages {
    display: none;
    position: absolute;
    margin: 0;
    background: #dddddd;
}

.languages > li {
    width: 200px;
    background: #eee;
    line-height: 25px;
    font-size: 14px;
    padding: 0 10px;
    cursor: pointer;
}

.languages > li:hover {
    background: #aaa;
}

Demo

Try before buy


Original Answer From 2013

I would do it like this:

var nav = $('#nav');
var selection = $('.select');
var select = selection.find('li');

nav.click(function(event) {
    if (nav.hasClass('active')) {
        nav.removeClass('active');
        selection.stop().slideUp(200);
    } else {
        nav.addClass('active');
        selection.stop().slideDown(200);
    }
    event.preventDefault();
});

select.click(function(event) {
    // updated code to select the current language
    select.removeClass('active');
    $(this).addClass('active');

    alert ("location.href = 'index.php?lang=" + $(this).attr('data-value'));
});
h2 {
    width: 200px;
    background: #222;
    color:  #eee;
    line-height: 25px;
    font-size: 14px;
    padding: 0 10px;
    cursor: pointer;
}
ol.select {
    display: none;
}

ol.select > li {
    width: 200px;
    background: #eee;
    line-height: 25px;
    font-size: 14px;
    padding: 0 10px;
    cursor: pointer;
}

ol.select > li:hover {
    background: #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h2 id="nav">Choose Language</h2>
<ol class="select">
    <li data-value="en">English</li>
    <li data-value="de">Deutsch</li>
</ol>

This one adds a class the the selected element. This works, if you stay on that very page after the select and don't use location.href.

Altri suggerimenti

You can't use the select attributes, instead you can create your own attributes and use them in <ul> element

Maybe this will help you

First the html code

<div id="language">Change Lang</div>
<ul id="lang">
    <li>
        <a href="" name="lang" data-val="de">
           <img src="http://icons.iconarchive.com/icons/famfamfam/flag/16/ad-icon.png"/>
        English</a></li>
    <li>
        <a href="" name="lang" data-val="he">
            <img src="http://icons.iconarchive.com/icons/famfamfam/flag/16/il-icon.png"/>
            Hebrew</a></li>
</ul>

Next the jquery code

$("#language").click(function(){
   $("#lang li").slideToggle();
});

$("#lang li").click(function() {
    var url = location.href = "index.php?lang=" + $(this).find('a').attr("data-val");
   location.href =url;
});

i have did it without the plugin.

Pay attention that i created a data-val attribute so store the desire language. and i getting this attribute using jquery code

A very simple one (ul to select dropdown jquery transformation) no need to change html, very useful for mobile menus:

$(function(){
  var close = function() {
    $("ul").each(function() {
      var $thisUl = $(this);    
      if($thisUl.find("li > a.click").length == 0) {
        var $li = $(document.createElement('li')).append($(document.createElement('a')).attr({
          "class": "click selectable visible",
          "href": "#"
        }).text("Select"));
        $thisUl.append($li);
      }
      else {
        $thisUl.find("li > a.click").addClass("visible");
      }
      $thisUl.find("li:has(> a:not(.click))").hide();
      $thisUl.find("li > a.click").show();
    });
  };

  var sentinel = function() {
    $("ul").each(function(){
      var $thisUl = $(this);
      $($thisUl).find("li > a").click(function(event){
        if($(event.target).is('ul li a.visible')) {
          event.preventDefault();
          $thisUl.find("li:has(> a:not(.click))").show();
          $thisUl.find("li > a.selectable").hide();
          $thisUl.find("li > a.click").removeClass("visible");
        }
        else {
          $thisUl.find("li").each(function(){
            $(this).find("a").removeClass("click selectable visible");
            $(this).find("a.selectable").remove();
          });
          $(this).addClass("click visible");
          close();
        }
      });
    });
  };

  var reconnaissance = function() {
    $(document).click(function(event) {
      if(!$(event.target).is('ul li a')) {
        close();
      }
    });
  };

  close();
  sentinel();
  reconnaissance();
});
ul { 
  width: auto;
  margin: 2px auto;
  background-color: #ddd;
  border-top: 1px solid #999;
  border-bottom: 3px solid #999;
  border-left: 1px solid #999;
  border-right: 1px solid #999;
  border-radius: 8px;
  list-style:none;
  background-size: 16px 16px;
  background-repeat: no-repeat;
  background-attachment: scroll;
  background-position: left 2px;
  background-color: transparent;
  cursor: pointer;
}
li > a.click { 
  color: darkgreen; 
  font-weight: bold;
}
li a {
  color:darkblue;
  text-decoration:none;
}
li a:active, li a:hover {
  color:darkred;
  background-color: lightyellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
  <li><a href="#">Option 1</a></li>
  <li><a class="click" href="#">Option 2</a></li>
  <li><a href="#">Option 3</a></li>
</ul>

<ul>
  <li><a href="#">Option 1</a></li>
  <li><a href="#">Option 2</a></li>
  <li><a href="#">Option 3</a></li>
</ul>

// Generated by CoffeeScript 1.4.0
(function() {
  var $;

  $ = window.jQuery || window.Zepto || window.$;

  $.fn.fancySelect = function(opts) {
    var isiOS, settings;
    if (opts == null) {
      opts = {};
    }
    settings = $.extend({
      forceiOS: false,
      includeBlank: false,
      optionTemplate: function(optionEl) {
        return optionEl.text();
      },
      triggerTemplate: function(optionEl) {
        return optionEl.text();
      }
    }, opts);
    isiOS = !!navigator.userAgent.match(/iP(hone|od|ad)/i);
    return this.each(function() {
      var copyOptionsToList, disabled, options, sel, trigger, updateTriggerText, wrapper;
      sel = $(this);
      if (sel.hasClass('fancified') || sel[0].tagName !== 'SELECT') {
        return;
      }
      sel.addClass('fancified');
      sel.css({
        width: 1,
        height: 1,
        display: 'block',
        position: 'absolute',
        top: 0,
        left: 0,
        opacity: 0
      });
      sel.wrap('<div class="fancy-select">');
      wrapper = sel.parent();
      if (sel.data('class')) {
        wrapper.addClass(sel.data('class'));
      }
      wrapper.append('<div class="trigger">');
      if (!(isiOS && !settings.forceiOS)) {
        wrapper.append('<ul class="options">');
      }
      trigger = wrapper.find('.trigger');
      options = wrapper.find('.options');
      disabled = sel.prop('disabled');
      if (disabled) {
        wrapper.addClass('disabled');
      }
      updateTriggerText = function() {
        var triggerHtml;
        triggerHtml = settings.triggerTemplate(sel.find(':selected'));
        return trigger.html(triggerHtml);
      };
      sel.on('blur.fs', function() {
        if (trigger.hasClass('open')) {
          return setTimeout(function() {
            return trigger.trigger('close.fs');
          }, 120);
        }
      });
      trigger.on('close.fs', function() {
        trigger.removeClass('open');
        return options.removeClass('open');
      });
      trigger.on('click.fs', function() {
        var offParent, parent;
        if (!disabled) {
          trigger.toggleClass('open');
          if (isiOS && !settings.forceiOS) {
            if (trigger.hasClass('open')) {
              return sel.focus();
            }
          } else {
            if (trigger.hasClass('open')) {
              parent = trigger.parent();
              offParent = parent.offsetParent();
              if ((parent.offset().top + parent.outerHeight() + options.outerHeight() + 20) > $(window).height() + $(window).scrollTop()) {
                options.addClass('overflowing');
              } else {
                options.removeClass('overflowing');
              }
            }
            options.toggleClass('open');
            if (!isiOS) {
              return sel.focus();
            }
          }
        }
      });
      sel.on('enable', function() {
        sel.prop('disabled', false);
        wrapper.removeClass('disabled');
        disabled = false;
        return copyOptionsToList();
      });
      sel.on('disable', function() {
        sel.prop('disabled', true);
        wrapper.addClass('disabled');
        return disabled = true;
      });
      sel.on('change.fs', function(e) {
        if (e.originalEvent && e.originalEvent.isTrusted) {
          return e.stopPropagation();
        } else {
          return updateTriggerText();
        }
      });
      sel.on('keydown', function(e) {
        var hovered, newHovered, w;
        w = e.which;
        hovered = options.find('.hover');
        hovered.removeClass('hover');
        if (!options.hasClass('open')) {
          if (w === 13 || w === 32 || w === 38 || w === 40) {
            e.preventDefault();
            return trigger.trigger('click.fs');
          }
        } else {
          if (w === 38) {
            e.preventDefault();
            if (hovered.length && hovered.index() > 0) {
              hovered.prev().addClass('hover');
            } else {
              options.find('li:last-child').addClass('hover');
            }
          } else if (w === 40) {
            e.preventDefault();
            if (hovered.length && hovered.index() < options.find('li').length - 1) {
              hovered.next().addClass('hover');
            } else {
              options.find('li:first-child').addClass('hover');
            }
          } else if (w === 27) {
            e.preventDefault();
            trigger.trigger('click.fs');
          } else if (w === 13 || w === 32) {
            e.preventDefault();
            hovered.trigger('click.fs');
          } else if (w === 9) {
            if (trigger.hasClass('open')) {
              trigger.trigger('close.fs');
            }
          }
          newHovered = options.find('.hover');
          if (newHovered.length) {
            options.scrollTop(0);
            return options.scrollTop(newHovered.position().top - 12);
          }
        }
      });
      options.on('click.fs', 'li', function(e) {
        var clicked;
        clicked = $(this);
        sel.val(clicked.data('raw-value'));
        if (!isiOS) {
          sel.trigger('blur.fs').trigger('focus.fs');
        }
        options.find('.selected').removeClass('selected');
        clicked.addClass('selected');
        return sel.val(clicked.data('raw-value')).trigger('change.fs').trigger('blur.fs').trigger('focus.fs');
      });
      options.on('mouseenter.fs', 'li', function() {
        var hovered, nowHovered;
        nowHovered = $(this);
        hovered = options.find('.hover');
        hovered.removeClass('hover');
        return nowHovered.addClass('hover');
      });
      options.on('mouseleave.fs', 'li', function() {
        return options.find('.hover').removeClass('hover');
      });
      copyOptionsToList = function() {
        var selOpts;
        updateTriggerText();
        if (isiOS && !settings.forceiOS) {
          return;
        }
        selOpts = sel.find('option');
        return sel.find('option').each(function(i, opt) {
          var optHtml;
          opt = $(opt);
          if (!opt.prop('disabled') && (opt.val() || settings.includeBlank)) {
            optHtml = settings.optionTemplate(opt);
            if (opt.prop('selected')) {
              return options.append("<li data-raw-value=\"" + (opt.val()) + "\" class=\"selected\">" + optHtml + "</li>");
            } else {
              return options.append("<li data-raw-value=\"" + (opt.val()) + "\">" + optHtml + "</li>");
            }
          }
        });
      };
      sel.on('update.fs', function() {
        wrapper.find('.options').empty();
        return copyOptionsToList();
      });
      return copyOptionsToList();
    });
  };

}).call(this);
div.fancy-select {
  position: relative;
  color: #505050;  
}

div.fancy-select.disabled {
	opacity: 0.5;
}

div.fancy-select select:focus + div.trigger {
}

div.fancy-select select:focus + div.trigger.open {
}

div.fancy-select div.trigger {
  cursor: pointer;
  height: 50px;
  line-height: 50px;
  padding-left: 20px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  position: relative;
  width: 100%;
  border: 1px solid #6e6e6e;
  
  transition: all 240ms ease-out;
  -webkit-transition: all 240ms ease-out;
  -moz-transition: all 240ms ease-out;
  -ms-transition: all 240ms ease-out;
  -o-transition: all 240ms ease-out;
}

div.fancy-select div.trigger:after {
	content: "";
	display: block;
	position: absolute;
	width: 0;
	height: 0;
	border: 5px solid transparent;
	border-top-color: #4B5468;
	top: 20px;
	right: 9px;
}

div.fancy-select div.trigger.open {
}

div.fancy-select div.trigger.open:after {
}

div.fancy-select ul.options {
	list-style: none;
	margin: 0;
	position: absolute;
	top: 49px;
	left: 0;
	visibility: hidden;
	opacity: 0;
	z-index: 50;
	max-height: 200px;
	overflow: auto;
	border: 1px solid #6e6e6e;
	width: 100%;
  	padding: 0;
	background: #fff;
	transition: opacity 300ms ease-out, top 300ms ease-out, visibility 300ms ease-out;
	-webkit-transition: opacity 300ms ease-out, top 300ms ease-out, visibility 300ms ease-out;
	-moz-transition: opacity 300ms ease-out, top 300ms ease-out, visibility 300ms ease-out;
	-ms-transition: opacity 300ms ease-out, top 300ms ease-out, visibility 300ms ease-out;
	-o-transition: opacity 300ms ease-out, top 300ms ease-out, visibility 300ms ease-out;
}

div.fancy-select ul.options.open {
	visibility: visible;
	top: 50px;
	opacity: 1;

	/* have to use a non-visibility transition to prevent this iOS issue (bug?): */
	/*http://stackoverflow.com/questions/10736478/css-animation-visibility-visible-works-on-chrome-and-safari-but-not-on-ios*/
	transition: opacity 300ms ease-out, top 300ms ease-out;
	-webkit-transition: opacity 300ms ease-out, top 300ms ease-out;
	-moz-transition: opacity 300ms ease-out, top 300ms ease-out;
	-ms-transition: opacity 300ms ease-out, top 300ms ease-out;
	-o-transition: opacity 300ms ease-out, top 300ms ease-out;
}

div.fancy-select ul.options.overflowing {
	top: auto;
	bottom: 40px;

	transition: opacity 300ms ease-out, bottom 300ms ease-out, visibility 300ms ease-out;
	-webkit-transition: opacity 300ms ease-out, bottom 300ms ease-out, visibility 300ms ease-out;
	-moz-transition: opacity 300ms ease-out, bottom 300ms ease-out, visibility 300ms ease-out;
	-ms-transition: opacity 300ms ease-out, bottom 300ms ease-out, visibility 300ms ease-out;
	-o-transition: opacity 300ms ease-out, bottom 300ms ease-out, visibility 300ms ease-out;
}

div.fancy-select ul.options.overflowing.open {
	top: auto;
	bottom: 50px;

	transition: opacity 300ms ease-out, bottom 300ms ease-out;
	-webkit-transition: opacity 300ms ease-out, bottom 300ms ease-out;
	-moz-transition: opacity 300ms ease-out, bottom 300ms ease-out;
	-ms-transition: opacity 300ms ease-out, bottom 300ms ease-out;
	-o-transition: opacity 300ms ease-out, bottom 300ms ease-out;
}

div.fancy-select ul.options li {
	padding: 8px 20px;
	color: #000;
	cursor: pointer;
	white-space: nowrap;

	transition: all 150ms ease-out;
	-webkit-transition: all 150ms ease-out;
	-moz-transition: all 150ms ease-out;
	-ms-transition: all 150ms ease-out;
	-o-transition: all 150ms ease-out;
}

div.fancy-select ul.options li.selected {
	background: #d3d3d3;
	color: #000;
}

div.fancy-select ul.options li:hover, div.fancy-select ul.options li.hover {
  	background: #d3d3d3;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select name="SortBy" id="SortBy" class="filters-toolbar__input">
  <option value="" selected="selected">Option 1</option>
  <option value="" selected="selected">Option 2</option>
  <option value="" selected="selected">Option 3</option>
</select>

/* --- fancySelect --- */



$(function() {
$('#SortBy').fancySelect();
});

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top