如何在语言切换器中使用 <ul> 列表而不是 <select> 下拉列表?
Posted
技术标签:
【中文标题】如何在语言切换器中使用 <ul> 列表而不是 <select> 下拉列表?【英文标题】:How can I use <ul> list instead of <select> dropdown for the languages switcher? 【发布时间】:2013-02-02 07:08:05 【问题描述】:我使用msDropDown
将<select>
转换为<ul>
语言切换器列表。但问题是,使用这个 jQuery 插件,页面加载后 select 需要很长时间才能加载。
那么,我怎样才能使用ul
列表而不是select
?
这是我的选择代码:
<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>
我试过了:
<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>
但ul
和a
不支持value
和onchange
。
有没有办法让ul
与select
属性一起使用?
谢谢!对不起我的英语不好!
【问题讨论】:
您希望它充当下拉列表吗?或者你对元素列表很好? 【参考方案1】:您不能使用选择属性,而是可以创建自己的属性并在<ul>
元素中使用它们
也许这会对你有所帮助
首先是html代码
<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>
接下来是jquery代码
$("#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;
);
我在没有插件的情况下做到了。
请注意,我创建了一个data-val
属性,以便存储所需的语言。
我使用 jquery 代码获取此属性
【讨论】:
感谢您对 Silagy 的帮助!【参考方案2】:2015 年更新答案
由于这个问题仍然经常被访问,并且由于 cmets 中的一些请求,我重新访问了我的代码。您仍然可以在下面找到我的原始答案。
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;
演示
Try before buy
2013 年的原始答案
我会这样做:
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>
这个为被选元素添加了一个类。如果您在选择后停留在该页面上并且不使用location.href
,则此方法有效。
【讨论】:
你很快,非常好的解决方案...(使用选择确切的属性)+1 非常感谢。我之前构建过类似的东西,所以我可以快速适应它。 @insertusernamehere 您好,但是我如何将课程添加到所选语言?我用$('.select li').removeClass('active'); $(this).addClass('active');
处理不好,但是使用标准列表可以正常工作,为什么?
嘿@Fuiba 实际上它应该像你写的那样工作。我已经更新了我的答案。您不必再次使用另一个选择器,因为 li
s 存储在变量中。如果您使用location.href
,这将不起作用,因为页面会在之后重新加载。如果这样做,您可以在打印语言列表时使用 PHP 添加类 active
。
我将如何做同样的事情但不让它向下推元素? (即,如果您在 下方添加一堆文本并运行 sn-p,您会看到它向下推而不是像人们期望的那样覆盖下拉)【参考方案3】:
一个很简单的(ul to select dropdown jquery transformation)不用改html,对手机菜单很有用:
$(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>
【讨论】:
【参考方案4】:// 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://***.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();
);
【讨论】:
欢迎来到 Stack Overflow,感谢您详细而冗长的回答。您能否编辑您的答案并解释这如何解决原始问题? 一个好的答案有一个更好的解释How do I write a good answer?以上是关于如何在语言切换器中使用 <ul> 列表而不是 <select> 下拉列表?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery 填充 <ul> 和从 JSON ActionResult 返回的列表?
BeautifulSoup:如何从包含一些嵌套 <ul> 的 <ul> 列表中提取所有 <li>?