I came across this control while using a webapp (this in invite-only beta) and liked the UI interaction. The webapp was built using 开发者_Go百科prototype/scriptaculous, and we typically use jQuery when building our web apps.. my question is, has anyone seen a jQuery equivalent to this UI element?
A couple of the nice things I like about this approach, instead of the typical radioset approach, is the animated sliding effect of the switch button and still being able to slide on a double-click and the resize cursor.
Since I don't have a working example of the element, I've attached a link to view a screen cap of it in action. :)
http://www.youtube.com/watch?v=kdyBodu4bSM
What I'm looking for is a jQuery plugin that can accomplish the same thing.. or a code snippet of something like this in jQuery. Thanks!
Well, it's certainly not easy to make yourself. Not easy, but quite fun. This is my first attempt at creating a plugin so please excuse the poor code quality. The code uses (but is not an extension of) jQuery UI. Specifically, it uses the draggable component for the handle, and some UI CSS classes.
This is certainly a work in progress. It is by no means finished. These are the things I'd like to see done before declaring this thing done:
- Keyboard control for moving the handle, for accessibility reasons
- Implement WAI-RIA standards, again for accessibility
- Set up more options, maybe even events
- Refactor the code into something a little more manageable.
The first two are very important, and is the reason why this code shouldn't be used yet. You are, however, welcome to hack around the code and play around with it. All suggestions on how this thing might be made to work better are welcome.
Live demo: 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);
Check this out: http://papermashup.com/jquery-iphone-style-ajax-switch/
That should be exactly what you want. Or at least easily modifiable. Click "DEMO" further down the page to see it in action.
And for other interesting JQuery plugins check out these links: 40 useful JQuery Plugins: http://www.smashingmagazine.com/2010/04/27/45-useful-jquery-techniques-and-plugins/
20 Awesome JQuery buttons: http://speckyboy.com/2010/05/26/20-awesome-jquery-enhanced-css-button-techniques/
I constantly refer to them :)
Also check out the upcoming jQuery Mobile library. They'll have a control just like that one. Some time late October is when we should first see some output apparently.
jquery slider switch using 3 images
<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<link type="text/css" rel="stylesheet" href="style.css">
<script>
$(document).ready(function() {
$('.bool-slider .inset .control').click(function() {
if ($(this).parent().parent().hasClass('true')) {
$(this).parent().parent().addClass('false').removeClass('true');
}
else
{
$(this).parent().parent().addClass('true').removeClass('false');
}
});
});
</script>
</head>
<body>
<div class="bool-slider false">
<div class="inset">
<div class="control"></div>
</div>
</div>
</body>
</html>
css code
.bool-slider.true .inset
{
width:79px;
height: 31px;
background: url(images/On.png)no-repeat;
}
.bool-slider.true .inset .control
{
float: left;
}
.bool-slider.true .inset .control:after
{
content: 'On';
position: relative;
right: -135%;
top: 20%;
}
.bool-slider.false .inset
{
width:79px;
height: 31px;
background: url(images/Off.png)no-repeat;
}
.bool-slider.false .inset .control
{
float: right;
}
.bool-slider.false .inset .control:before
{
content: 'Off';
position: relative;
left: -100%;
top: 20%;
}
.bool-slider .inset .control
{
width: 40%;
height: 100%;
background: url(images/Button.png)no-repeat;
}
.bool-slider .inset .control:hover
{
cursor: pointer;
}
精彩评论