jQuery voting tools
Markup
Like anything, this can be done a number of ways. There’s not much semantic relevance here, so any sensible structure will do. The only real requirement is to have enough elements for styling and animation.
<div class="votecard"> <div><em><strong>293</strong><span>Flips</span></em></div> </div> <a class="voteaction">Flippit</a>
Background & CSS
I’ll just use one sprite for this tool. The top will serve as the background for the numeric value, the bottom area gives us backgrounds for the unclicked, hover and clicked states of the action button.
There’s nothing too tricky or innovative in the CSS below. However, the key technique here is the overflow:hidden rule on the “votecard” class’s child div (line 10). This will effectively serve as a mask which the animating objects will move across. More on that later.
.votecard { background: url(images/sprite.png) no-repeat 0 0; padding: 4px; width: 63px; height: 43px; text-align: center; } .votecard div { position: relative; overflow: hidden; width: 63px; height: 43px; } .votecard em { display: block; position: relative; width: 63px; height: 33px; padding: 6px 0 6px 0; font: normal 24px/24px "Helvetica Neue","Helvetica","Arial",Sans-serif; color: #45453f; } .votecard strong { font-weight: bold; } .votecard span { font-size: 10px; line-height: 10px; display: block; color: #9a9a94; } a.voteaction { margin: 0 0 0 3px; display: block; text-indent: -9999px; width: 71px; height: 21px; background: url(images/sprite.png) no-repeat -3px -75px; } a.voteaction:hover { outline: none; background-position: -3px -54px; } a.voted, a.voted:hover { outline: none; background-position: -3px -96px; cursor: default; }
jQuery
Now we’ll have some real fun and wire this up.
$(document).ready(function() { /* create a node for the flip-to number */ $(".votecard em").clone().appendTo(".votecard div"); /* increment that by 1 */ var node = $(".votecard em:last strong") node.text(parseInt(node.text())+1); function flip(obj) { obj.prev().find("em").animate({ top: '-=45' }, 200); obj.toggleClass("voted",true); } $('.voteaction').bind({ click: function(event) { event.preventDefault() }, mouseup: function() { flip($(this)); $(this).unbind('mouseup'); } }); });
Content duplication
You might have wondered why the next number (294) was not included in the original markup shown earlier. The answer is found in line 3 through 6. This code duplicates the <em> node containing the current vote value (293) then increments that value by one. This new <em> node is forced to flow beneath the original one, but is hidden from view as specified in the CSS above. Here’s what your browser sees after this code runs:
Button events
Two events will be bound to the “Flippit” button, and you’ll see why these events are kept separate shortly. The default browser response is disabled in the click event. The mouseup event handler will call the flip() function which will perform the animation. It is important to allow this function to be called once only. After the user has initiated a “flip”, this action should be immediately disabled.
Had we grouped the event.preventDefault() together with the flip() call in a single button event (on click for example), we’d reinstate the default browser response when we unbound that event from the button. This would likely result in a page refresh if the user clicked the button twice. Keeping these events separate lets us unbind just the flipping action while preserving event.preventDefault().
Flip tha script *
The flip() function’s task is to select both <em>s and then move them up a distance of 45 pixels. Note also that this function takes as an argument a jQuery object reference to the button which called it. From this, we can traverse to select the <em>s we want to animate. The top <em> will slide out of view, while the jQuery generated one slides into view. The process is completed by toggling the button’s class name to “voted”.
What’s this good for?
This adds a little tactility to these contraptions. It reinforces the notion that you just impacted a piece of content on the web, if only by one solitary unit. If it’s good enough for sports apps, it’s good enough for anything else.
This technique could be used for anything where a numeric value increases or decreases whether it results from user interaction or not (as in live scoreboards).
You might also like
Tags
accordion accordion menu animation navigation animation navigation menu carousel checkbox inputs css3 css3 menu css3 navigation date picker dialog drag drop drop down menu drop down navigation menu elastic navigation form form validation gallery glide navigation horizontal navigation menu hover effect image gallery image hover image lightbox image scroller image slideshow multi-level navigation menus rating select dependent select list slide image slider menu stylish form table tabs text effect text scroller tooltips tree menu vertical navigation menu