9

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

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

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

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


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

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

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

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

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


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

4

6 回答 6

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();
        }
    });
}
于 2008-12-16T14:09:34.060 回答
4

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

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

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

于 2012-01-24T20:48:04.120 回答
2

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

我唯一真正的答案是放弃 ASP.NET 验证器并改用 jQuery 表单验证插件。然后你的文本框可以只是一个普通的 ASP Webforms 控件,当内容发生变化和回发时一切都很好。此外,您将更多的客户端问题与服务器代码分开。

将 Webform Client 控件(如 Form Validation 控件)与外部 JS 库(如 jQuery)混合使用时,我从来没有运气好过。我发现更好的方法是选择其中一种,而不是混合搭配。

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

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

于 2008-10-03T23:57:04.840 回答
2

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

于 2008-10-05T12:54:37.110 回答
2

这是 jQuery datepickers 和 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();
}
于 2010-05-25T13:46:26.917 回答
0

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

于 2008-11-29T12:11:33.900 回答