11数据访问

数据访问对象模式

本地数据访问例子

var BaseLocalStorage = function (preId, timeSign) {
  this.preId = preId;
  this.timeSign = timeSign || '|-|';
}
BaseLocalStorage.prototype = {
  status: {
    SUCCESS: 0,
    FAILURE: 1,
    OVERFLOW: 2,
    TIMEOUT: 3
  },
  storage: localStorage || window.localStorage,
  getKey: function (key) {
    return this.preId + key;
  },
  set: function (key, value, cb, time) {
    var status = this.status.SUCCESS,
        key = this.getKey(key);
    try {
      time = new Date(time).getTime() || time.getTime();
    } catch(e) {
      time = new Date().getTime() + 1000 * 60 * 60 * 24 * 31;
    }
    try {
      this.storage.setItem(key, time + this.timeSign + value);
    } catch(e) {
      status = this.status.OVERFLOW;
    }
    cb && cb.call(this, status, key, value);
  },
  get: function (key, cb) {
    var status = this.status.SUCCESS,
        key = this.getKey(key),
        value = null,
        timeSignLen = this.timeSign.length,
        self = this,
        index, time, result;
    try {
      value = self.storage.getItem(key);
    } catch(e) {
      result = {
        status: self.status.FAILURE,
        value: null
      }
      cb && cb.call(this, result.status, result.value);
      return result;
    }
    if(value) {
      index = value.indexOf(self.timeSign);
      time = +value.slice(0, index);
      if(new Date(time).getTime() > new Date().getTime() || time == 0) {
        value = value.slice(index + timeSignLen);
      } else {
      	value = null;
      	status = self.status.TIMEOUT;
      	self.remove(key);
      }
    } else {
      status = self.status.FAILURE 
    }
    result = {
      status: status,
      value: value
    };
    cb && cb.call(this, result.status, result.value);
    return result;
  },
  remove: function (key, cb) {
    var status = this.status.FAILURE,
        key = this.getKey(key),
        value = null;
    try {
      value = this.storage.getItem(key);
    } catch(e) {}
    if(value) {
      try {
        this.storage.removeItem(key);
        status = this.status.SUCCESS;
      } catch(e) {}
    }
    cb && cb.call(this, status, status > 0 ? null : value.slice(value.indexOf(this.timeSign) + this.timeSign.length))
  }
}

var LS = new BaseLocalStorage('LS__');
var cb = function () {console.log(arguments)}

LS.set('a', 'a label', cb);
LS.get('a', cb);
LS.remove('a', cb);
LS.remove('a', cb);
LS.get('a', cb);

节流模式

  • 对重复的业务逻辑进行节流控制,执行最后一次操作病取消其他操作;

节流器-页面滚动例子

var extend = function (source, target) {
  target = target || {};
  for(var p in source) {
  	!target[p] && (target[p] = source[p])
  }
  return target;
};

var throttle = function () {
  var isClear = arguments[0], fn, param;
  if(typeof isClear === 'boolean') {
    fn = arguments[1];
    //函数的计时器句柄存在,清除计时器
    fn._throttleID && clearTimeout(fn._throttleID);
  } else {
    fn = isClear;
    param = arguments[1];
    //对执行的参数适配默认值
    var p = extend({
      context: null,
      args: [],
      time: 300
    }, param);
    //清除执行函数计时器句柄
    arguments.callee(true, fn);
    //为函数绑定计时器句柄,延迟执行函数
    fn._throttleID = setTimeout(function () {
      fn.apply(p.context, p.args)
    }, p.time)
  }
}

function moveScroll () {
   console.log('test');
} 
window.onscroll = function () {
  throttle(moveScroll);
}

优化浮层

  • 当光标划入和划出容器时,为避免是用户误操作,应该使用节流器延迟操作;

图片延迟加载优化

  • 目标是使可视范围内的图片优先加载;
  • 先将获取的src设置到图片的data-src,再延迟设置;
function LazyLoad (id) {
  this.container = document.getElementById(id);
  //缓存图片
  this.imgs = this.getImgs();
  this.init();
}
LazyLoad.prototype = {
  init: function () {
    //加载当前视图图片
    this.update();
    //绑定事件
    this.bindEvent();
  },
  getImgs: function () {
    var arr = [];
    var imgs = this.container.getElementsByTagName('img');
    for (var i = 0, l = imgs.length; i < l; i++) {
      arr.push(imgs[i]);
    }
    return arr;
  },
  update: function () {
    if(!this.imgs.length) return;
    var i = this.imgs.length;
    for(--i; i >= 0; i--) {
      if(this.shouldShow(i)) {
        this.imgs[i].src = this.imgs[i].getAttribute('data-scr');
        this.imgs.splice(i, 1);
      }
    }
  },
  //判断图片是否在可视范围内
  shouldShow: function (i) {
    var img = this.imgs[i];
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var scrollBottom = scrollTop + document.documentElement.clientHeight;
    var imgTop = this.pageY(img);
    var imgBottom = imgTop + img.offsetHeight;

    if(imgBottom > scrollTop && imgBottom < scrollBottom || (imgTop > scrollTop && imgTop < scrollBottom))
      return true;
    return false;
  },
  pageY: function (element) {
    //如果元素有父元素
    if(element.offsetParent) {
      return element.offsetTop + this.pageY(element.offsetParent);
    } else {
      return element.offsetTop;
    }
  },
  on: function (element, type, fn) {
    if(element.addEventListener) {
      element.addEventListener(type, fn, false);
    } else {
      element.attachEvent('on' + type, fn, false);
    }
  },
  bindEvent: function () {
    var self = this;
    this.on(window, 'resize', function () {
      throttle(self.update, {context: self})
    });
    this.on(window, 'scroll', function () {
      throttle(self.update, {context: self})
    })
  }
}

var lazyLoad = new LazyLoad('container');
原文地址:https://www.cnblogs.com/jinkspeng/p/4893451.html