kimizuka.hatenablog.com
kimizuka.hatenablog.com
以前つくったもの を改良しました。
- 自動送りとユーザー操作のタイミングが重なったときの対策をいれました。
- touchend が発火しないことのあるAndroid にも対応させるべく、touchmoveにイベントを張りました。
DEMO
※ スマートフォンでしか動作しません
JavaScript
// forked from kimmy's "forked: カルーセルをつくろう" http://jsdo.it/kimmy/7siJ // forked from kimmy's "カルーセルをつくろう" http://jsdo.it/kimmy/w9Gt (function buildCarousel(win, doc, $) { "use strict"; function Carousel($elm) { var that = this, diff = 0, x = 0, LIMIT = 100; that.$elm = $elm; that.$photos = $elm.find(".photos"), that.$photo = $elm.find(".photo"), that.$btn = $elm.find(".btn"), that.index = $elm.attr("data-carousel") - 0 || 0; that.length = $elm.find(".photo").length; that.max = that.length - 1; that.timer = null; that.INTERVAL = 5000; $elm.on("touchstart", _start); $elm.on("touchmove", _move); // endからmoveに変更 ※ Android対策 that.$photos.prepend(that.$photo.last().clone()); that.$photos.append(that.$photo.eq(0).clone()); // コピーしたDOM分調整 that.index += 1; that.length += 2; that.max += 2; that.$photos.width(that.length * 100 + "%"); $elm.find(".photo").width(100 / that.length + "%"); that._show(); function _start(evt) { x = evt.originalEvent.touches[0].pageX; } function _move(evt) { diff = x - evt.originalEvent.changedTouches[0].pageX; if (diff > LIMIT) { x = evt.originalEvent.changedTouches[0].pageX; that.next(); } else if (diff < -LIMIT) { x = evt.originalEvent.changedTouches[0].pageX; that.prev(); } } } Carousel.prototype._show = function() { var that = this; that.$photos.stop(true).animate({ left : that.index * -100 + "%" }, function() { if (that.index <= 0) { // タイミング悪く負の値になったとき対策で = から <= に変更 that.index = that.max - 1; } else if (that.index >= that.max) { // タイミング悪くmaxを越えたとき対策で = から >= に変更 that.index = 1; } that.$photos.css({ left : that.index * -100 + "%" }); that.$elm.attr("data-carousel", that.index); }); if (that.length > 1) { clearInterval(that.timer); that.timer = setTimeout(that.next.bind(that), that.INTERVAL); } }; Carousel.prototype.next = function() { var that = this; if (that.length < 2) { return; } ++that.index; that._show(); }; Carousel.prototype.prev = function() { var that = this; if (that.length < 2) { return; } --that.index; that._show(); }; $(function() { var $carousel = $("[data-carousel]"); $carousel.each(function(index) { new Carousel($carousel.eq(index)); }); }); })(this, document, jQuery);