功能运行,即使它不应该运行

时间:2017-11-22 09:38:42

标签: javascript reactjs redux

我有一个元素。用户点击后,它会被激活,并根据下一次点击用户获得他成功或不成功的消息。在这两种情况下,点击后项目都会停用。

然而,即使我将项目状态改为" false"这应该阻止代码运行它一直反复运行。这是代码:

handleBoltcuttersClicked(){
    this.props.dispatch(activate('boltcutters', true));
    console.log('klik');
    setTimeout(() => this.chainMechanics(), 100)

}

chainMechanics(){
    if(this.props.inventory.activeItem.boltcutters===true){
        let clickedElement;
        window.onclick = ((e)=>{
            clickedElement = e.target;
            if(clickedElement.id === 'chainChainedDoor'){
                alert('you got it');
                this.props.dispatch(activate('boltcutters', false))
            } else {
                this.props.dispatch(activate('boltcutters', false));
                alert('try again')
                console.log(this.props.inventory.activeItem.boltcutters);
            }

        })
    }  
}
<a className="ghost-button items" href="#" onClick={() => this.handleBoltcuttersClicked()}>Boltcutters</a>

循环的部分是整个window.onclick函数。即使它不应该是可访问的,因为布尔值不再是真的它仍然有效,我不知道为什么。

奖金问题: 正如您所看到的,我使用setTimeout延迟了chainMechanics函数,因为显然商店在函数触发之前没有足够快地更新它并且它没有工作。它只在第二次点击后开始工作(并且它没有正常工作,因为window.onclick函数在第二次单击该项目时立即被触发,这是不可能的)

2 个答案:

答案 0 :(得分:1)

只要执行此命令:window.onclick = ((e)=>{}),就会在窗口中注册一个事件侦听器。从现在开始,窗口会侦听自身上的任何click事件,并在单击后执行给定的函数。此过程独立于注册之前或之后的代码。

所以你有两个选择来解决这个问题:

  • 检查elementID(window.removeEventlistenter('click', functionName))后删除事件侦听器。这仅在添加侦听器时给出的函数已经具有名称且不像您的情况那样内联时才有效。详情请看:https://developer.mozilla.org/de/docs/Web/API/EventTarget/removeEventListener
  • 或者您在第二个单击处理程序中进行布尔检查。因此,您可以阻止实际代码执行,并且您不必处理添加/删除事件侦听器。我会推荐这个解决方案。

让我知道这是否有帮助,或者有什么不清楚。

修改

chainMechanics(){
    let clickedElement;
    window.onclick = ((e)=>{
        if(this.props.inventory.activeItem.boltcutters===true){
            clickedElement = e.target;
            if(clickedElement.id === 'chainChainedDoor'){
                alert('you got it');
                this.props.dispatch(activate('boltcutters', false))
            } else {
                this.props.dispatch(activate('boltcutters', false));
                alert('try again')
                console.log(this.props.inventory.activeItem.boltcutters);
            }
        }
    })
}

修改2

function myFunc(e) {
     let clickedElement;
     if(this.props.inventory.activeItem.boltcutters===true){
            clickedElement = e.target;
            if(clickedElement.id === 'chainChainedDoor'){
                alert('you got it');
                this.props.dispatch(activate('boltcutters', false))
            } else {
                this.props.dispatch(activate('boltcutters', false));
                alert('try again')
                console.log(this.props.inventory.activeItem.boltcutters);
            }
        }
}

chainMechanics(){
    if (window.onclick !== myFunc) {
        window.onclick = ((e)=> myFunc(e))
    }
}

答案 1 :(得分:0)

我修好了,它不好看,很难看,但它确实有效。我在按钮上添加了id,然后第二次点击了boltcutters&#34;否则如果&#34;检查正在被激活,防止断裂器本身的状态改变,允许应用程序获取正确元素的ID并正常工作。

如果有人有更优雅的方式来解决这个问题,我愿意接受建议。

    chainMechanics(){
    let clickedElement;
    window.onclick = ((e)=>{
        console.log(clickedElement, 'clickedelement', this.props.inventory.activeItem.boltcutters)
        if(this.props.inventory.activeItem.boltcutters===true){
            clickedElement = e.target;
            if(clickedElement.id === 'chainChainedDoor'){
                alert('you got it');
                this.props.dispatch(activate('boltcutters', false))
            } else if(clickedElement.id === 'test'){
                console.log('Why wont you cooperate')
            } else {
                this.props.dispatch(activate('boltcutters', false));
                alert('try again')
                console.log(this.props.inventory.activeItem.boltcutters); 
            }
        }
    })
}