; (function ($){ var NAMESPACE = '.serialScroll'; var $serialScroll = $.serialScroll = function (settings){ return $(window).serialScroll(settings); } ; $serialScroll.defaults = { duration: 1000, axis: 'x', event: 'click', start: 0, step: 1, lock: true , cycle: true , constant: true } ; function isNumeric(obj){ var type = typeof obj; return (type === 'number' || type === 'string') && !isNaN(obj - parseFloat(obj)); } $.fn.serialScroll = function (options){ return this.each(function (){ var settings = $.extend({ } , $serialScroll.defaults, options), event = settings.event, step = settings.step, lazy = settings.lazy, context = _AN_Read_target('target', settings)? this: document, $pane = $(_AN_Read_target('target', settings) || this, context), pane = $pane[0], items = settings.items, active = settings.start, auto = settings.interval, nav = settings.navigation, timer; delete settings.step; delete settings.start; if (!pane) { return ; } if (!lazy) { items = getItems(); } if (settings.force || auto) { jump({ } , active); } $(settings.prev || [] , context).on(event, - step, move); $(settings.next || [] , context).on(event, step, move); if (!pane._bound_) { $pane.on('prev' + NAMESPACE, - step, move).on('next' + NAMESPACE, step, move).on('goto' + NAMESPACE, jump); } if (auto) { $pane.on('start' + NAMESPACE, function (e){ if (!auto) { clear(); auto = true ; next(); } } ).on('stop' + NAMESPACE, function (){ clear(); auto = false ; } ); } $pane.on('notify' + NAMESPACE, function (e, elem){ var i = index(elem); if (i > -1) { active = i; } } ); pane._bound_ = true ; if (settings.jump) { (lazy? $pane: getItems()).on(event, function (e){ jump(e, index(_AN_Read_target('target', e))); } ); } if (nav) { nav = $(nav, context).on(event, function (e){ e.data = Math.round(_AN_Read_length('length', getItems()) / _AN_Read_length('length', nav)) * nav.index(this); jump(e, this); } ); } function move(e){ e.data += active; jump(e, this); } function jump(e, pos){ if (!isNumeric(pos)) { pos = e.data; } var n, real = e.type, $items = settings.exclude? getItems().slice(0, - settings.exclude): getItems(), limit = _AN_Read_length('length', $items) - 1, elem = $items[pos], duration = settings.duration; if (real) { e.preventDefault(); } if (auto) { clear(); timer = _AN_Call_settimeout('setTimeout', window, next, settings.interval); } if (!elem) { n = pos < 0? 0: limit; if (active !== n) { pos = n; } else if (!settings.cycle) { return ; } else { pos = limit - n; } elem = $items[pos]; } if (!elem || settings.lock && $pane.is(':animated') || real && settings.onBefore && settings.onBefore(e, elem, $pane, getItems(), pos) === false ) { return ; } if (settings.stop) { $pane.stop(true ); } if (settings.constant) { duration = Math.abs(duration / step * (active - pos)); } $pane.scrollTo(elem, duration, settings); trigger('notify', pos); } function next(){ trigger('next'); } function clear(){ clearTimeout(timer); } function getItems(){ return $(items, pane); } function trigger(event){ $pane.trigger(event + NAMESPACE, [] .slice.call(arguments, 1)); } function index(elem){ if (isNumeric(elem)) { return elem; } var $items = getItems(), i; while ((i = $items.index(elem)) === -1 && elem !== pane){ elem = elem.parentNode; } return i; } } ); } ; } )(jQuery);