使用 jQuery 在 IE 的 Javascript 中以编程方式触发事件
Posted
技术标签:
【中文标题】使用 jQuery 在 IE 的 Javascript 中以编程方式触发事件【英文标题】:Programmatically triggering events in Javascript for IE using jQuery 【发布时间】:2010-09-15 04:17:27 【问题描述】:当用户在 IE 中触发事件时,它被设置为window.event
对象。查看触发事件的唯一方法是访问window.event
对象(据我所知)
如果以编程方式触发事件(例如通过 jQuery 触发事件时),这会导致 ASP.NET 验证器出现问题。在这种情况下,window.event
对象存储了最后一个用户触发的事件。
当 onchange
事件以编程方式为附加了 ASP.NET 验证器的文本框触发时,验证会中断,因为它正在查看触发最后一个事件的元素,而不是验证器所在的元素为。
有人知道解决这个问题的方法吗?这似乎是一个可以解决的问题,但从网上看,大多数人只是想方设法忽略问题而不是解决它。
具体说明我在做什么: 我在一个文本框上使用 jQuery 时间选择器插件,该文本框也有 2 个与之关联的 ASP.NET 验证器。当时间更改时,我使用更新面板回发到服务器以动态执行某些操作,因此我需要触发 onchange 事件以触发该文本框的回发。
jQuery 时间选择器通过创建一个隐藏的无序列表进行操作,当单击文本框时该列表可见。当单击列表项之一时,会通过 jQuery 的 change()
方法以编程方式为文本框触发“更改”事件。
因为事件的触发器是一个列表项,所以 IE 将 列表项 视为事件的来源,而不是文本框,就像它应该的那样。
我不太关心这个 ASP.NET 验证器在文本框更改后立即工作,我只需要处理“change
”事件,以便为文本框调用我的回发事件。问题是验证器在 IE 中抛出异常,阻止任何事件被触发。
Firefox(我假设其他浏览器)没有这个问题。由于事件模型不同,只有 IE。有没有人遇到过这个问题并知道如何解决?
我在其他几个地方发现了这个问题,但他们没有提供解决方案:
jQuery's forum, with the jQuery UI Datepicker and an ASP.NET Validator ASP.NET forums, bug with ValidatorOnChange() function【问题讨论】:
【参考方案1】:我遇到了同样的问题。使用此函数解决:
jQuery.fn.extend(
fire: function(evttype)
el = this.get(0);
if (document.createEvent)
var evt = document.createEvent('htmlEvents');
evt.initEvent(evttype, false, false);
el.dispatchEvent(evt);
else if (document.createEventObject)
el.fireEvent('on' + evttype);
return this;
);
所以我对 datepicker 的“onSelect”事件处理程序看起来像:
if ($.browser.msie)
datepickerOptions = $.extend(datepickerOptions,
onSelect: function()
$(this).fire("change").blur();
);
【讨论】:
太棒了。感谢您提供最佳解决方案。【参考方案2】:我用补丁解决了这个问题:
window.ValidatorHookupEvent = function(control, eventType, body)
$(control).bind(eventType.slice(2), new Function("event", body));
;
更新:我已将问题提交给 MS (link)。
【讨论】:
你把这段代码放在哪里?这个问题让我头疼!我的验证事件现在根本没有被触发。 注册ClientScriptManager.RegisterStartupScript(...)
嗯,我添加了以下代码。它不会影响任何东西 - 错误仍然存在。这是 SharePoint 2010 下的 .NET 3.5 SP1 解决方案。 ClientScriptManager cm = Page.ClientScript;字符串键=“GRR”; if (!cm.IsStartupScriptRegistered(key)) string script = "window.ValidatorHookupEvent = function(control, eventType, body) $(control).bind(eventType.slice(2), new Function(\"event\" , 身体)); ;”; cm.RegisterStartupScript(this.GetType(), key, script, true);
OK +1 得到了这个工作,事件现在按预期触发谢谢:-)【参考方案3】:
根据您的描述,这个问题很可能是 IE 用于 JS 的独特事件冒泡模型的结果。
我唯一真正的答案是放弃 ASP.NET 验证器并改用 jQuery 表单验证插件。然后你的文本框可以只是一个常规的 ASP Webforms 控件,当内容发生变化和回发时一切都很好。此外,您还可以将更多的客户端问题与服务器代码分开。
在将 Webform Client 控件(如 Form Validation 控件)与外部 JS 库(如 jQuery)混合使用时,我从来没有这么幸运过。我发现更好的方法是选择其中一种,而不是混合搭配。
不是您可能正在寻找的答案。
如果你想使用 jQuery 表单验证插件,请考虑这个jQuery Form Validation
【讨论】:
我的问题是我的公司想要严格使用 ASP 验证器。到目前为止,我这样做没有问题,但我认为我将不得不考虑使用 jQuery 验证,因为我当前的解决方案不起作用。【参考方案4】:考虑在使用 javascript 启动事件之前设置隐藏字段 _EVENTTARGET 值。您需要将其设置为服务器端 ID(在客户端 ID 中将下划线替换为 $),以便服务器理解它。我在我模拟的按钮单击上执行此操作,以便服务器端可以确定在返回结果时触发哪个 OnClick 方法——Ajax 与否,并不重要。
【讨论】:
因为 jQuery 不是 Microsoft 技术,并且 __EVENTTARGET 隐藏字段仅适用于 ASP.NET Web 表单,并且仅当页面上的元素有关联的事件处理程序时,我相信。 IMO 整个基于“事件”的回发模型并不适合网络,我预计随着 MVC 的声名鹊起,它会消失。【参考方案5】:这是 jQuery 日期选择器和 ASP 验证控件的地方性问题。 正如您所说,错误的元素会交叉触发 ASP NET javascript 验证例程,然后 M$ 代码会抛出错误,因为该例程中的触发元素未定义。
我解决这个问题的方式与我见过的其他人不同——决定 M$ 应该更健壮地编写他们的代码,因此重新声明了一些 M$ 验证器代码来处理未定义的元素。我所看到的其他一切本质上都是 jQuery 方面的一种解决方法,并削减了可能的功能(例如,使用单击事件而不是更改)。
失败的位是
for (i = 0; i < vals.length; i++)
ValidatorValidate(vals[i], null, event);
当它试图获取未定义的 'vals' 的长度时会引发错误。
我刚刚加了
if (vals)
for (i = 0; i < vals.length; i++)
ValidatorValidate(vals[i], null, event);
她很高兴。下面是重新声明整个违规函数的最终代码。我把它作为脚本包含在我的母版页或页面的底部。
是的,如果 M$ 决定将来更改其验证器代码,这确实会破坏向上的兼容性。但希望他们能修复它,然后我们可以完全摆脱这个补丁。
// Fix issue with datepicker and ASPNET validators: redeclare MS validator code with fix
function ValidatorOnChange(event)
if (!event)
event = window.event;
Page_InvalidControlToBeFocused = null;
var targetedControl;
if ((typeof (event.srcElement) != "undefined") && (event.srcElement != null))
targetedControl = event.srcElement;
else
targetedControl = event.target;
var vals;
if (typeof (targetedControl.Validators) != "undefined")
vals = targetedControl.Validators;
else
if (targetedControl.tagName.toLowerCase() == "label")
targetedControl = document.getElementById(targetedControl.htmlFor);
vals = targetedControl.Validators;
var i;
if (vals)
for (i = 0; i < vals.length; i++)
ValidatorValidate(vals[i], null, event);
ValidatorUpdateIsValid();
【讨论】:
虽然这并不能直接回答上述问题,但它解决了 Datepicker-IE 的另一个问题 :)【参考方案6】:这就是我解决类似问题的方法。 为日期选择器编写了一个 onSelect() 处理程序。 link text 在那个函数中,称为 __doPostBack('textboxcontrolid','')。 这触发了将文本框部分回发到服务器,服务器依次调用验证器。
【讨论】:
以上是关于使用 jQuery 在 IE 的 Javascript 中以编程方式触发事件的主要内容,如果未能解决你的问题,请参考以下文章