UNPKG

ielevator

Version:

ielevator is quite useful for simulating elevator.

295 lines (268 loc) 8.89 kB
// UMD support ;(function(root, factory) { if (typeof define === "function" && define.amd) { define(["jquery"], factory); } else if (typeof exports === "object") { module.exports = factory(require("jquery")); } else { root.Requester = factory(root.$); } }(this, function($) { 'use strict'; // IE6 support if (typeof Array.prototype.indexOf !== 'function') { Array.prototype.indexOf = function(item) { for (var i = this.length - 1; i >= 0; i--) { if (this[i] === item) { return i; } } } } // detection IE6 function IETest(version) { var b = document.createElement('b'); b.innerHTML = '<!--[if IE ' + version + ']><i></i><![endif]-->'; return b.getElementsByTagName('i').length === 1; } /** * iElevator constructor * @param {object} options configuration * @param {DOM} element DOM node */ function iElevator(options, element) { // cache for context this.element = $(element); this.namespace = 'iElevator'; // defaults var _defaults = { floors: null, btns: null, backtop: null, selected: '', visible: {isHide: 'no', numShow: 0}, speed: 400, show: function (me) { me.element.show(); }, hide: function (me) { me.element.hide(); } }, meta = this.element.data('ielevator-options') || {}; // configurations extended, priority: _defaults < options < meta this.settings = $.extend({}, _defaults, options, meta); this.init(options); } iElevator.prototype = (function() { // caching scrollTop(value) of each module var _scrollTopArr = [], _STARR, _refArr; /** * lazy definition visible * @private _visible */ var _visible = function (_sTop) { var _parent = _getSettings.call(this, 'visible'), _isHide = _parent.isHide.toLowerCase(), _numShow = _parent.numShow; if(_isHide === 'yes') { this.element.hide(); } else { _numShow = 0; } _visible = function (_sTop) { if(_sTop >= _numShow) { _ielevatorShow.call(this); } else { _ielevatorHide.call(this); } } }, _supportIE6 = (function () { if(IETest(6)){ // Anti-shake $('html').css({ "backgroundImage": "url(about:blank)", "backgroundAttachment": "fixed" }); return function (_sTop, _currentTop) { this.element.css('top', parseInt(_sTop, 10) + _currentTop + 'px'); } } })(); function _initPattern(options) { var _patternFields = { floors: ('floors' in options), btns: ('btns' in options), backtop: ('backtop' in options) }; if(_patternFields.floors) { this.floors = _getSettings.call(this, 'floors'); this.floors.each(function() { _scrollTopArr.push($(this).offset().top); }); this.btns = _patternFields.btns ? _getSettings.call(this, 'btns') : null; } if(_patternFields.backtop) { this.backtop = _getSettings.call(this, 'backtop'); // _scrollTopArr.push(0); } if (this.btns) { if (this.backtop) { _refArr = this.btns.add(this.backtop); } else { _refArr = this.btns; } } else { _refArr = this.backtop; } _STARR = _scrollTopArr.slice(); _STARR.push(0); // support 3 patterns if(!(_patternFields.floors && _patternFields.btns && _patternFields.backtop) && !(_patternFields.floors && _patternFields.btns) && !(_patternFields.backtop)) { $.error('you provide at least one of "cBacktop" , "cFloors + cBtns" or "cFloors + cBtns + cBacktop"') } } function _getSettings(key) { // to verify whether settings contains key or not if(key in this.settings) { var _value = this.settings[key], requiredKey = { cFloors: true, cBtns: true, cBacktop: true }; if ( !_value && requiredKey[key]) { $.error('the "' + key + '" is required, not ' + _value); } else { return _value; } } else { $.error('the settings contains no such ¡°' + key + '¡± option!'); } } function _ielevatorShow() { _getSettings.call(this, 'show')(this); } function _ielevatorHide() { _getSettings.call(this, 'hide')(this); } function _getLocation(num) { var _num = parseInt(num, 10), _index = _scrollTopArr.indexOf(_num); if(_index > -1) { return _index; } _scrollTopArr.push(_num); _scrollTopArr.sort(function(A, B) { return A - B; }); _index = _scrollTopArr.indexOf(_num); _scrollTopArr.splice(_index, 1); return (_index - 1); } function _setLocation(index, _speed) { if (index === -1) { return; } // $(window).scrollTop(_scrollTopsP[index]); $('html, body').animate({scrollTop: _STARR[index]}, _speed); } function _setBtns(index) { var _selected = _getSettings.call(this, 'selected'); // this.btns && this.btns.removeClass(_selected).eq(index).addClass(_selected); _refArr && _refArr.removeClass(_selected).eq(index).addClass(_selected); } function _bindEvents() { var _me = this, _speed = _getSettings.call(this, 'speed'), _currentTop = this.element.offset().top, _len = _STARR.length; _refArr.on('click.' + this.namespace, function(e) { var _index = _refArr.index($(this)); _setLocation.call(_me, _index, _speed); }); $(window).on('scroll.' + this.namespace, function() { var _sTop = $(this).scrollTop(); var _index = _getLocation.call(_me, _sTop); _supportIE6 && _supportIE6.call(_me, _sTop, _currentTop); _visible.call(_me, _sTop); _setBtns.call(_me, _index); }); } function _unbindEvents() { this.element.off('.' + this.namespace); $(window).off('.' + this.namespace); } function _destory() { _unbindEvents.call(this); // clear cache data $.removeData(this); } function _init(options) { _initPattern.call(this, options); _visible.call(this); _bindEvents.call(this); } return { // ensure constructor point to iElevator(constuctor === iElevator) constructor: iElevator, init: function(options) { this._(_init)(options); }, destory: function () { console.log('destory'); this._(_destory)(); }, getSettings: function(key) { return this._(_getSettings)(key); }, _: function(callback) { //cache this var self = this; return function( /*argument*/ ) { return callback.apply(self, arguments); } } } })(); $.fn.ielevator = function(options) { var PLUGIN_NS = "ielevatorPlugin", args, returnVal; if (typeof options === 'string') { args = Array.prototype.slice.call(arguments, 1); this.each(function() { var pluginInstance = $.data(this, PLUGIN_NS); if (!pluginInstance) { $.error("The plugin has not been initialised yet when you tried to call this method: " + options); return; } if (!$.isFunction(pluginInstance[options])) { $.error("The plugin contains no such method: " + options); return; } else { returnVal = pluginInstance[options].apply(pluginInstance, args); } }); if (returnVal !== undefined) { // If the method returned a value, return the value. return returnVal; } else { // Otherwise, returning 'this' preserves chainability. return this; } } else { return this.each(function() { var pluginInstance = $.data(this, PLUGIN_NS); if (pluginInstance) { pluginInstance.option(options); } else { $.data(this, PLUGIN_NS, new iElevator(options, this)); } }); } }; }));