gpt4 book ai didi

javascript - jstree 委托(delegate)中意外创建多个实例

转载 作者:行者123 更新时间:2023-11-28 09:49:55 25 4
gpt4 key购买 nike

var json_string=$.parseJSON(document.getElementById("json_db").innerHTML);
$(function ()
{
$("#folder_tree").jstree({
contextmenu: {items: customMenu},
"json_data" : {data:json_string},
"plugins" : [ "themes", "json_data", "ui", "contextmenu" ],

});
});
function customMenu(node)
{
var items = { };
}



$('#folder_tree').delegate('a', 'contextmenu', function (e)
{

idn = $(this).parent().attr("id");
if(idn) pool_control(idn,e); //sendMsg(idn)

});

嗨,我在 jsTree 中发现了一些非常奇怪的东西。上面的代码显示了树的创建和委托(delegate)右键单击事件。sendMsg(idn) 向另一个页面发送 AJAX 请求。pool_control(idn,e) 使用该事件在单击的节点旁边显示一个表单。表单填写完毕后,它会调用 sendMsg。

当我直接在委托(delegate)事件处理程序(而不是 pool_control)中调用 sendMsg 时,该脚本完美运行。但是,当我通过 pool_control 调用它时,会发生这种情况:每个pool_control都被调用,没有。发送的 Ajax 请求数增加 1。请求的内容似乎是相同的,但我不知道为什么没有。 ajax 请求数量增加。当我直接调用 sendMsg 时,不会发生这种情况。

发生什么事了?我该如何解决这个问题?

pool_control 和 sendMsg:

function pool_control(id,ev)
{

$("#pool_count").css("left",ev.pageX);
$("#pool_count").css("top",ev.pageY);
$("#pool_count").css("visibility","visible");
$("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});
$("#poolcancel").click(function()
{
$('#pool_count').css('visibility','hidden');
});
}

function sendMsg(a,ev)
{

$('#pool_count').css('visibility','hidden');
var factid = $("#factid").val();
var floor = $("#floor").val();
var ceiling = $("#ceiling").val();
var pool_count = $('#poolsize').val();
var userid = document.getElementById("userid").innerHTML;
$.ajax(
{
type: "POST",
url: "generator.php",
data: {what:a,name:factid,author:userid,floor:floor,ceiling:ceiling,pool_count:pool_count},
async: false,
cache: false,
timeout:50000,
});
}

这是一个长轮询网页。 sendMsg 在树中发送用户所做的更改,并且不关心响应。另一个函数waitForMsg是长轮询ajax请求。当它看到由于 sendMsg 导致 db 发生变化时,它会再次调用 jstree() 函数来重新创建树。当我在树中进行更改时,sendMsg 第一次发送 1 个请求,第二次发送 2 个请求,第三次发送 3 个请求,依此类推。我很确定该函数没有任何问题,但就在这里,以防万一

function waitForMsg()
{
var lastupdate = document.getElementById("lastupdate").innerHTML;
var msg;
$.ajax({
type: "POST",
url: "oracle.php",
data: {lastupdate:lastupdate},
async: true,
cache: false,
timeout:20000,

success: function(data)
{
msg = data.split("@");
document.getElementById("lastupdate").innerHTML=msg[0];
document.getElementById("json_db").innerHTML=msg[1];
initPage(); //a <body onready> function which creates the tree again
setTimeout('waitForMsg()', 200 );
},
error: function(XMLHttpRequest, textStatus, errorThrown){
setTimeout('waitForMsg()', 1000);

}
});
}

最佳答案

由于事件在 jQuery 中的工作方式,每次使用 .click() 等函数附加事件时,该事件都会“堆叠”到列表中,而不是被替换。

通俗地说,代码如下:

    $("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});

不告诉 jQuery 在单击发生时运行此函数,而是将其添加到触发单击时应运行的事件列表中。 p>

也就是说,如果多次附加事件,例如通过以下方式:

    $("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});

$("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});

$("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});

结果将是(您猜对了)sendMsg() 每次点击都会被调用 3 次,因为附加的每个事件都是独立处理的。

由于每次调用 pool_control 时都会附加新的点击事件,因此每次调用 pool_control() 时,sendMsg() 调用的次数以及 ajax 请求都会增加 1。

修复?要么取消绑定(bind)点击事件,然后再在 pool_control() 中再次绑定(bind)它们:

function pool_control(id,ev)
{

$("#pool_count").css("left",ev.pageX);
$("#pool_count").css("top",ev.pageY);
$("#pool_count").css("visibility","visible");
$("#poolbutton").unbind('click').click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});
$("#poolcancel").unbind('click').click(function()
{
$('#pool_count').css('visibility','hidden');
});
}
或者,我个人更愿意推荐这种方式,因为它的开销较小,只需在初始化代码中附加一次事件。您可以随时附加事件,在您的示例中,在 pool_control() 外部的上下文菜单上调用委托(delegate)之前附加它们是完全可以的:

var json_string=$.parseJSON(document.getElementById("json_db").innerHTML);
$(function ()
{
$("#folder_tree").jstree({
contextmenu: {items: customMenu},
"json_data" : {data:json_string},
"plugins" : [ "themes", "json_data", "ui", "contextmenu" ],

});
});
function customMenu(node)
{
var items = { };
}

$("#poolbutton").click(function()
{
$('#pool_count').css('visibility','hidden');
sendMsg(id);
});
$("#poolcancel").click(function()
{
$('#pool_count').css('visibility','hidden');
});

$('#folder_tree').delegate('a', 'contextmenu', function (e)
{

idn = $(this).parent().attr("id");
if(idn) pool_control(idn,e); //sendMsg(idn)

});

function pool_control(id,ev)
{
$("#pool_count").css("left",ev.pageX);
$("#pool_count").css("top",ev.pageY);
$("#pool_count").css("visibility","visible");
}

此方法确保事件仅附加一次,并且只要您不破坏 #pool_count 就可以了,只要发生点击,事件就会被触发,而不必在 pool_control() 中关心它。

关于javascript - jstree 委托(delegate)中意外创建多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11204497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com