Javascript事件同步

时间:2009-05-24 18:06:54

标签: javascript synchronization events

是否有可能在javascript中同步事件?

我的情况如下:我有一个包含许多字段的输入表单,每个字段都有一个onchange事件已注册。还有一个按钮可以打开弹出窗口,用于其他一些特殊事物。

我的要求是,在我打开弹出窗口之前,onchange事件已经完成。

如何在不使用setTimeout的情况下实现这一目标?

编辑:对要求的进一步说明:

为了澄清我的情况,我试着详细说明我在做什么。

我得到了一个包含一些输入项的表单(订单输入矩阵表单,例如文章,序列号,计数)。每当用户更改其中一个字段中的数据时,ajax调用由onchange事件触发,以验证用户输入并读取其他数据(例如,预设/格式化其他字段之一)。这些ajax调用很繁重,而且成本时间很长,所以我必须避免重复验证。 还有一个按钮,打开一个弹出窗口,为用户提供另一种形式来更改他在逐行之前输入的数据,因此绝对有必要在打开此弹出窗口之前完成所有验证。 目前我尝试使用setTimeout同步onchange事件和弹出窗口(在完成所有验证之前未打开弹出窗口),这会导致我的客户站点出现问题,因为弹出窗口阻止程序会捕获这些弹出窗口。 所以我需要打开我的弹出窗口而不会被一些弹出窗口阻止程序(IE 6/7/8)阻止。

由于我的矩阵形式,我只是无法在打开弹出窗口之前验证所有输入项目,我只需要验证那些已经更改但尚未验证的项目(最多应为1)。

7 个答案:

答案 0 :(得分:2)

听起来您正在进行表单验证,并在表单完全完成时自动弹出窗口。为此,您在javascript中编写一个验证函数来检查表单上的每个字段。您可以从每个OnChange事件中触发此函数,并在整个表单成功验证时让该函数打开弹出窗口。

当你有一点空闲时间时,请考虑查看jQuery。

http://jquery.com/

答案 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)

为每组验证设置标志​​(变量)。

  • 在0开始标记。
  • 将标志设置为1,何时 该组的验证已完成。
  • 当用户弹出按钮时,如果全部 flags为1,弹出窗口。

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验证。如果有任何待处理的验证,则单击“完成”将不允许用户关闭向导。为此我们只需要一个待处理验证的计数器,以及一个标志,表示用户是否希望关闭向导。基本算法是:

  • 如果启动了新的AJAX验证,请增加“待处理”计数。
  • 当AJAX验证返回时,减少“待处理”计数。
  • 如果在递减时,待处理的计数达到零,则检查“完成”标志;如果已设置,请完成向导。
  • 当用户点击完成时,检查“待定”计数;如果它为零,则完成向导;它不为零,设置“完成”标志。

这样,只需两个变量(“pending”,“finish”)即可处理同步。

我强烈建议不要为每个不同的AJAX操作使用多个标志;当使用多个状态变量跟踪状态时,状态机通常会失控。除非绝对必要,否则尽量避免使用它。

我也不建议使用setTimeout任意等待直到满足所需的条件。使用上面的计数器方法,您的代码将在更改条件后立即采取行动。