嗯,这是当然不容易让自己。不容易,但很有趣。这是我第一次尝试创建插件,请原谅糟糕的代码质量。该代码使用(但不是jQuery UI的扩展)。具体来说,它使用可拖动组件的句柄和一些UI CSS类。
这当然是一项正在进行的工作。这决不是完成的。这是我想看到宣布这件事情做以前做过的事情:
- 移动手柄键盘控制,可访问性的原因
- 实现WAI-RIA标准,再次为无障碍
- 设置更多的选择,甚至可能是事件
- 将代码重构成更易于管理的东西。
前两个是非常重要的,这就是为什么这个代码不应该使用的原因。不过,欢迎您对代码进行破解并使用它。所有有关如何使这件事情更好地工作的建议值得欢迎。
现场演示:http://jsfiddle.net/RDkBL/7/
(function($) {
$.fn.slideButton = function(options) {
// Settings
var settings = $.extend({
slideSpeed: 10,
revertSpeed: 5,
labelWidth: 0
}, options);
this.each(function() {
var container = $(this);
var label = container.children('label');
var input = container.children(':radio');
var maxWidth = 0;
if (label.length != 2 || input.length != 2) {
throw new Error("The container must contain two radio buttons and two labels");
}
// move() does the animation associated with
// state changing for the button
function move(direction, speed) {
var amount = direction === 'right' ? halfWidth : -1;
var duration = (direction === 'right' ? halfWidth - handle.position().left : handle.position().left) * speed;
handle.animate({
left: amount
}, duration);
input.eq(direction === 'right' ? 0 : 1).attr('checked', true);
}
// Handles changing by checking current state
function updateState() {
move(handle.hasClass('on') ? 'right' : 'left', settings.slideSpeed);
handle.toggleClass('on');
return false;
}
// Reverts position - think of this as
// the opposite of updateState()
function revert() {
move(handle.hasClass('on') ? 'left' : 'right', settings.revertSpeed);
return false;
}
// Adding classes and hiding input elements
container.addClass('ui-sbutton-container ui-corner-all');
input.addClass('ui-helper-hidden-accessible');
label.addClass('ui-sbutton-label');
// Setting label widths - if none set,
// then loop through all of them and use the biggest
if (settings.labelWidth) {
maxWidth = settings.labelWidth;
} else {
label.each(function() {
var w = $(this).outerWidth();
if (w > maxWidth) {
maxWidth = w;
}
});
}
// Padding was useful for finding largest width,
// but will now interfere when setting explicit widths
label.width(maxWidth).css({
'padding-left': 0,
'padding-right': 0
});
// Getting all important half width for later use
var halfWidth = (container.outerWidth()/2);
// Very messy chain that does element creation,
// insertion and event handling all at once
var handle = $('<a />')
.addClass('ui-sbutton-handle ui-corner-all').hover(function() {
$(this).toggleClass('ui-sbutton-active');
}).dblclick(function(){
updateState();
return false;
}).appendTo(container).width(maxWidth - 1).draggable({
containment: 'parent',
axis: 'x',
stop: function(event, ui) {
var left = $(this).position().left;
if ((left > (halfWidth - 1)/2 && handle.hasClass('on')) || (left < (halfWidth/2 - 1) && !handle.hasClass('on'))) {
updateState();
} else {
revert();
}
}
});
// Set up initial state of the button
if (input.first().is(':checked')) {
move('right', 0);
} else {
handle.addClass('on');
}
});
return this;
};})(jQuery);
非常好!使用jsFiddle测试代码总是很有趣:D感谢您花时间解决这个问题!我每天都在学习更多东西,并且非常感谢这方面的帮助。因为我的技能更多的体现在HTML5/CSS3/UX/UI领域。学习如何扩展jQuery是我不断努力的方向。我会更多地使用代码,如果你有能力/有时间解决你列出的问题,我很乐意提供任何帮助,我可以。再次感谢! – revive 2010-09-25 12:58:32