Last active
June 8, 2016 17:18
-
-
Save bob-moore/acc265981542f623838f5eec4baf347f to your computer and use it in GitHub Desktop.
Toggle Element inside clickable div
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="togglevisible" data-click-target=".inner"> | |
<p>alksjdfkajsdfkaskdfj</p> | |
<div class="inner"> | |
<p>this is a paragraph</p> | |
<a href="http://google.com" target="_blank">link</a> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.inner { | |
opacity: 0; | |
visibility: hidden; | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
background: rgba( #000, .3 ); | |
z-index: 0; | |
transform: translate3d( 0, 0, 0 ); | |
transition: opacity .4s ease, z-index .4s ease; | |
&.expose, &.exposed { | |
visibility: visible; | |
z-index: 9999; | |
opacity: 1; | |
} | |
&.conceal { | |
visibility: visible; | |
opacity: 0; | |
z-index: 0; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function( $ ) { | |
'use strict'; | |
var ToggleVisible = ( function () { | |
$.map( $( '.togglevisible' ), function( element ) { | |
return new Toggle( element ); | |
}); | |
function Toggle( el ) { | |
// Cache dom tree | |
var $el = $( el ); | |
var $body = $( 'body' ); | |
var $target = $el.data( 'click-target' ) !== undefined ? $el.find( $el.data( 'click-target' ) ) : null; | |
var complete = false; | |
var transitionEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend transitionend'; | |
// Bind Handlers | |
$el.on( 'click', toggleState ); | |
// Define state change | |
function toggleState( event ) { | |
// If we can't find a target, just return | |
if( $target === null ) { | |
return false; | |
} | |
var $clicktarget = $el.find( event.target ); | |
// If the target of the click is a link, or child of link just return | |
if( $clicktarget.is( 'a' ) || $clicktarget.closest( 'a' ).length ) { | |
return true; | |
} | |
// Else let's keep this puppy from reloading | |
event.preventDefault(); | |
complete = false; | |
switch( $target.hasClass( 'expose' ) || $target.hasClass( 'exposed' ) ) { | |
case true : | |
// Show the element with callback to remove click handler on body | |
concealElement(); | |
break; | |
case false : | |
// Expose element with callback to set click handler on body | |
exposeElement(); | |
break; | |
default : | |
break; | |
} | |
} | |
function exposeElement() { | |
// Set click handler on body to close | |
$body.on( 'click', clickOut ); | |
// Add classes to individual elements | |
$target.addClass( 'expose' ).removeClass( 'exposed conceal concealed' ).one( transitionEnd, function() { | |
$target.addClass( 'exposed' ).removeClass( 'expose' ); | |
complete = true; | |
return true; | |
}); | |
// Set timeout in case ending events dont fire | |
setTimeout( function() { | |
// If transition is already complete, lets bail | |
if( complete === true ) { | |
return true; | |
} | |
// If the class we need to remove was already removed by something else, let's bail | |
if( !$target.hasClass( 'expose' ) ) { | |
$target.off( transitionEnd ); | |
return true; | |
} | |
// If we made it here, we have some cleanup to do | |
$target.addClass( 'exposed' ).removeClass( 'expose conceal concealed' ).off( transitionEnd ); | |
}, 1000 ); | |
return true; | |
} | |
function concealElement() { | |
// Remove click handler on body to close | |
$body.off( 'click', clickOut ); | |
// Add classes to individual elements | |
$target.addClass( 'conceal' ).removeClass( 'concealed exposed expose' ).one( transitionEnd, function() { | |
$target.addClass( 'concealed' ).removeClass( 'conceal' ); | |
complete = true; | |
return true; | |
}); | |
// Set timeout in case ending events dont fire | |
setTimeout( function() { | |
// If transition is already complete, lets bail | |
if( complete === true ) { | |
return true; | |
} | |
// If the class we need to remove was already removed by something else, let's bail | |
if( !$target.hasClass( 'conceal' ) ) { | |
$target.off( transitionEnd ); | |
return true; | |
} | |
// If we made it here, we have some cleanup to do | |
$target.addClass( 'concealed' ).removeClass( 'conceal exposed expose' ).off( transitionEnd ); | |
}, 1000 ); | |
return true; | |
} | |
function clickOut( event ) { | |
if( !$el.is( event.target ) && !$el.find( event.target ).length ) { | |
concealElement(); | |
} | |
} | |
} | |
})(); | |
})( jQuery ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment