在我的在线商店中,我想实现一个像亚马逊的这样的接口来选择产品的大小和颜色。也就是说,用户应该看到的不是单选按钮,而是不同大小/颜色的单选按钮,每个小框都包含一个颜色样本或一个大小的名称。当用户单击某个框时,边框应更改以指示其已被选中。
我已经在使用jQuery了,所以我认为jQuery可选小部件是实现这一点的一种自然方式。不幸的是,它似乎不能让您控制用户可以选择的最大项目数,因此我不能限制用户在UI中选择一种颜色/大小的在线项目。
--以jQuery友好的方式(如果可能的话)实现此功能的最佳方法是什么?
发布于 2009-04-13 15:07:05
下面是如何使用渐进强化正确地做到这一点。这个想法很简单,为拥有JavaScript的用户,将一个被正确标记的HTML表单转换成更好的颜色和大小的样本按钮。
这种方法的好处很多,您可以轻松地切换或删除组件(JS/CSS),并且表单仍然可以工作。它将适用于那些不使用will javascript的用户,如果我们小心的话,它将可以通过键盘和屏幕阅读器访问。它在提交时也不需要额外的代码,在表单验证器中使用也要容易得多。
大部分的工作都是用CSS做的,只有最小的JavaScript来增加最后的工作。
完整的示例示例可以找到关于jsbin。它包括颜色和大小的选择。我只在这里包含了颜色,因为它们之间的CSS只有细微的差别。
首先,标记表单组件。下面是一些基本知识,您可能很明显想要添加一些东西,比如对整个小部件进行包装,或者使用其他类名。
<label>Color</label>
<ul class="radio color">
<li class="red">
<input type="radio" name="color" id="color_red" value="red" />
<label for="color_red">Red</label>
</li>
<li class="green">
<input type="radio" name="color" id="color_green" value="green" />
<label for="color_green">Green</label>
</li>
<!-- ...and so on... -->
</ul>
这对于“基础”来说可能是很多的,但是这里有几件事情要做。整个UL
容器被标记为“收音机”,因此可以使用CSS ("ul.radio label"
)适当地针对内部的所有内容。
此外,我还添加了一个与输入名称相对应的类,并在每个LI
上添加了一个类,以响应该值,从而允许CSS添加适当的样式("ul.color li.red"
)。其余的基本上是您的标准表单标记。
JavaScript
JavaScript非常简单。我们所做的就是检测当前选择了哪个无线电输入,并用一个“选择”类标记容器LI
,从而允许CSS适当地突出显示它。
jQuery(function($){
// notify CSS that JS is present
$( 'body' ).addClass( 'js-active' );
// for every radio control...
$( 'ul.radio' )
// redo every change
.bind('click', function () {
// refresh "current classes"
$( 'li', this ).removeClass( 'selected' )
.filter( ':has(:checked)' ).addClass( 'selected' );
})
// trigger initial run
.trigger( 'click' );
});
请注意:这种触发单击以执行初始运行的“技巧”可能是不安全的,如果您有更高的单击处理程序(通常是document.body
),我使用此方法是为了简洁。
这就是真正的魔法发生的地方。我们的想法是,我们可以将输入控件从视图中移开,并将标签设置为彩色按钮。只要标签上的for
属性正确地指向输入端的id
属性,那么单击标签就足以正确选择控件。
我们需要只针对".js-active"
内部的东西,这样没有JavaScript但仍然有CSS的用户将看到无线电输入元素。可以在UL
包装器上添加某种类型的“.”类,以完成相同的任务。
首先,让按钮浮起来,让它们看起来更像按钮:
/* attributes are lined up horizontally */
ul.color li,
ul.size li {
border : 1px solid #aaa;
margin : 0 4px 0 0;
padding : 2px;
float : left;
overflow : hidden;
position : relative;
}
我们将position:relative
和overflow:hidden
放在每个LI上,这样就可以将输入元素移出视图。这将保持它的可访问性,但我们不再需要查看它:
/* if JS: remove inputs from sight */
.js-active ul.color input,
.js-active ul.size input {
position : absolute;
left : -999em;
}
下一步是把标签变成按钮:
/* if JS: turn color labels into buttons */
.js-active ul.color label {
cursor : pointer;
display : block;
height : 18px;
width : 18px;
text-indent : -999em; /* hide text */
}
/* color buttons in color -- allowed even if no JS */
ul.color li.red label { background : red; }
ul.color li.green label { background : green; }
ul.color li.blue label { background : blue; }
最后,为突出显示的/选定的项设置一些样式。
/* if JS: current selected highlight */
.js-active ul.color .selected,
.js-active ul.size .selected {
border : 2px solid #000;
padding : 1px;
}
为了完整性:如果您想要添加更多的效果,获取选择值将在其他地方演示。
发布于 2009-04-11 19:34:47
虽然不幸的是,jQuery选择并不是很直观,但是可以选择:
$('#selectable').selectable({
selected: function(event, ui) {
var total = $(ui.selected).siblings('li.ui-selected').length + 1;
if(total > 1) {
$(ui.selected).removeClass('ui-selected');
}
}
});
这将停止在可选择的小部件上进行超过1项选择的任何操作。
剩下的只是根据您的特定需求定制它。
编辑:我有点无聊,所以我实现了更多,这样你就能有一个想法了。
查看一个工作演示。有很多重复的事情所做的大小和颜色,你可能可以摆脱,但我想让他们分开,因为我可以想象事情可能改变之间。不管怎样,这应该会给你一个很好的开始。
发布于 2009-04-11 20:53:55
如果您的目标是只允许选择一个项目,这将执行以下操作:
$(function() {
$("#selectable").selectable({
// this will prevent selecting a second item (for dragging\clicking)
selecting: function(event,ui) {
if ($(ui.selecting).siblings("li.ui-selecting").length > 0)
$(ui.selecting).removeClass("ui-selecting");
},
// this will prevent selecting a second item (for CTRL+Click)
selected: function(event,ui) {
if ($(ui.selected).siblings("li.ui-selected").length > 0)
$(ui.selected).removeClass("ui-selected");
},
// this will prevent un-selecting items (one item must be selected)
unselected: function(event,ui) {
if ($(ui.unselected).siblings("li.ui-selecting").length == 0)
$(ui.unselected).addClass("ui-selected");
}
})
});
此代码将允许选择单个项,并且它将防止通过鼠标拖动或使用CTRL+click选择另一项。它还将防止未选择的项目。它的行为与亚马逊的行为非常相似。
您可以使用stop
事件在选定项后在页面上执行更改(类似于JQuery UI附带的示例)。
https://stackoverflow.com/questions/717988
复制相似问题