Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts
Saturday, 10 October 2015
Flip Wall With jQuery & CSS
Designing and coding a sponsors page is part of the developer’s life (at least the lucky developer’s life, if it is about a personal site of theirs). It, however, follows different rules than those for the other pages of the site. You have to find a way to fit a lot of information and organize it clearly, so that the emphasis is put on your sponsors, and not on other elements of your design.
We are using PHP, CSS and jQuery with the jQuery Flip plug-in, to do just that. The resulting code can be used to showcase your sponsors, clients or portfolio projects as well.
Step 1 – XHTML
Most of the markup is generated by PHP for each of the sponsors after looping the main $sponsor array. Below you can see the code that would be generated and outputted for Google:
demo.php
<div title="Click to flip" class="sponsor">
<div class="sponsorFlip">
<img alt="More about google" src="img/sponsors/google.png">
</div>
<div class="sponsorData">
<div class="sponsorDescription">
The company that redefined web search.
</div>
<div class="sponsorURL">
<a href="http://www.google.com/">http://www.google.com/ </a>
</div>
</div>
</div>
The outermost .sponsor div contains two additional div elements. The first – sponsorFlip – contains the company logo. Every click on this element causes the Flip effect to be initiated, as you will see in the jQuery part of the tutorial.
Maybe more interesting is the sponsorData div. It is hidden from view with a display:none CSS rule, but is accessible to jQuery. This way we can pass the description and the URL of the sponsoring company to the front end. After the flipping animation is complete, the contents of this div is dynamically inserted intosponsorFlip.
Step 2 – CSS
We can start laying down the styling of the wall, as without it there is no much use of the page. The code is divided in two parts. Some classes are omitted for clarity. You can see all the styles used by the demo instyles.css in the download archive.
styles.css – Part 1
body{
/* Setting default text color, background and a font stack */
font-size:0.825em;
color:#666;
background-color:#fff;
font-family:Arial, Helvetica, sans-serif;
}
.sponsorListHolder{
margin-bottom:30px;
}
.sponsor{
width:180px;
height:180px;
float:left;
margin:4px;
/* Giving the sponsor div a relative positioning: */
position:relative;
cursor:pointer;
}
.sponsorFlip{
/* The sponsor div will be positioned absolutely with respect
to its parent .sponsor div and fill it in entirely */
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
border:1px solid #ddd;
background:url("img/background.jpg") no-repeat center center #f9f9f9;
}
.sponsorFlip:hover{
border:1px solid #999;
/* CSS3 inset shadow: */
-moz-box-shadow:0 0 30px #999 inset;
-webkit-box-shadow:0 0 30px #999 inset;
box-shadow:0 0 30px #999 inset;
}
After styling the sponsor and sponsorFlip divs, we add a :hover state for the latter. We are using CSS3 inset box-shadow to mimic the inner shadow effect you may be familiar with from Photoshop. At the moment of writing inset shadows only work in the latest versions of Firefox, Opera and Chrome, but being primarily a visual enhancement, without it the page is still perfectly usable in all browsers.
styles.css – Part 2
.sponsorFlip img{
/* Centering the logo image in the middle of the .sponsorFlip div */
position:absolute;
top:50%;
left:50%;
margin:-70px 0 0 -70px;
}
.sponsorData{
/* Hiding the .sponsorData div */
display:none;
}
.sponsorDescription{
font-size:11px;
padding:50px 10px 20px 20px;
font-style:italic;
}
.sponsorURL{
font-size:10px;
font-weight:bold;
padding-left:20px;
}
.clear{
/* This class clears the floats */
clear:both;
}
As mentioned earlier, the sponsorData div is not meant for viewing, so it is hidden with display:none. Its purpose is to only store the data which is later extracted by jQuery and displayed at the end of the flipping animation.
Step 3 – PHP
You have many options in storing your sponsors data – in a MySQL database, XML document or even a plain text file. These all have their benefits and we’ve used all of them in the previous tutorials (except XML storage, note to self).
However, the sponsor data is not something that changes often. This is why a different approach is needed. For the purposes of the task at hand, we are using a multidimensional array with all the sponsor information inside it. It is easy to update and even easier to implement:
demo.php – Part 1
// Each sponsor is an element of the $sponsors array:
$sponsors = array(
array('facebook','The biggest social..','http://www.facebook.com/'),
array('adobe','The leading software de..','http://www.adobe.com/'),
array('microsoft','One of the top software c..','http://www.microsoft.com/'),
array('sony','A global multibillion electronics..','http://www.sony.com/'),
array('dell','One of the biggest computer develo..','http://www.dell.com/'),
array('ebay','The biggest online auction and..','http://www.ebay.com/'),
array('digg','One of the most popular web 2.0..','http://www.digg.com/'),
array('google','The company that redefined w..','http://www.google.com/'),
array('ea','The biggest computer game manufacturer.','http://www.ea.com/'),
array('mysql','The most popular open source dat..','http://www.mysql.com/'),
array('hp','One of the biggest computer manufacturers.','http://www.hp.com/'),
array('yahoo','The most popular network of so..','http://www.yahoo.com/'),
array('cisco','The biggest networking and co..','http://www.cisco.com/'),
array('vimeo','A popular video-centric social n..','http://www.vimeo.com/'),
array('canon','Imaging and optical technology ma..','http://www.canon.com/')
);
// Randomizing the order of sponsors:
shuffle($sponsors);
The sponsors are grouped into the main $sponsors array. Each sponsor entry is organized as a separate regular array. The first element of that array is the unique key of the sponsor, which corresponds to the file name of the logo. The second element is a description of the sponsor and the last is a link to the sponsor’s website.
After defining the array, we use the in-build shuffle() PHP function to randomize the order in which the sponsors are displayed.
demo.php – Part 2
// Looping through the array:
foreach($sponsors as $company)
{
echo'
<div class="sponsor" title="Click to flip">
<div class="sponsorFlip">
<img src="img/sponsors/'.$company[0].'.png" alt="More about '.$company[0].'" />
</div>
<div class="sponsorData">
<div class="sponsorDescription">
'.$company[1].'
</div>
<div class="sponsorURL">
<a href="'.$company[2].'">'.$company[2].'</a>
</div>
</div>
</div>
';
}
The code above can be found halfway down demo.php. It basically loops through the shuffled $sponsorsarray and outputs the markup we discussed in step one. Notice how the different elements of the array are inserted into the template.
Step 4 – jQuery
The jQuery Flip plugin requires both the jQuery library and jQuery UI. So, after including those in the page, we can move on with writing the code that will bring our sponsor wall to life.
script.js
$(document).ready(function(){
/* The following code is executed once the DOM is loaded */
$('.sponsorFlip').bind("click",function(){
// $(this) point to the clicked .sponsorFlip element (caching it in elem for speed):
var elem = $(this);
// data('flipped') is a flag we set when we flip the element:
if(elem.data('flipped'))
{
// If the element has already been flipped, use the revertFlip method
// defined by the plug-in to revert to the default state automatically:
elem.revertFlip();
// Unsetting the flag:
elem.data('flipped',false)
}
else
{
// Using the flip method defined by the plugin:
elem.flip({
direction:'lr',
speed: 350,
onBefore: function(){
// Insert the contents of the .sponsorData div (hidden
// from view with display:none) into the clicked
// .sponsorFlip div before the flipping animation starts:
elem.html(elem.siblings('.sponsorData').html());
}
});
// Setting the flag:
elem.data('flipped',true);
}
});
});
First we bind a function as a listener for the click event on the .sponsorFlip divs. After a click event occurs, we check whether the flipped flag is set via the jquery data() method. This flag is set individually for eachsponsorFlip div and helps us determine whether the div has already been flipped. If this is so, we use therevertFlip() method which is defined by the Flip plugin. It returns the div to its previous state.
If the flag is not present, however, we initiate a flip on the element. As mentioned earlier, the .sponsorDatadiv, which is contained in every sponsor div, contains the description and the URL of the sponsor, and is hidden from view with CSS. Before the flipping starts, the plug-in executes the onBefore function we define in the configuration object that is passed as a parameter (line 29). In it we change the content of thesponsorFlip div to the one of sponsorData div, which replaces the logo image with information about the sponsor.
With this our sponsor flip wall is complete!
Conclusion
Today we used the jQuery Flip plug-in to build a sponsor wall for your site. You can use this example to bring interactivity to your site’s pages. And as the data for the wall is read from an array, you can easily modify it to work with any kind of database or storage.
What do you think? How would you modify this code?
7 Essential, Most Important JavaScript Functions
I remember the early days of JavaScript where you needed a simple function for just about everything because the browser vendors implemented features differently, and not just edge features, basic features, like
Read More
addEventListener and attachEvent. Times have changed but there are still a few functions each developer should have in their arsenal, for performance for functional ease purposes.
debounce
The debounce function can be a game-changer when it comes to event-fueled performance. If you aren't using a debouncing function with a
scroll, resize, key* event, you're probably doing it wrong. Here's a debounce function to keep your code efficient:// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; // Usage var myEfficientFn = debounce(function() { // All the taxing stuff you do }, 250); window.addEventListener('resize', myEfficientFn);
The
debounce function will not allow a callback to be used more than once per given time frame. This is especially important when assigning a callback function to frequently-firing events.
poll
As I mentioned with the
debounce function, sometimes you don't get to plug into an event to signify a desired state -- if the event doesn't exist, you need to check for your desired state at intervals:function poll(fn, callback, errback, timeout, interval) { var endTime = Number(new Date()) + (timeout || 2000); interval = interval || 100; (function p() { // If the condition is met, we're done! if(fn()) { callback(); } // If the condition isn't met but the timeout hasn't elapsed, go again else if (Number(new Date()) < endTime) { setTimeout(p, interval); } // Didn't match and too much time, reject! else { errback(new Error('timed out for ' + fn + ': ' + arguments)); } })(); } // Usage: ensure element is visible poll( function() { return document.getElementById('lightbox').offsetWidth > 0; }, function() { // Done, success callback }, function() { // Error, failure callback } );
Polling has long been useful on the web and will continue to be in the future!
once
There are times when you prefer a given functionality only happen once, similar to the way you'd use an
onload event. This code provides you said functionality:function once(fn, context) { var result; return function() { if(fn) { result = fn.apply(context || this, arguments); fn = null; } return result; }; } // Usage var canOnlyFireOnce = once(function() { console.log('Fired!'); }); canOnlyFireOnce(); // "Fired!" canOnlyFireOnce(); // nada
The
once function ensures a given function can only be called once, thus prevent duplicate initialization!
getAbsoluteUrl
Getting an absolute URL from a variable string isn't as easy as you think. There's the
URLconstructor but it can act up if you don't provide the required arguments (which sometimes you can't). Here's a suave trick for getting an absolute URL from and string input:var getAbsoluteUrl = (function() { var a; return function(url) { if(!a) a = document.createElement('a'); a.href = url; return a.href; }; })(); // Usage getAbsoluteUrl('/something'); // http://davidwalsh.name/something
The "burn" element
href handles and URL nonsense for you, providing a reliable absolute URL in return.
isNative
Knowing if a given function is native or not can signal if you're willing to override it. This handy code can give you the answer:
;(function() { // Used to resolve the internal `[[Class]]` of values var toString = Object.prototype.toString; // Used to resolve the decompiled source of functions var fnToString = Function.prototype.toString; // Used to detect host constructors (Safari > 4; really typed array specific) var reHostCtor = /^\[object .+?Constructor\]$/; // Compile a regexp using a common native method as a template. // We chose `Object#toString` because there's a good chance it is not being mucked with. var reNative = RegExp('^' + // Coerce `Object#toString` to a string String(toString) // Escape any special regexp characters .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&') // Replace mentions of `toString` with `.*?` to keep the template generic. // Replace thing like `for ...` to support environments like Rhino which add extra info // such as method arity. .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); function isNative(value) { var type = typeof value; return type == 'function' // Use `Function#toString` to bypass the value's own `toString` method // and avoid being faked out. ? reNative.test(fnToString.call(value)) // Fallback to a host object check because some environments will represent // things like typed arrays as DOM methods which may not conform to the // normal native pattern. : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false; } // export however you want module.exports = isNative; }()); // Usage isNative(alert); // true isNative(myCustomFunction); // false
The function isn't pretty but it gets the job done!
insertRule
We all know that we can grab a NodeList from a selector (via
document.querySelectorAll) and give each of them a style, but what's more efficient is setting that style to a selector (like you do in a stylesheet):var sheet = (function() { // Create the <style> tag var style = document.createElement('style'); // Add a media (and/or media query) here if you'd like! // style.setAttribute('media', 'screen') // style.setAttribute('media', 'only screen and (max-width : 1024px)') // WebKit hack :( style.appendChild(document.createTextNode('')); // Add the <style> element to the page document.head.appendChild(style); return style.sheet; })(); // Usage sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
This is especially useful when working on a dynamic, AJAX-heavy site. If you set the style to a selector, you don't need to account for styling each element that may match that selector (now or in the future).
matchesSelector
Oftentimes we validate input before moving forward; ensuring a truthy value, ensuring forms data is valid, etc. But how often do we ensure an element qualifies for moving forward? You can use a
matchesSelector function to validate if an element is of a given selector match:function matchesSelector(el, selector) { var p = Element.prototype; var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { return [].indexOf.call(document.querySelectorAll(s), this) !== -1; }; return f.call(el, selector); } // Usage matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')
There you have it: seven JavaScript functions that every developer should keep in their toolbox. Have a function I missed? Please share it!
Subscribe to:
Comments
(
Atom
)
Blog Archive
-
2015
(11)
-
October
(11)
- How To Create A WordPress Plugin
- WordPress Custom Post Type Complete - Easy Way
- How to Create CSS Sliding Background Effect
- 10 PHP Tips Every W.Developer Should Know :)
- Flip Wall With jQuery & CSS
- 7 Essential, Most Important JavaScript Functions
- jQuery topLink Plugin
- Layers vs. Artboards: ADOBE ILLUSTRATOR
- Regular Expressions ~ Hands On!
- Clipboard.js makes it easy to copy and cut text fr...
- Unraveling the Secrets of WordPress' Comments.php ...
-
October
(11)
© Xe Blog 2013 . Powered by Bootstrap Blogger templates and RWD Testing Tool



