Javascript Onclick vs Onmousedown Race Condition

时间:2013-01-11 20:03:18

标签: javascript listener race-condition mousedown

我有一个表单的SUBMIT和SAVE按钮,默认情况下会监听Onclick事件。 当表单被提交或保存时 - 页面将滚动位置重置为页面顶部。

最近,应用程序的用户已请求页面停留在页面底部,按钮所在的位置仅用于表单的子集。 (这些按钮用于数百种其他形式,因此我无法全局更改滚动的重置。)

因此,我尝试实现的解决方案涉及一些隐藏的输入字段和一些事件侦听器。

我为这些按钮添加了一个onmousedown事件,就像这样 -

// Submit and Save button listeners
  var globalButtons;
  if (v_doc.getElementsByClassName) {
    globalButtons = v_doc.getElementsByClassName('globalbuttons');
  }
  // Internet Explorer does not support getElementsByClassName - therefore implement our own version of it here
  else {
    globalButtons = [];
    var myclass = new RegExp('\\b'+'globalbuttons'+'\\b');
    var elem = v_doc.body.getElementsByTagName("input");
    for (var i = 0; i < elem.length; i++) {
      var classes = elem[i].className;
      if (myclass.test(classes)) {
        globalButtons.push(elem[i]);
      }
    }
  }
  for (var gb = 0; gb < globalButtons.length; gb++) {
    if (globalButtons[gb].name == 'methodToCall.route' ||
        globalButtons[gb].name == 'methodToCall.save') {
      if(globalButtons[gb].addEventListener) { //all browsers except IE before version 9
         globalButtons[gb].addEventListener("mousedown", function(){flagSpecialScrollOnRefresh()},false);
      }
      else {
        if(globalButtons[gb].attachEvent) { //IE before version 9
           globalButtons[gb].attachEvent("onmousedown",function(){flagSpecialScrollOnRefresh()});
        }
      }
    }
    else { continue; }
  }

此代码位于名为attachButtonListeners

的函数中

接下来,我像这样定义了我的处理程序并将其放入另一个函数中,每次加载页面时都会调用它 -

function checkSpecialScrollCase() {
  var spfrm   = getPortlet();
  var sp_doc  = spfrm.contentDocument ? spfrm.contentDocument: spfrm.contentWindow.document;
  var specialScrollExists = sp_doc.getElementById(docTypeButton).value;

  if (specialScrollExists == "YES") {
    sp_doc.getElementById(docTypeButton).value = 'NO';
  }
  // else - nothing to do in this case
}

docTypeButton = REQS_BUTTONS 它引用了我的JSP页面底部的以下元素 -

<input type="hidden" id="REQS_BUTTONS" value="NO"/>
<a name="anchorREQS"></a>

注意锚标记。最后,我需要将location.hash调用添加到我的处理程序中,以便滚动到此位置。那部分在这一点上是无关紧要的,这就是原因。

问题 - 我的flagSpecialScrollOnRefresh函数不应该将值设置为YES。

我相信我的onClick事件发生得太快,以至于我的onmousedown事件不会发生。

证据 - 如果我发出类似的警告声明 -

function flagSpecialScrollOnRefresh() {
  var scfrm   = getPortlet();
  var sc_doc  = scfrm.contentDocument ? scfrm.contentDocument: scfrm.contentWindow.document;
  alert("BLAH!");
  sc_doc.getElementById(docTypeButton).value = "YES";
}

然后我使用Firebug检查元素 - 值正在变为SET! 一旦我拿出警报 - 不要去!

如何确保首先执行mousedown事件?或者这甚至是这里的问题????

1 个答案:

答案 0 :(得分:0)

mousedownclick事件的一部分。

现在,无论您使用click事件做什么,都应该转移到表单上的submit事件。这样,您可以在按钮上使用mousedownmouseover甚至click来做您想做的任何事情。