<select> 上的 jQuery 更改事件未在 IE 中触发

Posted

技术标签:

【中文标题】<select> 上的 jQuery 更改事件未在 IE 中触发【英文标题】:jQuery change event on <select> not firing in IE 【发布时间】:2010-12-10 21:14:33 【问题描述】:

我有一个包含可变数量的&lt;select&gt; 元素的页面(这解释了为什么我在这里使用事件委托)。当用户更改所选选项时,我想在页面上隐藏/显示不同的内容区域。这是我的代码:

$(document).ready(function() 
  $('#container').change(function(e) 
    var changed = $(e.target);

    if (changed.is('select[name="mySelectName"]')) 
      // Test the selected option and hide/show different content areas.
    
  );
);

这在 Firefox 和 Safari 中有效,但在 IE 中不会触发更改事件。有谁知道为什么?谢谢!

【问题讨论】:

根据 MSDN,更改事件不会在 IE 中冒泡,因此除非 jQuery 发挥作用,否则事件委托将不起作用:msdn.microsoft.com/en-us/library/ms536912(VS.85).aspx 【参考方案1】:

change 事件不会在 IE 中冒泡(请参阅 here 和 here)。您不能同时使用事件委托。

事实上,正是因为这个 IE 漏洞,jQuery live 不得不正式从 list of supported events 中排除 change(仅供参考,DOM 规范声明 change should bubble) .[1]

关于您的问题,您可以直接绑定到每个选择:

$('#container select').change(/*...*/)

如果您真的想要事件委托,您可能会在尝试 this person did 并仅在 IE 中绑定到 click 时取得一些成功,确实冒泡:

$('#container').bind($.browser.msie ? 'click' : 'change', function(event) 
    /* test event.type and event.target 
     * to capture only select control changes
     */
)

但是这种浏览器检测感觉真的不对。我真的会尝试使用前一个示例(直接绑定到下拉菜单)。除非您有数百个 &lt;select&gt; 框,否则事件委托不会在这里为您买太多。


[1] 注意:jQuery >= 1.4 现在通过live()/on() 在 IE 中模拟冒泡的change 事件。

【讨论】:

这将是您无法摆脱浏览器测试的情况之一,因为您无法真正进行功能测试。但是,要获得完整的解决方案,您还必须处理键盘导航的按键操作 @Juan:有些人认为检测冒泡事件的功能是可能的。见perfectionkills.com/… 太好了,谢谢。适用于此处的链接概述:该帖子是关于检测支持的事件。通过检查 div 上的“更改”事件,您将知道更改事件是否冒泡,因为 div 没有自己的更改事件。【参考方案2】:

可能有帮助的想法:

$(document).ready(function() 
  $('#container select[name="mySelectName"]').change(function(e) 
    var s = $(e.target);
    if (s.val()=='1') //hide/show something;
  );
);

如果你使用 AJAX,试试live() 函数:

 $(document).ready(function() 
       $('#container select[name="mySelectName"]').live('change', function(e) 
        var s = $(e.target);
        if (s.val()=='1') //hide/show something;
      );
    );

【讨论】:

jQuery/live() 不支持 change 事件。见docs.jquery.com/Events/live#typefn 1.4 支持 .live 的更改事件,但据我所知,事件本身在 IE 中仍然是一团糟。 .live() 现在在 1.7.7 中已弃用。【参考方案3】:

如果我没记错的话,你需要调用 blur() 来让 jQuery 在 IE 机器上调用 change()。尝试类似:

$("select[name=mySelectName]").click(function() 
    $(this).blur();
);

【讨论】:

不幸的是,这不起作用。即使 我不认为模糊会自动触发更改。但是,模糊会正确传播,因此解决方案可能是触发更改事件的委托模糊事件(如果您想检查旧值是否已更改,您甚至可以将旧值保存为数据)。这是一个黑客。不幸的是,正确的解决方案需要 MS 修复旧的 IE 版本【参考方案4】:

现在使用 jquery 1.4.4(我认为 1.4.3)似乎一切都很好......更改事件在我有限的测试中始终有效。

【讨论】:

我使用的是 jQuery 1.7。它适用于加载时页面上的选择,但不适用于之后动态添加的选择(当您填写最后一个现有行时,我会添加一个新行)。该问题似乎仅限于 IE 8 及以下版本。【参考方案5】:

将此行添加到您的页面标题,请高枕无忧! :)

$(document).ready(function()$('select').bind('onChange',function()$(this).blur()););

【讨论】:

【参考方案6】:

onchange=doAction 可以在 IE 和 Firefox 中使用,但在 Chrome 中不支持。

你需要使用jQuery的.change事件来处理这个。

【讨论】:

【参考方案7】:

我试图理解为什么您需要在收到事件后仔细检查选择的名称。

您是否有多个具有相同 id 的元素?

您的意思是说“#container select”而不是“#container”吗?

【讨论】:

没有。我正在使用事件委托,因为我不想将事件附加到页面上的每一个 页面上还有其他 您可以为选择元素本身添加一个ID【参考方案8】:

我只是在“Crescent Flesh”设置的示例的基础上构建一个跨平台解决方案,即使通过 AJAX 调用将这个 SELECT 加载到 #container 中,该解决方案也将继续存在。

$('#container').bind($.browser.msie ? 'click' : 'change', function(event) 
  if ((event.type == 'click') || (event.type == 'change')) 
    if (event.target.toString().indexOf('Select') != -1) 
      var sWhich = $('#container SELECT').val();
      handleSelectionChange(sWhich);
    
  
);

现在您只需构建 handleSelectionChange() 函数,并随意重命名它。

【讨论】:

【参考方案9】:

IE 要求将更改事件放置在准备好的文档中。这似乎将更改事件绑定到关联元素。希望对您有所帮助。

【讨论】:

【参考方案10】:

:D:D 哇,我正在寻找解决方案... 为什么想得这么复杂? 简单地说:&lt;select onchange="doAction"&gt;

【讨论】:

除了问题是专门针对 jQuery 的“更改”事件之外,提问者正在使用事件委托。 对不起,关于小主题的错过,但也许它会对寻找解决方案的人有所帮助,这些^想法在 IE 8 中对我不起作用:(

以上是关于<select> 上的 jQuery 更改事件未在 IE 中触发的主要内容,如果未能解决你的问题,请参考以下文章

Jquery:根据 <select> 属性设置 <option> 检查

jQuery Mobile 表单选择菜单

jQuery Mobile 表单选择菜单

带有多个属性的标记上的querySelector

jQuery操作<select>

jquery怎么获取select选中的值