Html 使用React时,如何使用onClick更改x3dom形状?
我正在尝试将React与X3DOM一起使用。 我希望能够单击红色的x3domHtml 使用React时,如何使用onClick更改x3dom形状?,html,reactjs,x3d,x3dom,Html,Reactjs,X3d,X3dom,我正在尝试将React与X3DOM一起使用。 我希望能够单击红色的x3dom,以便在按下时将其颜色更改为蓝色。我尝试在标记中使用onClick方法。我只能通过按html来实现这一点。我在代码中也有按钮 这是我的index.js文件 import React from "react"; import ReactDOM from "react-dom"; class Toggle extends React.Component { constructor(props) {
,以便在按下时将其颜色更改为蓝色。我尝试在
标记中使用onClick方法。我只能通过按html
来实现这一点。我在代码中也有按钮
这是我的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'));
从“React”导入React;
从“react dom”导入react dom;
类切换扩展了React.Component{
建造师(道具){
超级(道具);
this.state={istogleon:true};
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.setState(prevState=>({
isToggleOn:!prevState.isToggleOn
}));
}
render(){
返回(
{this.state.isToggleOn?'BLUE':'RED'}
);
}
}
ReactDOM.render(,document.getElementById('toggle');
有人能给我一个解决方案,或者解释一下为什么这不起作用。我非常感谢您的回答。问题是X3DOM直接调用EventHandler。 引自: onclick函数的调用由x3dom通过直接调用回调函数来处理,因为需要覆盖addEventListener方法。不会引发页面范围的onclick事件,因此只有在之后才能将侦听器附加到此对象
我还没有对此进行测试,但是在
组件中添加onclick once didmount
可能是一个不错的选择。正如@Johannes已经指出的,您需要在X3DOM初始化后添加事件侦听器。
如果你仔细观察,你会发现他们明确指出:
警告:onclick函数的调用由x3dom通过
直接调用回调函数,因为addEventListener
方法需要被覆盖。不支持页面范围的onclick事件
抛出,因此只有在之后才能将侦听器附加到此对象。
在这种情况下,不要使用$(“#myBox”)。在(“单击”,doSomething(事件))
但是,$(“#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缺乏了解。你可能会找到更好的办法
您还可以在以下位置看到它:不确定这是否是最好的解决方案,但我可以使用
componentdiddupdate()
。我通过给
一些id添加了一个eventListner。我还必须删除eventListner以避免无限循环。使用componentdiddupdate()
的问题是,组件必须以某种方式更新,然后才能使用该方法。为此,我添加了一个额外的状态“start”,在应用程序运行的第一秒钟后,我将该状态从false更新为true
import React from "react";
import ReactDOM from "react-dom";
class Toggle extends React.Component {
constructor() {
super();
this.state = { isToggleOn: true, start: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
console.log("Pressed");
}
componentDidUpdate() {
console.log('Component update');
//Have to do this to avoid potential infinty loop
document.getElementById('someId').removeEventListener("click", this.handleClick);
document.getElementById('someId').addEventListener("click", this.handleClick);
}
render() {
//Need to update component once, to run componentDidUpdate
if(!(this.state.start)){
setTimeout(() => {
this.setState({start: true });
}, 1000)
}
//
return (
<div>
<x3d width='500px' height='300px'>
<scene>
<shape id="someId">
<appearance>
<material id='color' diffusecolor={this.state.isToggleOn ? '1 0 0' : '0 0 1'}> </material>
</appearance>
<box></box>
</shape>
</scene>
</x3d>
</div>
);
}
}
ReactDOM.render(<Toggle />, document.getElementById('toggle'));
从“React”导入React;
从“react dom”导入react dom;
类切换扩展了React.Component{
构造函数(){
超级();
this.state={istogleon:true,start:false};
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.setState(prevState=>({
isToggleOn:!prevState.isToggleOn
}));
控制台日志(“按下”);
}
componentDidUpdate(){
console.log(“组件更新”);
//必须这样做以避免潜在的infinty循环
document.getElementById('someId')。removeEventListener(“单击”,this.handleClick);
document.getElementById('someId').addEventListener(“单击”,this.handleClick);
}
render(){
//需要更新组件一次,才能运行componentDidUpdate
if(!(this.state.start)){
设置超时(()=>{
this.setState({start:true});
}, 1000)
}
//
返回(
);
}
}
ReactDOM.render(,document.getElementById('toggle');
多亏了你问题的答案,以及这篇无关的帖子,我几个星期来都遇到了同样的问题:,我能够用onClick
和mouseover
事件处理它
正如在上面的一个答案中所说,X3Dom附带了它自己的一组附加到onClick事件的函数。正如X3DOM文档中提到的,您只能在加载文档后附加事件。此外,@mistapink的想法是正确的,除了由于某些原因,setAttribute
方法不起作用。所以我这样做了:
const Scene = () => {
const [toggle, setToggle] = useState(false);
const handleMouseOver = () => {/* do some mouse over stuff here */};
const handleClick = () => setToggle(prevToggle => !prevToggle};
useEffect(() => {
const 3dObject = document.getElementById('my-3d-object');
/* I guess you can also try to use a reference, don't know if it'll work */
document.onload = () => {
3dObject.addEventListener("mouseover", handleMouseOver);
/* magic happens here */
3dObject.onclick = () => handleClick(
/* you can pass some extra arguments here */
);
}
return () => sphere.removeEvenetListener("mouseover", handleMouseOver);
});
return (...)
};
我在本地主机上的应用程序中尝试了codepen中的代码。但这对我不起作用。除了单击框的功能外,所有功能都按预期工作,即使是在shape标记中显示onClick方法的console.log消息也是如此。有什么理由不应该在localhost上工作吗?没有,它应该与codepen上的工作方式相同。没有额外的魔力。正在使用文件://
或http://
?在codepen上使用的版本和您的本地版本之间可能存在差异?如果您可以显示一些代码,例如作为要点,则更容易发现错误。