我试图在封装一个storage模块
做的单页面应用,其中有个业务需求。
假如用户打开两个窗口A和窗口B
当A窗口登陆时,B窗口的状态也是登陆,同样登出也是一样。
我就想到用localStorage的onstorage事件(好吧,其实token就是存在localStorage,已经放弃cookie)
当token变化时,触发onstorage事件,然后问题就是。
localStorage能够触发,有点小bug,IE以及低版本firefox会触发本身的页面之外(这里请教各位,如何让本身的页面不触发?试了好几个方法都不行)
业务需求已满足。
就是sessionStorage的改变,并不会触发onstorage事件(chrome49)
我查了各方资料都表示,sessionStorage也有onstorage事件,可是为什么不触发么,求解?
这是angular的部分代码
/**
* watch key storage change,when it change and run watcher
* @param key origin key
* @param watcher watch function
*/
var _watchList = {};
var _hasWatch = false;
var watch = function () {
// watch once
if (_hasWatch) return;
$window.addEventListener('storage', function (e) {
angular.forEach(_watchList, function (watcherList, key) {
var atStorageKey = e.key;
var originKey = _revertKey(atStorageKey);
var newVal = e.newValue;
var oldVal = e.oldValue;
// not match the key
if (originKey !== key) return;
// in the same window,void this bug in IE9+
// if ($window.$$identifiers === e.srcElement.$$identifiers) return;
if (newVal === oldVal) return;
// trigger
angular.forEach(watcherList, function (watcherObj) {
if (watcherObj.watcher && angular.isFunction(watcherObj.watcher)) {
watcherObj.watcher(newVal, oldVal, e);
}
})
});
}, false);
_hasWatch = true;
};
var watchQueue = function (key, watcher, $scope) {
watch();
// push to then queue
if (!_watchList[key]) {
_watchList[key] = [];
}
// _watchList[key].push(watcher);
var $$id = _watchList[key].length;
_watchList[key][0] = {
$$id: $$id,
watcher: watcher
};
// if is a $scope,the watcher will be destroy with $scope
if ($scope && $scope.$id && $scope.$parent && angular.isFunction($scope.$on)) {
$scope.$on('$destroy', function () {
cancelWatch();
})
}
function cancelWatch() {
angular.forEach(_watchList, function (watcherList) {
angular.forEach(watcherList, function (watcher, id) {
if (id === $$id) {
watcherList = watcherList.splice(id, 1);
}
});
});
}
/**
* return a function to cancel this watcher
*/
return cancelWatch;
};
完整源码我已经放到github上面了。
at-storage