使用jQuery以编程方式在Javascript for IE中触发事件

时间:2008-10-03 19:50:18

标签: asp.net javascript jquery internet-explorer

当IE中的用户触发事件时,它将设置为window.event对象。查看触发事件的唯一方法是访问window.event对象(据我所知)

如果以编程方式触发事件(例如通过jQuery触发事件),则会导致ASP.NET验证程序出现问题。在这种情况下,window.event对象存储最后一个用户触发的事件。

当以编程方式触发附加了ASP.NET验证程序的文本框的onchange事件时,验证会中断,因为它正在查看触发上一个事件的元素,而该元素不是验证器适用于。

有没有人知道解决这个问题的方法?这似乎是一个可以解决的问题,但从在线看,大多数人只是想方设法忽略问题而不是解决问题。


解释我在具体做什么:
我在文本框上使用了一个jQuery时间选择器插件,该插件还有2个与之关联的ASP.NET验证器。当时间改变时,我正在使用更新面板回发到服务器以动态执行某些操作,因此我需要触发onchange事件以触发该文本框的回发。

jQuery时间选择器通过创建隐藏的无序列表来操作,该列表在单击文本框时可见。单击其中一个列表项时,将通过jQuery的change()方法以编程方式为文本框触发“更改”事件。

因为事件的触发器是一个列表项,所以IE将列表项视为事件的来源,而不是文本框,就像它应该的那样。

我不太关心这个ASP.NET验证器在文本框更改后立即工作,我只需要处理“change”事件,以便为文本框调用我的回发事件。问题是验证器在IE中抛出一个异常,阻止任何事件被触发。

Firefox(我假设其他浏览器)没有此问题。由于事件模型不同,只有IE。有没有人遇到这个并看过如何解决它?


我发现这个问题报告了其他几个地方,但它们没有提供解决方案:

6 个答案:

答案 0 :(得分:7)

我遇到了同样的问题。使用此功能解决:

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();
        }
    });
}

答案 1 :(得分:4)

我用补丁解决了这个问题:

    window.ValidatorHookupEvent = function(control, eventType, body) {
        $(control).bind(eventType.slice(2), new Function("event", body));
    };

更新:我已将问题提交给MS(link)。

答案 2 :(得分:2)

根据您的描述,此问题可能是IE用于JS的独特事件冒泡模型的结果。

我唯一真正的答案是抛弃ASP.NET验证器并使用jQuery表单验证插件。然后您的文本框可以只是一个常规的ASP Webforms控件,当内容更改和回发发生时,一切都很好。此外,您还会从服务器代码中分离出更多客户端问题。

我从来没有太多运气将Webform Client控件(如Form Validation控件)与外部JS库(如jQuery)混合在一起。我发现更好的路线只是选择其中一种,而不是混合搭配。

不是你可能正在寻找的答案。

如果你想使用jQuery表单验证插件,请使用jQuery Form Validation

答案 3 :(得分:2)

在使用javascript启动事件之前,请考虑设置隐藏字段_EVENTTARGET值。您需要将其设置为服务器端ID(用客户端ID中的$替换下划线),以便服务器了解它。我在我模拟的按钮点击上执行此操作,以便服务器端可以确定在结果发回时触发哪个OnClick方法 - Ajax与否,并不重要。

答案 4 :(得分:2)

这是jQuery datepickers和ASP验证控件的地方性问题。 正如您所说,错误的元素交叉触发ASP NET javascript验证例程,然后M $代码抛出错误,因为例程中的触发元素未定义。

我通过决定M $应该更强大地编写代码并因此重新声明一些M $验证器代码来处理未定义的元素,从而与我见过的任何其他人不同地解决了这个问题。我所看到的其他所有内容基本上都是jQuery方面的解决方法,并且可以削减可能的功能(例如,使用click事件而不是更改)。

失败的位是

   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();
}

答案 5 :(得分:0)

这就是我解决一个类似问题的方法。 为datepicker写了一个onSelect()处理程序。 link text 在该函数中,称为__doPostBack('textboxcontrolid','')。 这触发了文本框到服务器的部分回发,该服务器依次调用验证器。