<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>jQuery.scrollable 1.1.1, demo (AMD)</title>
<meta name="description" content="jQuery.scrollable 1.1.1, demo (AMD)">
<!-- ATTN Foundation loaded without JS - stay clear of JS-driven widgets, or add the JS setup -->
<!--
ATTN jQuery 1.x is used here, making the demo compatible with oldIE. As a side effect,
Foundation 5 JS can't be used reliably (requires jQuery 2.x). Stay clear, or switch to
jQuery 2.x.
-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/css/normalize.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/css/foundation.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/hashchange/jquery.scrollable/1.1.1/demo/amd/amd.css">
<!-- Fix HTML5 tags in oldIE and other lacking legacy browsers -->
<script src="http://modernizr.com/downloads/modernizr-latest.js"></script>
</head>
<body>
<section class="scroll-controls">
<ul class="button-group even-3">
<!-- Chaining mode -->
<!-- number -->
<li><a class="button mode default" data-mode="replace" href="#">replace</a></li>
<!-- px unit -->
<li><a class="button mode" data-mode="append" href="#">append</a></li>
<!-- percentage -->
<li><a class="button mode" data-mode="merge" href="#">merge</a></li>
</ul>
<hr>
<ul class="button-group even-3">
<!-- Relative movement, vertical down -->
<!-- number -->
<li><a class="button shift" data-y="+=100" href="#">↓<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-y="+=1000px" href="#">↓<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-y="+=25%" href="#">↓<br>25%</a></li>
</ul>
<ul class="button-group even-3">
<!-- Relative movement, horizontal right -->
<!-- number -->
<li><a class="button shift" data-x="+=100" href="#">→<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-x="+=1000px" href="#">→<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-x="+=25%" href="#">→<br>25%</a></li>
</ul>
<ul class="button-group even-3">
<!-- Relative movement, vertical up -->
<!-- number -->
<li><a class="button shift" data-y="-=100" href="#">↑<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-y="-=1000px" href="#">↑<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-y="-=25%" href="#">↑<br>25%</a></li>
</ul>
<ul class="button-group even-3">
<!-- Relative movement, horizontal left -->
<!-- number -->
<li><a class="button shift" data-x="-=100" href="#">←<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-x="-=1000px" href="#">←<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-x="-=25%" href="#">←<br>25%</a></li>
</ul>
<ul class="button-group even-3">
<!-- Relative movement, vertical and horizontal simultaneously -->
<!-- number -->
<li><a class="button shift" data-x="+=100" data-y="+=100" href="#">↘<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-x="+=1000px" data-y="+=1000px" href="#">↘<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-x="+=25%" data-y="+=25%" href="#">↘<br>25%</a></li>
</ul>
<ul class="button-group even-3">
<!-- Absolute movement, up or left -->
<!-- number -->
<li><a class="button jump" data-y="0" href="#">⇑</a></li>
<!-- px unit -->
<li><a class="button jump" data-x="0" href="#">⇐</a></li>
<!-- percentage -->
<li><a class="button jump" data-x="0" data-y="0" href="#">⇖</a></li>
</ul>
<ul class="button-group even-3">
<!-- Absolute movement, down or right -->
<!-- number -->
<li><a class="button jump" data-y="bottom" href="#">⇓</a></li>
<!-- px unit -->
<li><a class="button jump" data-x="right" href="#">⇒</a></li>
<!-- percentage -->
<li><a class="button jump" data-x="right" data-y="bottom" href="#">⇘</a></li>
</ul>
<hr>
<ul class="button-group even-3">
<!-- Chained, relative vertical and horizontal movements in a circle -->
<!-- not affected by the scroll mode settings, always in mode "append" -->
<!-- number -->
<li><a class="button shift" data-chain=",+=100|+=100,|,-=100|-=100," href="#">↳↰<br>100</a></li>
<!-- px unit -->
<li><a class="button shift" data-chain=",+=1000px|+=1000px,|,-=1000px|-=1000px," href="#">↳↰<br>1000px</a></li>
<!-- percentage -->
<li><a class="button shift" data-chain=",+=25%|+=25%,|,-=25%|-=25%," href="#">↳↰<br>25%</a></li>
</ul>
</section>
<section class="feedback panel">
<dl>
<dt>X</dt>
<dd class="pos x-px"></dd>
<dd class="pos x-percent"></dd>
<dt>Y</dt>
<dd class="pos y-px"></dd>
<dd class="pos y-percent"></dd>
</dl>
<p>Log</p>
<ul id="log"></ul>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.js"></script>
<script src="https://cdn.rawgit.com/hashchange/jquery.scrollable/1.1.1/demo/amd/jsbin/require-config.js"></script>
</body>
</html>
// amd.js
require( [
'jquery',
'underscore',
'usertiming',
'jquery.scrollable'
], function ( $, _, performance ) {
$( function () {
var $window = $( window ),
$body = $( document.body ),
$header = $( "#header" ),
$controlsPane = $( ".scroll-controls" ),
$modeControls = $( "a.mode", $controlsPane ),
$movementControls = $( "a.shift, a.jump", $controlsPane ),
$feedbackPane = $( ".feedback" ),
$feedbackX_px = $( ".x-px", $feedbackPane ),
$feedbackX_percent = $( ".x-percent", $feedbackPane ),
$feedbackY_px = $( ".y-px", $feedbackPane ),
$feedbackY_percent = $( ".y-percent", $feedbackPane ),
$log = $( "#log", $feedbackPane );
performance.clearMarks();
performance.clearMeasures();
// Make sure the document body is larger than the window by at least 2000px in each dimension
$body
.css( {
minWidth: ( $.windowWidth() + 2000 ) + "px",
minHeight: ( $.windowHeight() + 2000 ) + "px"
} );
// Add a gradient background by injecting a "gradient background div". This is a terrible hack.
//
// Setting the gradient directly on the body didn't work as intended. The gradient just extended across the
// screen, not across the full body size. Beyond the screen, the gradient was repeated, creating a pattern. Body
// somehow seems to be confused with "window". Observed in Chrome 43 (May 2015).
//
// (Adding the gradient class after setting the final body size didn't change this, either.)
$( "<div/>" ).appendTo( $body ).addClass( "maxed gradient" );
// Hide the info header (if present), show controls
if ( $header.length ) {
$header.delay( 2000 ).fadeOut( 800, function () {
$controlsPane.show();
} );
} else {
$controlsPane.show();
}
// Clicks on controls should not stop an ongoing scroll animation. Keep events from propagating.
$movementControls.on( "mousedown touchstart pointerdown", function ( event ) {
event.stopPropagation();
} );
$modeControls.on( "mousedown touchstart pointerdown", function ( event ) {
event.stopPropagation();
} );
// Wire up the movement controls
$movementControls.click( function ( event ) {
var chain,
$elem = $( this ),
chainData = $elem.data( "chain" ),
scrollMode = chainData ? "append" : getScrollMode(),
actionLabel = $elem.text(),
config = {
duration: 2000,
append: scrollMode === "append",
merge: scrollMode === "merge",
lockSpeedBelow: 1500,
start: function ( animation ) {
var callId = _.uniqueId( "callId" );
animation._callId = callId;
performance.mark( callId + " - Start" );
},
done: function ( animation ) {
var execTime,
callId = animation._callId;
performance.measure( callId, callId + " - Start" );
execTime = getMeasuredDuration( callId, { rounded: true, unit: true } );
updateLog( actionLabel + " done.", true, " (" + execTime + ")" );
}
};
event.preventDefault();
if ( chainData ) {
chain = chainData.split( "|" );
chain = $.map( chain, function ( stepData ) {
var coords = stepData.split( "," );
return { x: coords[0], y: coords[1] };
} );
$.each( chain, function ( index, position ) {
config.done = function () {
var isLastSubscroll = index === chain.length - 1;
updateLog( [ actionLabel, " (", index + 1, ") done for { x: ", position.x || "n/a", ", y: ", position.y || "n/a", " }." ], isLastSubscroll );
};
$window.scrollTo( position, config );
} );
} else {
$window.scrollTo( {
x: $elem.data( "x" ),
y: $elem.data( "y" )
}, config );
}
} );
// Wire up the mode controls
$modeControls.click( function ( event ) {
var $elem = $ ( this );
event.preventDefault();
$modeControls.not( $elem ).removeClass( "active" ).addClass( "info" );
$elem.addClass( "active" ).removeClass( "info" );
} );
$modeControls.filter( ".default" ).click();
$window.scroll( _.throttle( updateFeedback, 100 ) );
updateFeedback();
function updateFeedback () {
var posX = $window.scrollLeft(),
posY = $window.scrollTop(),
range = $window.scrollRange();
$feedbackX_px.text( posX + "px" );
$feedbackX_percent.text( toPercent( posX, range.horizontal, 4 ) + "%" );
$feedbackY_px.text( posY + "px" );
$feedbackY_percent.text( toPercent( posY, range.vertical, 4 ) + "%" );
}
function updateLog ( message, addSeparator, appendedMessageConsoleOnly ) {
var $entry = $( "<li/>" );
if ( $.isArray( message ) ) message = message.join( "" );
if ( addSeparator ) $entry.addClass( "done" );
$entry.text( message ).appendTo( $log );
if ( typeof console !== "undefined" ) {
if ( appendedMessageConsoleOnly ) message += appendedMessageConsoleOnly;
console.log( message );
if ( addSeparator ) console.log( "-------" );
}
}
function getScrollMode () {
return $modeControls.filter( ".active" ).data( "mode" );
}
} );
function toPercent ( pos, scrollRange, decimals ) {
var percentage = pos * 100 / scrollRange,
shift = Math.pow( 10, decimals || 0 );
return Math.round( percentage * shift ) / shift;
}
function getMeasuredDuration( entry, opts ) {
var duration = performance.getEntriesByName( entry )[0].duration;
if ( opts && opts.rounded ) duration = Math.round( duration );
if ( opts && opts.unit ) duration = duration + "ms";
return duration;
}
} );
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |