Skip to content

Instantly share code, notes, and snippets.

@bob-moore
Last active June 8, 2016 17:18
Show Gist options
  • Save bob-moore/acc265981542f623838f5eec4baf347f to your computer and use it in GitHub Desktop.
Save bob-moore/acc265981542f623838f5eec4baf347f to your computer and use it in GitHub Desktop.
Toggle Element inside clickable div
<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>
.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;
}
}
( 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