Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialBrad Woods
13,772 PointsInspiration for Article Intro Effects - Deciphering Code
After watching the Treehouse show I've been trying to work out the JavaScript for 'Inspiration for Article Intro Effect' - http://tympanus.net/codrops/2014/05/22/inspiration-for-article-intro-effects/. The code is below - (function() {
// detect if IE : from http://stackoverflow.com/a/16657946
// Thus, to detect IE:
// if (ie) {}
// And to detect the version:
// ie === 6 // IE6
// ie > 7 // IE8, IE9, IE10 ...
// ie < 9 // Anything less than IE9
var ie = (function(){
var undef,rv = -1; // Return value assumes failure.
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
var trident = ua.indexOf('Trident/');
if (msie > 0) {
// IE 10 or older => return version number
rv = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
} else if (trident > 0) {
// IE 11 (or newer) => return version number
var rvNum = ua.indexOf('rv:');
rv = parseInt(ua.substring(rvNum + 3, ua.indexOf('.', rvNum)), 10);
}
return ((rv > -1) ? rv : undef);
}());
// disable/enable scroll (mousewheel and keys) from http://stackoverflow.com/a/4770179
// left: 37, up: 38, right: 39, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = [32, 37, 38, 39, 40], wheelIter = 0;
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function keydown(e) {
for (var i = keys.length; i--;) {
if (e.keyCode === keys[i]) {
preventDefault(e);
return;
}
}
}
function touchmove(e) {
preventDefault(e);
}
function wheel(e) {
// for IE
//if( ie ) {
//preventDefault(e);
//}
}
function disable_scroll() {
window.onmousewheel = document.onmousewheel = wheel;
document.onkeydown = keydown;
document.body.ontouchmove = touchmove;
}
function enable_scroll() {
window.onmousewheel = document.onmousewheel = document.onkeydown = document.body.ontouchmove = null;
}
var docElem = window.document.documentElement,
scrollVal,
isRevealed,
noscroll,
isAnimating,
container = document.getElementById( 'container' ),
trigger = container.querySelector( 'button.trigger' );
function scrollY() {
return window.pageYOffset || docElem.scrollTop;
}
function scrollPage() {
scrollVal = scrollY();
if( noscroll && !ie ) {
if( scrollVal < 0 ) return false;
// keep it that way
window.scrollTo( 0, 0 );
}
if( classie.has( container, 'notrans' ) ) {
classie.remove( container, 'notrans' );
return false;
}
if( isAnimating ) {
return false;
}
if( scrollVal <= 0 && isRevealed ) {
toggle(0);
}
else if( scrollVal > 0 && !isRevealed ){
toggle(1);
}
}
function toggle( reveal ) {
isAnimating = true;
if( reveal ) {
classie.add( container, 'modify' );
}
else {
noscroll = true;
disable_scroll();
classie.remove( container, 'modify' );
}
// simulating the end of the transition:
setTimeout( function() {
isRevealed = !isRevealed;
isAnimating = false;
if( reveal ) {
noscroll = false;
enable_scroll();
}
}, 600 );
}
// refreshing the page...
var pageScroll = scrollY();
noscroll = pageScroll === 0;
disable_scroll();
if( pageScroll ) {
isRevealed = true;
classie.add( container, 'notrans' );
classie.add( container, 'modify' );
}
window.addEventListener( 'scroll', scrollPage );
trigger.addEventListener( 'click', function() { toggle( 'reveal' ); } );
})();
</script>
I'm not sure how this section of the code works -
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
I can't see where the function is being called or what is being passed into it. I understand the method 'e.preventDefault' but don't understand how it is being used here. Can anyone help? I'm keen to figure this script.
2 Answers
Dino Paškvan
Courses Plus Student 44,108 PointsOlder versions of Internet Explorer handled events differently. They didn't pass the event object into the handler function, instead, you'd have to check the window.event
property to see what the event was.
They also had a different mechanism for preventing the default reaction to the event, instead of the preventDefault
method, you'd use e.returnValue = false
.
This prevent function basically does all of that in one place, to keep the other event handling methods clean (keydown
, touchmove
, wheel
).
function preventDefault(e) {
e = e || window.event; // if an event object was passed, use that object, otherwise get it from window.event
if (e.preventDefault) { // if the browser supports e.preventDefault() use that
e.preventDefault();
}
e.returnValue = false; // in cases where preventDefault is not available, set e.returnValue to false
}
So, instead of having to write this piece of code for every handler, it was refactored into a function you can recycle throughout the rest of the code.
Brad Woods
13,772 PointsDo you have any idea why this was written without using JQuery. My understanding is that JQuery makes interacting with the DOM a lot easier/ produces more efficient code.
Dino Paškvan
Courses Plus Student 44,108 PointsjQuery makes it easier to write code, and the overall code is shorter but it's not really more efficient. Think about it, jQuery is a fairly large library (241.55 KB uncompressed for version 2.1.1). The user's browser will have to parse all of jQuery before it starts with this script.
This particular script is roughly 3 KB. Let's say the jQuery version is half of that — 1.5 KB. That sounds great, but the user will have to download whole jQuery on top of that — over 243 KB for a handful of effects that amount to 3 KB of vanilla JavaScript.
Sure, computers are fast these days, and Internet speeds are decent all over the world, but throw in the mobile users and things change a bit.
I always avoid jQuery unless I really need it. There are fewer browser quirks, they adhere to standards more than ever and in many cases you can easily write vanilla JavaScript.
Even when I use jQuery, I often find that I have no idea how it does certain things. Then I have to go through the code of the library to figure out if that's really what I want.
Writing vanilla JavaScript will always be more optimised (if you know what you're doing), you'll know exactly how things work, your users' traffic will go down, as will your server's.
Frankly, the amount of JS libraries that depend on jQuery is ridiculous. Half of them require you to use jQuery because of one line of code that could be polyfilled with two additional lines of code. So you get stuck with a whole library full of stuff that you don't need (in most cases).
Brad Woods
13,772 PointsBrad Woods
13,772 PointsCould you detail how the event object is being passed into the function without an event handler preceding it?
Dino Paškvan
Courses Plus Student 44,108 PointsDino Paškvan
Courses Plus Student 44,108 PointsThose three functions I mentioned are set as event handlers in the
disable_scroll()
function:The browser automatically sends event objects to event handlers. That object gets passed on by those functions to the
preventDefault
function.