使用React时如何使用onClick更改x3dom形状?

时间:2018-09-26 10:57:22

标签: html reactjs x3d x3dom

我正在尝试将React与X3DOM一起使用。 我希望能够单击红色的x3dom <box>,以便在按下时将其颜色更改为蓝色。我尝试在<shape>标记中使用onClick方法。我只能通过按下html <button>来做到这一点。代码中也有按钮。

这是我的index.js文件。

import React from "react";
import ReactDOM from "react-dom";

class Toggle extends React.Component {
    constructor(props) {
        super(props);
        this.state = { isToggleOn: true };

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
        }));
    }

    render() {
        return (
        <div>
            <x3d width='500px' height='300px' >
                <scene>
                    <shape onClick={this.handleClick}>
                        <appearance>
                            <material id='color' diffusecolor={this.state.isToggleOn ? '1 0 0' : '0 0 1'}> </material>
                        </appearance>
                        <box></box>
                    </shape>
                </scene>
            </x3d>

            <button onClick={this.handleClick}>
                {this.state.isToggleOn ? 'BLUE' : 'RED'}
            </button>

        </div>
        );
    }

}

ReactDOM.render(<Toggle />, document.getElementById('toggle'));

有人可以给我解决方案,或者解释为什么它不起作用。我将不胜感激。

4 个答案:

答案 0 :(得分:0)

问题是X3DOM直接调用eventHandlers。 引用docu

  

由于需要覆盖addEventListener方法,因此x3dom通过直接调用回调函数来处理onclick函数的调用。不会引发页面范围的onclick事件,因此只能在之后之后将侦听器附加到该对象。

我尚未对此进行测试,但是可以在componentDidMount中添加一次onclick可能是一种方法。

答案 1 :(得分:0)

正如@Johannes已经指出的那样,您需要在X3DOM初始化之后添加事件监听器。 如果仔细查看https://doc.x3dom.org/tutorials/animationInteraction/picking/index.html,您会发现它们明确声明:

  

注意事项:onclick函数的调用由x3dom通过以下方式处理:   直接调用回调函数,因为addEventListener   方法需要被覆盖。没有页面范围的onclick事件   抛出,因此只能在之后将侦听器附加到该对象。   在这种情况下,请勿使用$("#myBox").on("click", doSomething(event))   但改为$("#myBox").attr("onclick", "doSomething(event)")。   或者,等待页面完全加载完毕,然后   document.onload事件被触发。

一个工作示例可能如下所示:

var glob = {};
class Toggle {
    ...    
    componentDidMount() {
      glob.handleClick = this.handleClick;
      var k = document.getElementsByTagName('shape')[0];
      k.setAttribute('onclick', 'glob.handleClick()');
    }

请注意,我必须引入一个全局对象才能使其工作,这可能只是我对React的了解不足。您可能会找到更好的方法。

您也可以在https://codepen.io/pgab/pen/gBpEWo

上看到它

答案 2 :(得分:0)

不确定这是否是最好的解决方案,但是我能够通过使用使它起作用 componentDidUpdate()。我通过给<shape>提供一些ID来添加一个eventListner。我还必须删除eventListner以避免无限循环。使用<shape>的问题在于,必须先以某种方式更新组件,然后才能使用该方法。为此,我添加了一个额外的状态“开始”,该状态在应用程序运行的第一秒后从false更新为true。

componentDidUpdate()

答案 3 :(得分:0)

由于您的问题的答案以及与此无关的帖子Why does an onclick property set with setAttribute fail to work in IE?,我有几个星期都遇到了同样的问题,我得以使其与<asp:GridView ID="ShowActivitiesGridView" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"> <Columns> <asp:BoundField DataField="name" HeaderText="Name" SortExpression="name" /> <asp:BoundField DataField="location" HeaderText="Location" SortExpression="location" /> <asp:BoundField DataField="date_of_activity" HeaderText="Date of Activity" SortExpression="date_of_activity" /> <asp:BoundField DataField="organization" HeaderText="Organization" SortExpression="organization" /> <asp:BoundField DataField="no_of_student" HeaderText="No of Student" SortExpression="no_of_student" /> <asp:BoundField DataField="description" HeaderText="Description" SortExpression="description" /> <asp:ButtonField CommandName="RowCommand" HeaderText="Register For Activity" ShowHeader="True" Text="Register" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DefaultConnection %>" SelectCommand="SELECT [id], [name], [location], [date_of_activity], [organization], [no_of_student], [description] FROM [Activities]"> </asp:SqlDataSource>和{{1 }}事件。

如以上答案之一所述,X3Dom带有与onClick事件关联的自己的一组函数。并且,如X3DOM文档中所述,您只能在文档加载后附加事件。 @mistapink的想法也是正确的,除了onClick方法由于某些原因不起作用。所以我做到了:

mouseover