【发布时间】:2016-03-23 14:03:54
【问题描述】:
在普通的旧 HTML 中,我有 DIV
<div class="movie" id="my_movie">
以及下面的javascript代码
var myMovie = document.getElementById('my_movie');
myMovie.addEventListener('nv-enter', function (event) {
console.log('change scope');
});
现在我有一个 React 组件,在这个组件内部,在渲染方法中,我正在返回我的 div。如何为我的自定义事件添加事件侦听器? (我正在将此库用于电视应用程序 - navigation)
import React, { Component } from 'react';
class MovieItem extends Component {
render() {
if(this.props.index === 0) {
return (
<div aria-nv-el aria-nv-el-current className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.movieItem.caption.toUpperCase()}</span>
</div>
</div>
);
}
else {
return (
<div aria-nv-el className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.movieItem.caption.toUpperCase()}</span>
</div>
</div>
);
}
}
}
export default MovieItem;
更新#1:
我应用了答案中提供的所有想法。我将导航库设置为调试模式,并且我只能基于键盘在我的菜单项上导航(正如您在屏幕截图中看到的那样,我能够导航到电影 4)但是当我将一个项目集中在菜单中或按回车,我在控制台中看不到任何内容。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class MenuItem extends Component {
constructor(props) {
super(props);
// Pre-bind your event handler, or define it as a fat arrow in ES7/TS
this.handleNVFocus = this.handleNVFocus.bind(this);
this.handleNVEnter = this.handleNVEnter.bind(this);
this.handleNVRight = this.handleNVRight.bind(this);
}
handleNVFocus = event => {
console.log('Focused: ' + this.props.menuItem.caption.toUpperCase());
}
handleNVEnter = event => {
console.log('Enter: ' + this.props.menuItem.caption.toUpperCase());
}
handleNVRight = event => {
console.log('Right: ' + this.props.menuItem.caption.toUpperCase());
}
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('nv-focus', this.handleNVFocus);
ReactDOM.findDOMNode(this).addEventListener('nv-enter', this.handleNVEnter);
ReactDOM.findDOMNode(this).addEventListener('nv-right', this.handleNVEnter);
//this.refs.nv.addEventListener('nv-focus', this.handleNVFocus);
//this.refs.nv.addEventListener('nv-enter', this.handleNVEnter);
//this.refs.nv.addEventListener('nv-right', this.handleNVEnter);
}
componentWillUnmount() {
ReactDOM.findDOMNode(this).removeEventListener('nv-focus', this.handleNVFocus);
ReactDOM.findDOMNode(this).removeEventListener('nv-enter', this.handleNVEnter);
ReactDOM.findDOMNode(this).removeEventListener('nv-right', this.handleNVRight);
//this.refs.nv.removeEventListener('nv-focus', this.handleNVFocus);
//this.refs.nv.removeEventListener('nv-enter', this.handleNVEnter);
//this.refs.nv.removeEventListener('nv-right', this.handleNVEnter);
}
render() {
var attrs = this.props.index === 0 ? {"aria-nv-el-current": true} : {};
return (
<div ref="nv" aria-nv-el {...attrs} className="menu_item nv-default">
<div className="indicator selected"></div>
<div className="category">
<span className="title">{this.props.menuItem.caption.toUpperCase()}</span>
</div>
</div>
)
}
}
export default MenuItem;
我留下了一些注释,因为在这两种情况下我都无法记录控制台行。
更新 #2:这个导航库不适用于带有原始 Html 标签的 React,因此我必须设置选项并重命名标签以使用 aria-*,这样它就不会影响 React。
navigation.setOption('prefix','aria-nv-el');
navigation.setOption('attrScope','aria-nv-scope');
navigation.setOption('attrScopeFOV','aria-nv-scope-fov');
navigation.setOption('attrScopeCurrent','aria-nv-scope-current');
navigation.setOption('attrElement','aria-nv-el');
navigation.setOption('attrElementFOV','aria-nv-el-fov');
navigation.setOption('attrElementCurrent','aria-nv-el-current');
【问题讨论】:
-
@我基本上是在使用这个文件中的例子(github.com/ahiipsa/navigation/blob/master/demo/index.html)
-
你不需要在你的构造函数中预先绑定 (
this.handleNVEnter = this.handleNVEnter.bind(this)) 和使用带有箭头函数的 ES7 属性初始化器 (handleNVEnter = enter => {}) 因为胖箭头函数总是被绑定的。如果你可以使用 ES7 语法,那就去吧。 -
谢谢亚伦。我能够解决问题。我将接受您的回答,因为我现在正在使用您的解决方案,但我还必须做其他事情。由于 Nagivation 库 HTML 标签不能很好地与 React 配合使用,我不得不在 lib 配置中设置标签名称以使用 aria-* 前缀,问题是事件也使用相同的前缀触发,因此将事件设置为 aria -nv-enter 成功了!它现在工作正常。谢谢!
-
我建议将
aria-*更改为data-*,因为 ARIA 属性来自标准集,您无法自己制作。数据属性可以随意设置。
标签: reactjs