Javascript:如何临时禁用页面上的所有操作?

Javascript:如何临时禁用页面上的所有操作?,javascript,events,Javascript,Events,在带有Ajax事件的页面上,我想禁用所有操作,直到Ajax调用返回(以防止双重提交等问题) 我通过在return false前面加上前缀来尝试这一点添加到当前onclick事件,并在稍后“解锁”页面时删除此事件。但是,这些操作在“解锁”后将不再处于活动状态——您无法触发它们 为什么这不起作用?参见下面的示例页面。还有什么其他想法可以实现我的目标吗 示例代码: 链接和按钮都显示JS警报;按lock时,然后解锁事件处理程序与以前相同,但不起作用 该准则最终将与特立尼达合作,但也应在外部发挥作用 &l

在带有Ajax事件的页面上,我想禁用所有操作,直到Ajax调用返回(以防止双重提交等问题)

我通过在
return false前面加上前缀来尝试这一点添加到当前onclick事件,并在稍后“解锁”页面时删除此事件。但是,这些操作在“解锁”后将不再处于活动状态——您无法触发它们

为什么这不起作用?参见下面的示例页面。还有什么其他想法可以实现我的目标吗

示例代码:
链接和按钮都显示JS警报;按lock时,然后解锁事件处理程序与以前相同,但不起作用
该准则最终将与特立尼达合作,但也应在外部发挥作用

<html><head><title>Test</title>

<script type="text/javascript">
function lockPage()
{
  document.body.style.cursor = 'wait';
  lockElements(document.getElementsByTagName("a"));
  lockElements(document.getElementsByTagName("input"));

  if (typeof TrPage != "undefined")
  {
    TrPage.getInstance().getRequestQueue().addStateChangeListener(unlockPage);
  }
}

function lockElements(el)
{
  for (var i=0; i<el.length; i++)
  {
    el[i].style.cursor = 'wait';
    if (el[i].onclick)
    {
      var newEvent = 'return false;' + el[i].onclick;
      alert(el[i].onclick + "\n\nlock -->\n\n" + newEvent);
      el[i].onclick = newEvent;
    }
  }
}

function unlockPage(state)
{
  if (typeof TrRequestQueue == "undefined" || state == TrRequestQueue.STATE_READY)
  {
    //alert("unlocking for state: " + state);
    document.body.style.cursor = 'auto';
    unlockElements(document.getElementsByTagName("a"));
    unlockElements(document.getElementsByTagName("input"));
  }
}

function unlockElements(el)
{
  for (var i=0; i<el.length; i++)
  {
    el[i].style.cursor = 'auto';
    if (el[i].onclick && el[i].onclick.search(/^return false;/)==0)
    {
      var newEvent = el[i].onclick.substring(13);
      alert(el[i].onclick + "\n\nunlock -->\n\n" + newEvent);
      el[i].onclick = newEvent;
    }
  }
}
</script>

<style type="text/css">
</style>
</head>

<body>

<h1>Page lock/unlock test</h1>

<p>Use these actions to lock or unlock active elements on the page:
<a href="javascript:lockPage()">lock</a>,
<a href="javascript:unlockPage()">unlock</a>.</p>

<p>And now some elements:</p>

<a onclick="alert('This is the action!');return false;" href="#">link action</a> &nbsp;
<input type="button" value="button action" onclick="alert('This is another action!')"/>
</body>
</html>
测试
函数lockPage()
{
document.body.style.cursor='wait';
lockElements(document.getElementsByTagName(“a”);
lockElements(document.getElementsByTagName(“输入”);
if(TrPage的类型!=“未定义”)
{
TrPage.getInstance().getRequestQueue().addStateChangeListener(解锁页面);
}
}
功能锁定元件(el)
{

对于(var i=0;i我曾经通过创建一个DIV来实现这个目标,该DIV覆盖了我想要禁用的区域,将其
z-index
设置为高于页面上的任何其他元素,然后将其
opacity
设置为
0
。默认情况下,该DIV被
display:none
隐藏,这样它就不会干扰任何内容g、 但是,当我想禁用该区域时,我只是将其
显示设置为


史蒂夫

建立一个全球风险值怎么样

actions_disabled = 0
AJAX调用开始时递增,结束时递减

if (actions_disabled) return false;
比调试自修改代码简单得多

或者,要锁定控件,可以设置:

control.disabled="disabled"
这将有一个额外的好处,就是将它们变灰,让用户清楚地知道它们无法提交。要解锁,只需设置:

control.disabled=""
基于注释的新想法(无法在注释中引用代码,似乎是…):

您始终可以挂起Javascript对象的额外属性:

要锁定,您可以:

control.onclick_old = control.onclick
control.onclick = "return false;"
control.onclick = control.onclick_old
要解锁,您可以:

control.onclick_old = control.onclick
control.onclick = "return false;"
control.onclick = control.onclick_old

AJAX.Asynchronous。只需使HTTP请求同步。问题已解决。

代码中的问题是由于没有掌握javascript中的类型

当你说:

var newEvent = 'return false;' + el[i].onclick
这样做的目的是将el[i].onclick(这是一个函数)强制为字符串,然后将其连接到字符串“return false;”。然后,当您将其重新指定为该字符串时:

el[i].onclick = newEvent;
onclick以前是函数,现在是字符串

然后,通过获取子字符串,尝试从字符串中恢复旧函数:

var newEvent = el[i].onclick.substring(13);
这很好,只是newEvent仍然是一个字符串!因此,当您再次将其分配回onclick时,您分配的是原始函数的字符串表示形式,而不是函数本身

您可以使用eval对字符串求值并返回函数,但请不要这样做。正如其他评论员所建议的,有许多更好的方法可以做到这一点


我还想问,如果你不想允许异步请求,为什么要使用AJAX。

使用div覆盖并不能阻止用户进入你的页面。通常这是可以的,因为大多数用户无论如何都不会在页面上进行制表

如果您在页面上使用任何键盘快捷键,它们仍然可用,因此需要单独处理这些快捷键

同样,我假设单击一个可以有焦点的元素(例如,
标记),然后按enter键,仍然会导致双重提交。

将lockPage()放在activete()函数的顶部,将unlockPage()放在deactivate()函数的底部

激活:函数(){
函数lockPage()
{
lockElements(document.getElementsByTagName(“a”);
lockElements(document.getElementsByTagName(“输入”);
lockElements(document.getElementsByTagName(“按钮”);
};
功能锁定元件(el)
{

for(var i=0;我希望得到答案,但这实际上不是客户想要的…;-(页面应保持不变(所有按钮、字段等均可见)但只需防止用户再次触发另一个操作或相同的操作。这就是建议的。页面不会有任何可见的更改。您甚至不需要更改不透明度-只需将div保持为空,并在“无”和“块”之间切换显示属性。哦,是的,我明白了。应该更仔细地阅读此内容ly;)将尝试这种方法…这种技术也不会阻止用户使用键盘操纵页面…谢谢,但不幸的是,操作代码是由Trinidad framework生成的,我不能直接更改它。这就是为什么我必须使用JS来更改事件处理程序代码的原因。你能“包装”吗操作:函数thingo_wrap(e){if(actions_disabled)返回false;返回原始的东西(e)}另请参见上面的替代建议。好主意…我不能直接这样做,但可能会再次使用一些JS来修改操作。我的原始解决方案不起作用的原因似乎是我混淆了函数和字符串,对吗?我会尝试一下。或者,我可能会使用映射来存储原始操作,稍后再还原它…酷…这最后一个基于评论的新想法真的很好,我没有想到。效果很好,对现有代码做了一些小改动。谢谢!你说得对,但是…一方面,这部分代码是由我们的Web FW生成的,我对此没有直接控制权。另一方面,主要目的是防止重复提交(作为现有服务器端检测的附加层)因此,所有页面上都应该使用相同的机制,而不仅仅是Ajax调用。刚才提到的Ajax就是一个例子:(