场景
在做项目的时候,往往会遇到一些集成项目,特别是现场多家公司合作的那种项目,会将多个项目打包后用iframe的方式集合在一起;一种用主页面和子页面通过postmessage方式通信,如果主页面已经没法修改,也可以通过监听dom的方式实现。
以切换选项卡来切换iframe为例:
1 首先获取选项卡当前激活状态在哪个iframe页面
按照如下逻辑,根据自己的dom结构获取tab
// 获取当前选项卡
function getActiveTab () {
let tabItems = window.parent.document.getElementsByClassName('tabs')
let activeTab = ''
for (let i = 0; i < tabItems.length; i++) {
if (tabItems[i].classList.contains('active')) {
activeTab = tabItems[i].children[1].children[0].title
break
}
}
return activeTab
}
2 轮询监听获取到的tab是否变化,如果变化做出响应
通过Object.defineProperty属性实现监听
// tabWatcher监听对象
var tabWatcher = {
activeTabName: ''
}
// 当前tab值
let val = ''
// 暂存tab
let tempVal = ''
Object.defineProperty(tabWatcher, 'activeTabName', {
enumerable: true,
configurable: true,
get () {
console.log('activeTabName被读取')
return val
},
set (newVal) {
// 如果当前tab和暂存tab不一样,再执行监听函数
if (newVal !== tempVal) {
console.log('activeTabName被修改', newVal)
val = newVal
tempVal = newVal
// 可以执行监听函数
watcherFn()
}
}
})
// 通过监听active值执行
setInterval(() => {
tabWatcher.activeTabName = getActiveTab()
}, 500)
3 获取目标子window,可以获取想要操作的任意iframe window
// 获取目标window
function getMapWindow () {
let mapWindow = null
let targetName = 'frame_xiaobaigis'
let keys = Object.keys(window.parent)
// 过滤掉非window,返回windows的键值
keys = keys.filter((key) => {
return !isNaN(Number(key))
})
// 返回目标window
for (let i = 0; i < keys.length; i++) {
if (window.parent[i].name === targetName) {
mapWindow = window.parent[i]
break
}
}
return mapWindow
}
4 执行监听操作
function watcherFn () {
let mapWindow = getMapWindow()
// 非地图且地图iframe存在 则移除插件并关闭
if (tabWatcher.activeTabName !== '地图' && mapWindow) {
} else {
}
}
全部代码:
var tabWatcher = {
activeTabName: ''
}
let val = ''
let tempVal = ''
Object.defineProperty(tabWatcher, 'activeTabName', {
enumerable: true,
configurable: true,
get () {
console.log('activeTabName被读取')
return val
},
set (newVal) {
if (newVal !== tempVal) {
console.log('activeTabName被修改', newVal)
val = newVal
tempVal = newVal
watcherFn()
}
}
})
// 后续通过监听active值执行
setInterval(() => {
tabWatcher.activeTabName = getActiveTab()
}, 500)
// 获取当前选项卡
function getActiveTab () {
let tabItems = window.parent.document.getElementsByClassName('tabs')
let activeTab = ''
for (let i = 0; i < tabItems.length; i++) {
if (tabItems[i].classList.contains('active')) {
// activeTab = tabItems[i].children[0].title
activeTab = tabItems[i].children[1].children[0].title
break
}
}
return activeTab
}
// 获取地图window
function getMapWindow () {
let mapWindow = null
let targetName = 'frame_xiaobaigis'
let keys = Object.keys(window.parent)
// 返回windows的键值
keys = keys.filter((key) => {
return !isNaN(Number(key))
})
for (let i = 0; i < keys.length; i++) {
if (window.parent[i].name === targetName) {
mapWindow = window.parent[i]
break
}
}
return mapWindow
}
function watcherFn () {
let mapWindow = getMapWindow()
// 非地图且地图iframe存在 则移除插件并关闭
if (tabWatcher.activeTabName !== '地图' && mapWindow) {
} else {
}
}