首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么当javascript之前的javascript更改元素的边框颜色时,确认()首先发生?

为什么当javascript之前的javascript更改元素的边框颜色时,确认()首先发生?
EN

Stack Overflow用户
提问于 2022-09-08 19:48:06
回答 3查看 44关注 0票数 0

我想简单地删除一个HTML元素时,通过JavaScript点击它,并在用户提供确认后。

单击后,但在确认之前,我希望该元素被高亮显示(有不同的边框颜色)。但是,在下面的代码中,确认发生在边框颜色更改之前。

css:

代码语言:javascript
复制
.test-box {
            border: 2px solid black;
            height: 200px;
            width: 200px;
            cursor: pointer;
        }

联署材料:

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', () => {
            const testBox = document.createElement('div')
            testBox.className = "test-box"
            document.body.append(testBox)
            // Remove testBox when clicked
            testBox.addEventListener('click', () => {
                // Highlight testBox to be deleted
                testBox.style.border = "2px solid yellow"
                // Confirm deletion
                const confirmation = confirm("Delete testBox?")
                if (confirmation) {
                    testBox.remove()
                } else {
                    // Remove highlight
                    testBox.style.border = "2px solid black"
                }
            })
        })

让它按需要工作的唯一方法是在确认中添加一个1ms超时,如下所示:

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', () => {
            const testBox = document.createElement('div')
            testBox.className = "test-box"
            document.body.append(testBox)
            // Remove testBox when clicked
            testBox.addEventListener('click', () => {
                // Highlight testBox to be deleted
                testBox.style.border = "2px solid yellow"
                // Delay confirmation so that highlight will happen before confirmation
                setTimeout(() => {
                    // Confirm deletion
                    const confirmation = confirm("Delete testBox?")
                    if (confirmation) {
                        testBox.remove()
                    } else {
                        // Remove highlight
                        testBox.style.border = "2px solid black"
                    }
                }, 1)
            })
        })

这是最好的方法吗?我想知道发生了什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-09-08 20:03:30

对DOM的更新不是即时的,确实需要一些时间才能完成。在本例中,您的更新发生在setTimeout()函数等待的1ms内,然后启动对confirm()的调用。这就是延迟函数调用的原因。没有setTimeout,Javascript线程在DOM完成更新之前调用confirm的文章很好地解释了正在发生的事情以及您可以做些什么来避免它。

票数 1
EN

Stack Overflow用户

发布于 2022-09-08 20:00:28

confirmalertinput阻止JavaScript引擎处理浏览器的事件队列,该队列将包括油漆作业。

允许执行画图循环的一种方法是使用requestAnimationFrame:它将在画图作业之前执行给定的回调,如果再次调用requestAnimationFrame,该回调将在该油漆作业之后,在下一次调用之前调用。您可以使用此行为来解决下一个油漆周期后的承诺。将事件处理程序定义为async,并等待该承诺:

代码语言:javascript
复制
const paintCycle = () => new Promise(resolve =>
    requestAnimationFrame(() => requestAnimationFrame(resolve))
);

const testBox = document.createElement('div')
testBox.className = "test-box"
document.body.append(testBox)
// Remove testBox when clicked
testBox.addEventListener('click', async () => {
    // Highlight testBox to be deleted
    testBox.style.border = "2px solid yellow"
    await paintCycle();
    // Confirm deletion
    const confirmation = confirm("Delete testBox?")
    if (confirmation) {
        testBox.remove()
    } else {
        // Remove highlight
        testBox.style.border = "2px solid black"
    }
})
代码语言:javascript
复制
.test-box:after {
    content: "click me"
 }

票数 2
EN

Stack Overflow用户

发布于 2022-09-08 19:52:08

因为:

  • JavaScript是单线程的.
  • 在阻塞操作完成之前,不会对UI进行更新。
  • confirm()是一种阻塞操作。

如果您想要使用confirm(),那么您想出的方法对于您想要实现的UX来说是一个合理的解决方案。一种更现代和干净的方法是根本不使用confirm() (或alert()prompt()),并在页面中构建一个模态确认对话框。(或者使用第三方一党,其中有很多。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73654377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档