最近有个迭代需求:针对某些机型,在所有页面的底部增加安全距离
单页面项目的话比较简单,直接在main.js写就ok。而我这是多页面项目,每个页面都有自己的main和index,可以理解成共用一个config的多个项目。
这就需要封装组件了,打包时打进tunk,或各个自己引入。
思路:
1 写一个自执行函数,页面初始化的时候走一遍
2. 大部分项目用的是vue-router,自执行函数只能给第一页加安全距离,后边的页面的底部按钮不生效
3. 监听所有路由变化
4. 有的项目是history 模式,有的hash 模式
封装的代码如下:historyListener.js
class Dep {
// 订阅池
constructor(name) {
this.id = new Date() // 这里简单的运用时间戳做订阅池的ID
this.subs = [] // 该事件下被订阅对象的集合
}
defined() {
// 添加订阅者
Dep.watch.add(this)
}
notify() {
// 通知订阅者有变化
this.subs.forEach((e, i) => {
if (typeof e.update === 'function') {
try {
e.update.apply(e) // 触发订阅者更新函数
} catch (err) {
console.warr(err)
}
}
})
}
}
Dep.watch = null
class Watch {
constructor(name, fn) {
this.name = name // 订阅消息的名称
this.id = new Date() // 这里简单的运用时间戳做订阅者的ID
this.callBack = fn // 订阅消息发送改变时->订阅者执行的回调函数
}
add(dep) {
// 将订阅者放入dep订阅池
dep.subs.push(this)
}
update() {
// 将订阅者更新方法
var cb = this.callBack // 赋值为了不改变函数内调用的this
cb(this.name)
}
}
var addHistoryMethod = (function() {
var historyDep = new Dep()
return function(name) {
if (name === 'historychange') {
return function(name, fn) {
var event = new Watch(name, fn)
Dep.watch = event
historyDep.defined()
Dep.watch = null // 置空供下一个订阅者使用
}
} else if (name === 'pushState' || name === 'replaceState') {
var method = history[name]
return function() {
method.apply(history, arguments)
historyDep.notify()
}
}
}
})()
window.addHistoryListener = addHistoryMethod('historychange')
history.pushState = addHistoryMethod('pushState')
history.replaceState = addHistoryMethod('replaceState')
注意最后三行,叠加一起使用,几乎能监听所有情况的地址变化
使用
require('./historyListener.js')
window.safeArea = function() {
//do something
}
window.addHistoryListener('history', function() {
window.safeArea()
})
window.addEventListener('popstate', function(event) {
window.safeArea()
})
window.addEventListener('hashchange', function(event) {
window.safeArea()
})
window.safeArea()
写这篇博客的时候想到,应该通过种全局变量的方式更简单,有时间再研究研究 …^^