是否有可能在javascript中同步事件?
我的情况如下:我有一个包含许多字段的输入表单,每个字段都有一个onchange事件已注册。还有一个按钮可以打开弹出窗口,用于其他一些特殊事物。
我的要求是,在我打开弹出窗口之前,onchange事件已经完成。
如何在不使用setTimeout的情况下实现这一目标?
编辑:对要求的进一步说明:
为了澄清我的情况,我试着详细说明我在做什么。
我得到了一个包含一些输入项的表单(订单输入矩阵表单,例如文章,序列号,计数)。每当用户更改其中一个字段中的数据时,ajax调用由onchange事件触发,以验证用户输入并读取其他数据(例如,预设/格式化其他字段之一)。这些ajax调用很繁重,而且成本时间很长,所以我必须避免重复验证。 还有一个按钮,打开一个弹出窗口,为用户提供另一种形式来更改他在逐行之前输入的数据,因此绝对有必要在打开此弹出窗口之前完成所有验证。 目前我尝试使用setTimeout同步onchange事件和弹出窗口(在完成所有验证之前未打开弹出窗口),这会导致我的客户站点出现问题,因为弹出窗口阻止程序会捕获这些弹出窗口。 所以我需要打开我的弹出窗口而不会被一些弹出窗口阻止程序(IE 6/7/8)阻止。
由于我的矩阵形式,我只是无法在打开弹出窗口之前验证所有输入项目,我只需要验证那些已经更改但尚未验证的项目(最多应为1)。
答案 0 :(得分:2)
听起来您正在进行表单验证,并在表单完全完成时自动弹出窗口。为此,您在javascript中编写一个验证函数来检查表单上的每个字段。您可以从每个OnChange事件中触发此函数,并在整个表单成功验证时让该函数打开弹出窗口。
当你有一点空闲时间时,请考虑查看jQuery。
答案 1 :(得分:1)
您可以对onchange事件设置一个小回调,以确保在弹出窗口之前进行所有验证。
function onChange(callback)
{
// Do validation
// Call the callback
callback();
}
function showPopup()
{
// Show the popup
}
然后在你的onchange电话上打电话
onChange(showPopup);
答案 2 :(得分:0)
如果设置全局变量并使用setTimeout检查它是否设置正确。根据情况的复杂程度,你可以使用布尔值,两个布尔值,一个递增的数字,甚至一个对象。就个人而言,我会亲自使用一个对象,因为我知道哪一个还没有被解雇。像var isDone = {username: 0, password: 0, password2: 0};
答案 3 :(得分:0)
假设输入字段只表示文本输入,而不是任何复选框或combox(我猜你试图进行某种自动完成)。 我的建议是使用onkeyup和onkeydown。
var keypressed = false;
function onkeydown( )
{
keypressed = true;
}
function onkeyup( )
{
keypressed = false;
setTimeout( function()
{
if (!keypressed)
show_popup();
else
setTimeout( this.calee,1000)
}, 1000 );
}
答案 4 :(得分:0)
为每组验证设置标志(变量)。
Jon提到的回调可以解决“如果还没有完全验证你会怎么做?”的问题。
编辑:澄清后添加:
您是否考虑过通过DOM方法(简单)添加弹出按钮(或者如果您愿意,还可以添加innerHTML), 之后是否验证了所有内容?这样,在它的时间之前没有显示任何选项。 :D
另外,您是否测试弹出窗口是否被阻止?如果是,您可以分支到用户通知他们的阻止程序阻止编辑器;或者自动将编辑器加载到iframe中;或者通过DOM方法将编辑器加载到主页面(附加documentFragment等)。
一些拦截器让用户可以选择阻止点击链接产生的弹出窗口(传统上禁止阻挡者)。我认为你会受益于某种备份方法,或者至少是一个警告系统,无论如何。
HTH
答案 5 :(得分:0)
我不认为我完全理解你的问题,但这里有一些关于解决你可能所遇问题的想法:)
首先,我会在发送ajax调用时停用弹出窗口按钮。然后,当请求的数据到达并完成所有验证时,再次激活它。您可以使用计数器执行此操作:为每个已发送的请求递增它,在数据到达并且验证完成后递减它。当数据到达且计数器为零时激活弹出窗口按钮。这可以防止用户在仍有待处理的验证请求时单击弹出打开按钮。
您可以对输入字段本身使用相同的技术:通过将输入字段设置为只读来锁定等待验证的输入字段,在完成所有操作后将其解锁。
为防止用户在尚未返回ajax调用时更改表单值时出现问题,您有以下几种选择:
使用计时器发送请求:每次触发onchange事件时,请在发送请求前等待x秒。如果在发送ajax请求之前发生了另一个onchange事件,请重置该计时器。这样,几个具有特定时间帧的onchange事件只触发1个ajax请求。这有助于减轻负担。
您可以为每个位置计算和存储校验和,因此如果触发了onchange事件,请再次计算校验和并进行比较。通过这种方式,您可以了解哪些部分确实已更改,从而避免了不必要的验证请求。
另外,永远不要打赌(如果我理解了settimeout的东西吧)。在正常情况下x秒可能就足够了,但在最坏的情况下......
答案 6 :(得分:0)
我们需要类似的向导,其中一些步骤需要AJAX验证。如果有任何待处理的验证,则单击“完成”将不允许用户关闭向导。为此我们只需要一个待处理验证的计数器,以及一个标志,表示用户是否希望关闭向导。基本算法是:
这样,只需两个变量(“pending”,“finish”)即可处理同步。
我强烈建议不要为每个不同的AJAX操作使用多个标志;当使用多个状态变量跟踪状态时,状态机通常会失控。除非绝对必要,否则尽量避免使用它。
我也不建议使用setTimeout
任意等待直到满足所需的条件。使用上面的计数器方法,您的代码将在更改条件后立即采取行动。