<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Swiper</title>
</head>
<body>
<div class="swipe">
<div class="swipe-items-wrap" id="wrap">
<div class="swipe-item slide1">item 1</div>
<div class="swipe-item slide2">item 2</div>
<div class="swipe-item slide3">item 3</div>
</div>
</div>
</body>
</html>
.swipe {
overflow: hidden;
position: relative;
height: 200px;
color: #fff;
font-size: 30px;
text-align: center;
}
.swipe-items-wrap {
position: relative;
overflow: hidden;
height: 100%;
}
.swipe-items-wrap > div {
position: absolute;
transform: translateX(-100%);
width: 100%;
height: 100%;
display: none;
}
.swipe-items-wrap > div.is-active {
display: block;
transform: none;
}
.swipe-item {
line-height: 200px;
}
.slide1 {
background-color: #0089dc;
color: #fff;
}
.slide2 {
background-color: #ffd705;
color: #000;
}
.slide3 {
background-color: #ff2d4b;
color: #fff;
}
var dragState = {};
// variable
var ready = false;
var dragging = false;
var userScrolling = false;
var animating = false;
var index = 0;
var pages = [];
var timer = null;
var reInitTimer = null;
var noDrag = false;
var isDone = false;
// options
var speed = 300;
var defaultIndex = 0;
var auto = 3000;
var continuous = true;
var showIndicators = true;
var noDragWhenSingle = true;
var prevent = false;
var stopPropagation = false;
console.log(document.getElementById('wrap'));
var children = [];
var element = document.querySelector('#wrap');
var childNodes = element.childNodes;
children = [].slice.call(childNodes).filter(function(child) {
return child.nodeType === 1;
});
function reInitPages() {
noDrag = children.length === 1 && noDragWhenSingle;
var aPages = [];
var intDefaultIndex = Math.floor(defaultIndex);
var defaultIndex = (intDefaultIndex >= 0 && intDefaultIndex < children.length) ? intDefaultIndex : 0;
index = defaultIndex;
children.forEach(function(child, index) {
aPages.push(child);
child.classList.remove('is-active');
if (index === defaultIndex) {
child.classList.add('is-active');
}
});
pages = aPages;
}
function translate(element, offset, speed, callback) {
if (speed) {
animating = true;
element.style.webkitTransition = '-webkit-transform ' + speed + 'ms ease-in-out';
setTimeout(function() {
element.style.webkitTransform = 'translate3d(' + offset + 'px, 0, 0)';
}, 50);
var called = false;
var transitionEndCallback = function() {
if (called) return;
called = true;
animating = false;
element.style.webkitTransition = '';
element.style.webkitTransform = '';
if (callback) {
callback.apply(this, arguments)
}
}
element.addEventListener('webkitTransitionEnd', transitionEndCallback);
setTimeout(transitionEndCallback, speed + 100);
} else {
element.style.webkitTransition = '';
element.style.webkitTransform = 'translate3d(' + offset + 'px, 0, 0)';
}
}
function doAnimate(towards, options) {
if (children.length === 0) return;
if (!options && children.length < 2) return;
var prevPage, nextPage, currentPage, pageWidth, offsetLeft;
// var speed = speed || 300;
// var index = index;
// var pages = pages;
var pageCount = pages.length;
if (!options) {
pageWidth = element.clientWidth;
currentPage = pages[index];
prevPage = pages[index - 1];
nextPage = pages[index + 1];
if (continuous && pages.length > 1) {
if (!prevPage) {
prevPage = pages[pages.length - 1];
}
if (!nextPage) {
nextPage = pages[0];
}
}
if (prevPage) {
prevPage.style.display = 'block';
translate(prevPage, -pageWidth);
}
if (nextPage) {
nextPage.style.display = 'block';
translate(nextPage, pageWidth);
}
} else {
prevPage = options.prevPage;
currentPage = options.currentPage;
nextPage = options.nextPage;
pageWidth = options.pageWidth;
offsetLeft = options.offsetLeft;
}
var newIndex;
var oldPage = children[index];
if (towards === 'prev') {
if (index > 0) {
newIndex = index - 1;
}
if (continuous && index === 0) {
newIndex = pageCount - 1;
}
} else if (towards === 'next') {
if (index < pageCount - 1) {
newIndex = index + 1;
}
if (continuous && index === pageCount - 1) {
newIndex = 0;
}
}
var callback = function() {
if (newIndex !== undefined) {
var newPage = children[newIndex];
oldPage.classList.remove('is-active');
newPage.classList.add('is-active');
index = newIndex
}
if (isDone) {
end();
}
if (prevPage) {
prevPage.style.display = '';
}
if (nextPage) {
nextPage.style.display = '';
}
}
setTimeout(function() {
if (towards === 'next') {
isDone = true;
before(currentPage);
translate(currentPage, -pageWidth, speed, callback);
if (nextPage) {
translate(nextPage, 0, speed)
}
} else if (towards === 'prev') {
isDone = true;
before(currentPage);
translate(currentPage, pageWidth, speed, callback);
if (prevPage) {
translate(prevPage, 0, speed);
}
} else {
isDone = true;
translate(currentPage, 0, speed, callback);
if (typeof offsetLeft !== 'undefined') {
if (prevPage && offsetLeft > 0) {
translate(prevPage, pageWidth * -1, speed);
}
if (nextPage && offsetLeft < 0) {
translate(nextPage, pageWidth, speed);
}
} else {
if (prevPage) {
translate(prevPage, pageWidth * -1, speed);
}
if (nextPage) {
translate(nextPage, pageWidth, speed);
}
}
}
}, 10);
}
function next() {
doAnimate('next');
}
function prev() {
doAnimate('prev');
}
function before() {
// console.log('before', index);
}
function end() {
// console.log('end', index);
}
function doOnTouchStart(event) {
if (noDrag) return;
var touch = event.touches[0];
dragState.startTime = new Date();
dragState.startLeft = touch.pageX;
dragState.startTop = touch.pageY;
dragState.startTopAbsolute = touch.clientY;
dragState.pageWidth = element.offsetWidth;
dragState.pageHeight = element.offsetHeight;
var prevPage = children[this.index - 1];
var dragPage = children[index];
var nextPage = children[this.index + 1];
if (continuous && pages.length > 1) {
if (!prevPage) {
prevPage = children[children.length - 1];
}
if (!nextPage) {
nextPage = children[0];
}
}
dragState.prevPage = prevPage ? prevPage : null;
dragState.dragPage = dragPage ? dragPage : null;
dragState.nextPage = nextPage ? nextPage : null;
if (dragState.prevPage) {
dragState.prevPage.style.display = 'block';
}
if (dragState.nextPage) {
dragState.nextPage.style.display = 'block';
}
}
function doOnTouchMove() {
if (noDrag) return;
var touch = event.touches[0];
dragState.currentLeft = touch.pageX;
dragState.currentTop = touch.pageY;
dragState.currentTopAbsolute = touch.clientY;
var offsetLeft = dragState.currentLeft - dragState.startLeft;
var offsetTop = dragState.currentTopAbsolute - dragState.startTopAbsolute;
var distanceX = Math.abs(offsetLeft);
var distanceY = Math.abs(offsetTop);
if (distanceX < 5 || ( distanceY >= 5 && distanceY >= 1.73 * distanceX )) {
userScrolling = true;
return;
} else {
userScrolling = false;
event.preventDefault();
}
offsetLeft = Math.min(Math.max(-dragState.pageWidth + 1, offsetLeft), dragState.pageWidth - 1);
var towards = offsetLeft < 0 ? 'next' : 'prev';
if (dragState.prevPage && towards === 'prev') {
translate(dragState.prevPage, offsetLeft - dragState.pageWidth);
}
translate(dragState.dragPage, offsetLeft);
if (dragState.nextPage && towards === 'next') {
translate(dragState.nextPage, offsetLeft + dragState.pageWidth);
}
}
function doOnTouchEnd() {
if (noDrag) return;
var dragDuration = new Date() - dragState.startTime;
var towards = null;
var offsetLeft = dragState.currentLeft - dragState.startLeft;
var offsetTop = dragState.currentTop - dragState.startTop;
var pageWidth = dragState.pageWidth;
var pageCount = pages.length;
if (dragDuration < 300) {
var fireTap = Math.abs(offsetLeft) < 5 && Math.abs(offsetTop < 5);
if (isNaN(offsetLeft) || isNaN(offsetTop)) {
fireTap = true;
}
if (fireTap) {
console.log('tap');
}
}
if (dragDuration < 300 && dragState.currentLeft === undefined) return;
if (dragDuration < 300 || Math.abs(offsetLeft) > pageWidth / 2) {
towards = offsetLeft < 0 ? 'next' : 'prev';
}
if (!continuous) {
if ((index === 0 && towards === 'prev') || (index === pageCount - 1 && towards === 'next')) {
towards = null;
}
}
if (children.length < 2) {
towards = null;
}
doAnimate(towards, {
offsetLeft: offsetLeft,
pageWidth: dragState.pageWidth,
prevPage: dragState.prevPage,
currentPage: dragState.dragPage,
nextPage: dragState.nextPage
});
dragState = {};
}
function initTimer() {
if (auto > 0 && !timer) {
timer = setInterval(function() {
if (!continuous && index >= pages.length - 1) {
return clearTimer();
}
if (!dragging && !animating) {
next();
}
}, auto);
}
}
function clearTimer() {
clearInterval(timer);
timer = null;
}
function mounted() {
ready = true;
// 设置定时器
initTimer();
// 初始化页面
reInitPages();
// 绑定事件
element.addEventListener('touchstart', function(event) {
if (prevent) event.preventDefault();
if (stopPropagation) event.stopPropagation();
if (animating) return;
dragging = true;
userScrolling = false;
doOnTouchStart(event);
});
element.addEventListener('touchmove', function(event) {
if (!dragging) return;
if (timer) clearTimer();
doOnTouchMove(event);
});
element.addEventListener('touchend', function(event) {
if (userScrolling) {
dragging = false;
dragState = {};
return;
}
if (!dragging) return;
initTimer();
doOnTouchEnd(event);
dragging = false;
});
}
document.addEventListener('DOMContentLoaded', mounted);
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. |