如果要在React中引入外部界面, 可以考虑使用iframe标签. 特别是当重构某个项目, 变成React技术架构的时候, 一部分界面先用着之前的技术架构, 一部分界面重构, 这个时候iframe总能派上用场.
但是, iframe有个坑, 比如导航栏点击下拉菜单, 点击界面其他地方的时候收回菜单这个功能, 点击在iframe上面是不起作用的.
接下来就是我的一种解决方法, 可以实现在iframe上面绑定点击事件来触发相关功能.
1. 引入redux
既然使用了react, 相信你肯定也在使用redux来管理状态吧.
import { connect } from "react-redux"
import {hideNavDropDownMenu} from './navigation/headerActions' // 收回下拉菜单action
注意这个hideNavDropDownMenu
就是收回下拉菜单的action
2. 自定义一下Iframe控件
因为我们要给iframe绑定一个事件, 肯定不能使用html自带的ifram标签啦, 自己动手, 写一个React的Iframe组件吧
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { connect } from "react-redux"
import {hideNavDropDownMenu} from './navigation/headerActions'
class Iframe extends Component {
render() {
return (
<iframe className='top-iframe' src={this.props.location.pathname}/>
)
}
}
export default connect(
null,
{
hideNavDropDownMenu,
}
)(Iframe)
好, 这样下来我们就写好一个按照我们的当前路径寻找页面的Iframe组件了
接下来就是重点了
3.(重点)给iframe引入页面的body绑定onClick事件
我们要把事件绑定在iframe里面的页面上才能实现功能
但是react寻找元素绑定事件与document不一样, 要这样找到组件并绑定事件
let {hideNavDropDownMenu} = this.props
ReactDOM.findDOMNode(this).contentDocument.body.addEventListener('click', this.props.hideNavDropDownMenu);
4. 何时进行绑定组件
在第三步我们已经知道了如何在React里面给iframe绑定事件, 那么什么时候来进行绑定呢? 答案就是: 在 iframe onLoad 的时候进行绑定.
但是, 这个时候问题又来了, 在React里面, iframe根本就没有onLoad方法. 我们需要手动给iframe绑定一个onLoad方法. 需要在componentDidMount的方法里进行绑定
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('load', this.onLoad);
}
然后再在onLoad方法中进行第3步
onLoad = () => {
let {hideNavDropDownMenu} = this.props
ReactDOM.findDOMNode(this).contentDocument.body.addEventListener('click', this.props.hideNavDropDownMenu);
}
这样我们就成功的给iframe绑定好了点击事件
完整代码如下:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { connect } from "react-redux"
import {hideNavDropDownMenu} from './navigation/headerActions'
class Iframe extends Component {
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('load', this.onLoad);
}
onLoad = () => {
let {hideNavDropDownMenu} = this.props
ReactDOM.findDOMNode(this).contentDocument.body.addEventListener('click', this.props.hideNavDropDownMenu);
}
render() {
return (
<iframe className='top-iframe' src={this.props.location.pathname}/>
)
}
}
export default connect(
null,
{
hideNavDropDownMenu,
}
)(Iframe)