d3.js 如何在另一个函数中引用构造函数this

bfnvny8b  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(52)

如何将下面的部分转换为用JS类编写的部分?

svg authored with d3 without JS Class

const svgns = 'http://www.w3.org/2000/svg';
const width = 1280;
const height = 600;

const main = d3.select('div')
    .style('position', 'relative')
    .append('svg')
    .attr('xmlns', svgns)
    .attr('viewBox', `0 0 ${width} ${height}`)
    .attr('id', 'svg');

//listener
const listener = main
    .append('rect')
    .attr('class', 'vBoxRect')
    .attr('width', `${width}`)
    .attr('height', `${height}`)
    .attr('fill', 'none')
    .attr('stroke', 'red')
    .style("pointer-events", "all");

const focusText = main
    .append('g')
    .attr('class', 'someTxt')
    .append('text')
    .attr("opacity", '0')
    .attr('x', '100')
    .attr('y', '100')
    .html('I am a test text');

listener
    .on('mouseover', function() {
        focusText.attr("opacity", 1);
    })
    .on('mouseout', function() {
        focusText.attr("opacity", 0);
    })

个字符

svg authored with d3 + JS Class and Constructor

const svgns = 'http://www.w3.org/2000/svg';
const width = 1280;
const height = 600;

class Base {
    constructor(svgns, width, height) {
        this.base = d3.select('div')
            .style('position', 'relative')
            .append('svg')
            .attr('xmlns', svgns)
            .attr('viewBox', `0 0 ${width} ${height}`)
            .attr('id', 'svg');

        //listener
        this.listener = this.base
            .append('rect')
            .attr('class', 'vBoxRect')
            .attr('width', `${width}`)
            .attr('height', `${height}`)
            .attr('fill', 'none')
            .attr('stroke', 'red')
            .style("pointer-events", "all");

        this.focusText = this.base
            .append('g')
            .attr('class', 'someTxt')
            .append('text')
            .attr("opacity", '0')
            .attr('x', '100')
            .attr('y', '100')
            .html('I am a test text');

        this.listener
            .on('mouseover', function() {
                this.focusText.attr("opacity", 1);
            })
            .on('mouseout', function() {
                this.focusText.attr("opacity", 0);
            })
    }

};
const svg = new Base(svgns, width, height);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
<body>
    <div id="viz"></div>
</body>
<script src="min.js">
</script>

</html>

的字符串
代码当前在此处失败

//without class 
listener
    .on('mouseover', function() {
        focusText.attr("opacity", 1);
    })
    .on('mouseout', function() {
        focusText.attr("opacity", 0);
    })

//with Class 
this.listener
    .on('mouseover', function() {
        this.focusText.attr("opacity", 1);
    })
    .on('mouseout', function() {
        this.focusText.attr("opacity", 0);
    })

ztigrdn8

ztigrdn81#

问题是,事件系统在调用侦听器回调时会设置自己的this值。在DOM事件中,this的值通常是触发事件的DOM元素。有几种方法可以覆盖this的值并指定自己的值。
要使用this的词法值,请使用箭头函数而不是常规函数:

this.listener
    .on('mouseover', () => {
        this.focusText.attr("opacity", 1);
    })
    .on('mouseout', () => {
        this.focusText.attr("opacity", 0);
    })

字符串
箭头函数忽略了来自函数调用方式的this的值,它们使用this的词法值,这是定义函数时执行环境中this的值-这是您在上下文中想要的。
或者,你也可以使用.bind()(它创建了一个小存根函数,重新建立你想要的this的值):

this.listener
    .on('mouseover', function() {
        this.focusText.attr("opacity", 1);
    }.bind(this))
    .on('mouseout', function() {
        this.focusText.attr("opacity", 0);
    }.bind(this))

相关问题