如何从事件监听器绑定的方法中访问类的方法与变量?
问题原因及解决方法
问题出在事件绑定后的this指向错误:当你把listOfContent直接传给addEventListener时,点击事件触发时,this会指向触发事件的DOM元素(也就是那个id为page的div),而不是Page类的实例,自然找不到类里的addComponanet方法和page属性。
下面给你三种可行的解决方式:
方式一:绑定事件时用箭头函数
箭头函数会继承外层的this指向,也就是Page类的实例:
class Page{ page = document.createElement('div'); Component = [] ; // 纠正拼写错误:Componanet → Component constructor(page, Component){ if (page != null) {this.page = page;} if (Component != null) {this.Component = Component; this.displayAll();} this.page.id = 'page'; // 用箭头函数包裹,保留类实例的this this.page.addEventListener("click", () => this.listOfContent()); } addComponent(){ // 纠正拼写错误:addComponanet → addComponent this.Component.push(new Text(400,320)); }; listOfContent(){ this.addComponent(); this.page.style.borderStyle = "solid"; // 纠正拼写错误:borderStylr → borderStyle this.page.style.display = "inline"; } } class Text{ text = document.createElement('div'); constructor(xpos, ypos){ // 样式值需要加单位px,否则不生效 this.text.style.top = `${xpos}px`; this.text.style.left = `${ypos}px`; // 建议加上position: absolute,否则top/left不生效 this.text.style.position = 'absolute'; } }
方式二:在构造函数中绑定this到方法
通过bind方法手动把this绑定到listOfContent,确保事件触发时this指向类实例:
class Page{ page = document.createElement('div'); Component = [] ; constructor(page, Component){ if (page != null) {this.page = page;} if (Component != null) {this.Component = Component; this.displayAll();} this.page.id = 'page'; // 绑定this到listOfContent方法 this.listOfContent = this.listOfContent.bind(this); this.page.addEventListener("click", this.listOfContent); } addComponent(){ this.Component.push(new Text(400,320)); }; listOfContent(){ this.addComponent(); this.page.style.borderStyle = "solid"; this.page.style.display = "inline"; } } // Text类同上,略
方式三:用箭头函数定义类方法
把listOfContent定义为箭头函数形式的实例属性,这样它的this会始终指向类实例:
class Page{ page = document.createElement('div'); Component = [] ; constructor(page, Component){ if (page != null) {this.page = page;} if (Component != null) {this.Component = Component; this.displayAll();} this.page.id = 'page'; this.page.addEventListener("click", this.listOfContent); } addComponent(){ this.Component.push(new Text(400,320)); }; // 箭头函数形式的方法,this固定指向类实例 listOfContent = () => { this.addComponent(); this.page.style.borderStyle = "solid"; this.page.style.display = "inline"; } } // Text类同上,略
另外顺便纠正了你代码里的几个小问题:
- 拼写错误:
Componanet→Component,borderStylr→borderStyle - Text类中top/left样式需要加
px单位,并且建议设置position: absolute,否则定位不生效
内容的提问来源于stack exchange,提问作者Mohammed Yousef
相关产品推荐
相关产品推荐

