写在前面:
我是一个新手,希望各位看到此贴后,有不同见解的多多指正,不怕喷。
问题提出:
在写一个将链表显示在页面表格上的 js/jq 程序,要实现右键点击表格项时,弹出 增/删/改菜单。在用户在数据操作后,将受到影响的数据通过表格项背景色的变化表现出来,并通过弹出的confirm框等待用户确认。程序的执行逻辑是:右键菜单“删除数据”项变点击---->将受影响项背景改变颜色----->弹出confirm菜单---->根据用户选择操作数据。
这里遇到一个问题,如果将上述逻辑写在 删除菜单项被点击 的事件响应函数中,总是出现红圈2所示confirm框先弹出,红圈1所示表格位置无法改变颜色的情况。
网上查了很多资料,这一问题主要是因为:confirm是主线程执行的,而页面加载是异步线程执行的,在主线程遇到confirm后会阻塞运行。因此,即使在程序中加入等待,无论等待多长时间,页面也不会被刷新。网上的很多办法都试验了,均无效。
解决思路:既然问题无法在主线程结束前解决,那就放在线程结束后解决。
我将解决问题的主要代码总结如下 :点击红色div后,div颜色会变为蓝色,弹出框会出现。
<!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">
<script src="jquery-3.5.1.min.js"></script>
<!--这里需要引入jq,如果不想改程序,请交.html文件与jq文件放在同一目录下-->
<title>Document</title>
</head>
<body>
<div style="width: 200px;height: 200px;background-color: red;" id="main">
</div>
</body>
</html>
<script>
function addEventFunction(jqueryDom, dataList) {
jqueryDom.click(function (e) {
jqueryDom.css('background', 'blue');
//这里定义了一个事件,事件处理函数可以在线程结束后被执行,为了解决更多问题,需要将一些数据传入
jqueryDom.one('left-button-menu-delete-data', function (event, jqDom, datalist) {
let ret = confirm("颜色会在我之前改变");
console.log('这里是传过来的数据:', jqDom, datalist);
})
//这里将线程启动,为了线程启动时addEventFunction程序已经执行完,使用了setTimeout函数
setTimeout(function (a1, a2) { $("#main").trigger("left-button-menu-delete-data", [a1, a2]) }, 1, jqueryDom, dataList);
})
};
$(document).ready(function () {
data = ['这是第一个数据', '这是第二个数据'];
addEventFunction($('#main'), data);
})
</script>
为了对比,我将解决问题之前的代码附上,用于各位看官对比:点击红色div后,div颜色不会变,弹出框出现,弹出框消失后,div颜色会变为蓝色。
<script>
function addEventFunction(jqueryDom, dataList) {
jqueryDom.click(function (e) {
jqueryDom.css('background', 'blue');
let ret = confirm("颜色会在我之后改变");
})
};
$(document).ready(function () {
data = ['这是第一个数据', '这是第二个数据'];
addEventFunction($('#main'), data);
})
</script>