2014-09-10 117 views
0

我有一块连接到asp.net web窗体前端的jQuery(窗体的输入控件包装在标准的asp.net AJAX面板中),它有三个下拉列表它连接了一块jQuery的名单:从Jquery函数中忽略返回值

$(document).ready(function() { 
    jQuery("select").change(function() { 
     alert("Hi"); 
     return false; 
    }); 
}); 

的下拉菜单有由ASP.NET连接服务器端更改事件,你会希望做回发:

<select name="ctl00$leftContent$cmbPressureUnitsPo" tabindex="6" class="unit" id="cmbPressureUnitsPo" onchange="javascript:setTimeout('__doPostBack(\'ctl00$leftContent$cmbPressureUnitsPo\',\'\')', 0)"> 
      <option value="1">kPag</option> 
      <option value="1000">Pag (N/m²)</option> 
      <option selected="selected" value="0.001">MPag</option> 
      <option value="0.14504">PSIg</option> 
      <option value="10">mBarg</option> 
      <option value="0.01">Barg</option> 
      <option value="0.010197">kgf/cm²</option> 
      <option value="0.010197">atg</option> 
      <option value="0.0098692">atmg</option> 
      <option value="7.5001">torrg (mmHg)</option> 
      <option value="101.97">mmH₂O</option> 
      <option value="0.29528">inHg</option> 

     </select> 

唯一的问题是返回false不会像我期望的那样压制服务器端事件!如果我实现了一个正常的JavaScript函数返回false,那么我错过了什么?

我也试过event.PreventDefault没有效果!

回答

0

看来__doPostBack方法被绑定到绑定到onchange处理程序的setTimeout

<select ... onchange="javascript:setTimeout('__doPostBack(\'ctl00$leftContent$cmbPressureUnitsPo\',\'\')', 0)"> 

事件处理程序(绑定到通过jQuery的select元素)将被称为来自不同的(我的猜测,之前,给出的setTimeout如何工作 - 但你永远不知道...定时器的怪癖)

+0

感谢杰克,你是非常正确的,它似乎setTimeout保证DOM实际上比任何其他方法加载更好似乎 - 本周通过包装代码解决了一些问题是零间隔计时器! – mmacneill123 2014-09-15 18:56:02

+0

@ mmacneill123 - 是的 - 你是对的,它的确如此! (虽然我看到了Mobile Safari的一些怪癖,即使setTimeout也不保证DOM更改存在......奇怪的东西!)您是否能够解决您的问题? – Jack 2014-09-15 19:40:16

+1

是的杰克,只是写在jQuery!从标记复制并粘贴生成的ASP.NET代码,设置Autopost = False,以便ASP.NET不再发出它,然后手动附加该事件。认为我越来越困惑正常的JavaScript处理程序和jQuery! – mmacneill123 2014-09-16 07:30:23

0

这是因为在运行jQuery绑定事件之前,HTML中的onchange先运行第一个。你无法阻止它运行,因为它已经有了。你需要做的是删除之前通过jQuery添加一个HTML绑定的事件。

$(document).ready(function(){ 
    var $select = jQuery('select'), // Cache jQuery selector 
     HTML_event = $select.prop('onchange'); // Backup original event 

    $select.removeProp('onchange'); // Remove original event 

    $select.change(function(e){ 
     alert("Hi"); 

     //HTML_event.call(this, e.originalEvent); // If you want to call the original event 
    }); 
}); 

另一种解决方案可能是保存timeoutID,然后在其上调用clearTimeout

<select onchange="window.selectTimeout = setTimeout(function(){}, 0)"> 
</select> 
$(document).ready(function(){ 
    jQuery('select').change(function(e){ 
     alert("Hi"); 

     clearTimeout(window.selectTimeout); // clears the timeout 
    }); 
}); 
+0

这里不服气!该警报显示为我所期望的,然后返回,然后重新发布页面!在堆栈上还有其他的例子,就是我之后的行为,例如, http://stackoverflow.com/questions/18002368/我知道我可以通过删除事件并将其添加回来解决此问题,这是我在别处所做的,但只是困惑为什么行为似乎如此不同! – mmacneill123 2014-09-11 09:11:53

+0

@ mmacneill123:在您的示例中,当您更改该值时,要触发的第一个事件是在HTML中设置的“onchange”。这在'setTimeout.'中调用'__doPostBack'函数。该超时意味着浏览器将运行您的jQuery绑定事件,稍后再回到'__doPostBack'。那么,你的事件就会运行,并且'alert'打开(暂停所有其他的JavaScript执行)直到它关闭。你不能“预防”onchange,因为它已经完成了。当警报关闭时,浏览器返回并从超时运行'__doPostBack'。 – 2014-09-11 14:47:39

+0

P.S. “onchange”中有一些不好的做法。 1)不要在'onchange'中添加'javascript:'(它不会像你想象的那样做),2)不要将一个字符串传递给'setTimeout'(它调用'eval')。 – 2014-09-11 14:48:51

0

我使用的实际解决方案是创建结合了ASP.NET生成回发一个单一的jQuery过程。通过从ASP.NET标记中删除Autopost = True,您可以精确控制正在发生的事情,并仍然调用ASP.NET回调函数,而是将其写入jQuery中。