我的React组件中有这段代码禁用了“enter”键。
export const attachDisableEnterEvent = (ref) => {
const node = ReactDOM.findDOMNode(ref);
// Evergreen event listener || IE8 event listener
const addEvent = node.addEventListener || node.attachEvent;
addEvent('keypress', _disableEnter, false);
}
它适用于Chrome / Firefox,但不适用于Safari。在Safari上我得到: -
TypeError:只能在Node
的实例上调用Node.addEventListener
我只能这样做(在各方面): -
addEvent.call(node, 'keypress', _disableEnter, false);
只是想知道为什么addEventListener
的实施在Chrome和&苹果浏览器。 Chrome上的Node.addEventListener
似乎只是直观地将this
绑定到定义它的节点实例。
答案 0 :(得分:4)
这可能与我们拥有以下内容的原因相同:
var log = console.log;
log('foo') // TypeError
相反,我们必须:
var log = console.log.bind(console); // bind console.log function to it's proper context
log('foo') // 'foo'
在您的情况下,请致电
addEvent('keypress', _disableEnter, false);
导致上下文成为窗口对象(隐式)。
通常,当您打算将函数传递给其他人时,您总是希望首先将函数绑定到拥有对象。浏览器实现对于每个浏览器都是不同的,因此这是确保其统一工作的最佳方式。
在控制台的情况下,我相信.log是指控制台对象本身的其他实例方法。因此在Safari中,node.addEventListener
函数可能以需要仅在node
上定义的其他函数的方式实现,并且它们可能也会提供更具描述性的错误消息。
所以你应该这样做:
const addEvent = node.addEventListener || node.attachEvent;
const boundAddEvent = addEvent.bind(node);
// use boundAddEvent however you like anywhere, or .call like you did