在我的在线商店中,我想实现一个类似于亚马逊的界面来选择产品尺寸和颜色。即,用户应该看到一堆小框,而不是用于不同尺寸/颜色的单选按钮,每个小框包含颜色样本或尺寸名称。当用户单击一个框时,边框应更改以指示它已被选中。
我已经在使用 jQuery,所以我认为jQuery 可选小部件将是实现这一点的自然方式。不幸的是,它似乎无法让您控制用户可以选择的最大项目数,因此我无法限制用户在 UI 中在线选择一种颜色/尺寸。
以 jQuery 友好的方式(如果可能)实现此功能的最佳方式是什么?
在我的在线商店中,我想实现一个类似于亚马逊的界面来选择产品尺寸和颜色。即,用户应该看到一堆小框,而不是用于不同尺寸/颜色的单选按钮,每个小框包含颜色样本或尺寸名称。当用户单击一个框时,边框应更改以指示它已被选中。
我已经在使用 jQuery,所以我认为jQuery 可选小部件将是实现这一点的自然方式。不幸的是,它似乎无法让您控制用户可以选择的最大项目数,因此我无法限制用户在 UI 中在线选择一种颜色/尺寸。
以 jQuery 友好的方式(如果可能)实现此功能的最佳方式是什么?
以下是如何使用渐进式增强正确执行此操作。这个想法很简单,将一个标记得体的 HTML 表单变成更好的颜色和大小的样本按钮,供拥有 JavaScript 的用户使用。
这种方法的好处很多,您可以轻松切换或删除组件(JS/CSS)并且让表单仍然有效。它适用于不使用 javascript 的用户,如果我们小心的话,它可以通过键盘和屏幕阅读器访问。它在提交时也不需要额外的代码,并且与表单验证器一起使用会更容易。
大部分工作都是用 CSS 完成的,只用最少的 JavaScript 来添加最后的润色。
完整的工作示例可以在 jsbin 上找到。它包括颜色和尺寸选择。我在这里只包含了颜色,因为它们之间的 CSS 只有细微的差别。
的HTML
首先,标记表单组件。这是基础知识,您可能显然想要添加一些东西,例如围绕整个小部件的包装器,或使用其他类名。
<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>
对于“基础知识”来说,这似乎很多,但这里发生了几件事。整个容器被标记为“无线电”,因此可以使用 CSS ( )UL
适当地定位其中的所有内容。"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
,为了简洁起见,我使用这种方法。
CSS
这是真正的魔法发生的地方。这个想法是我们可以将输入控件隐藏起来,并将标签设置为颜色按钮。只要for
标签上的属性正确指向id
输入上的 ',然后单击标签就足以正确选择控件。
我们只需要在内部定位事物,".js-active"
以便没有 JavaScript 但仍然有 CSS 的用户可以看到单选输入元素。或者可以在包装器上添加某种“.radio-js”类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;
}
我们在每个 LI 上放置position:relative
和overflow:hidden
,以便我们可以将输入元素移出视图。这将使其可访问,但我们不再需要查看它:
/* 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;
}
为了完整性:如果您想添加更多效果,获取选择值在 SO 的其他地方进行了演示。
可以让 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 次选择。
其余的只是根据您的特定需求对其进行定制。
编辑:我有点无聊,所以我实施了更多,所以你可以得到一个想法。
查看一个工作演示。对尺寸和颜色所做的事情有很多重复,您可能可以摆脱它们,但我想将它们分开,因为我想事情可能会在两者之间发生变化。无论如何,这应该给你一个很好的开始。
如果您的目标是只允许选择一项,则可以这样做:
$(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+单击来选择另一个项目。它还将防止取消选择项目。它的行为与亚马逊的行为非常相似。
您可以在stop
选择项目后使用该事件在页面上执行更改(类似于 JQuery UI 附带的示例)。