使jQuery识别IE中的.change()


131

当单选按钮组被更改/单击时,我正在使用jQuery隐藏和显示元素。它在Firefox之类的浏览器中运行良好,但是在IE 6和IE 7中,仅当用户单击页面上的其他位置时,该操作才会发生。

详细地说,当您加载页面时,一切看起来都很好。在Firefox中,如果单击单选按钮,则会隐藏一个表行,而另一行会立即显示。但是,在IE 6和7中,单击单选按钮,直到单击页面上的任何位置,都不会发生任何事情。IE才会重新绘制页面,隐藏并显示相关元素。

这是我正在使用的jQuery:

$(document).ready(function () {
  $(".hiddenOnLoad").hide();

  $("#viewByOrg").change(function () {
    $(".visibleOnLoad").show();
    $(".hiddenOnLoad").hide();
  });

  $("#viewByProduct").change(function () {
    $(".visibleOnLoad").hide();
    $(".hiddenOnLoad").show();
  });
});

这是XHTML会影响的部分。整个页面验证为XHTML 1.0 Strict。

<tr>
  <td>View by:</td>
  <td>
    <p>
      <input type="radio" name="viewBy" id="viewByOrg" value="organisation"
      checked="checked" />Organisation</p>
    <p>
      <input type="radio" name="viewBy" id="viewByProduct" value="product" />Product</p>
  </td>
</tr>
<tr class="visibleOnLoad">
  <td>Organisation:</td>
  <td>
    <select name="organisation" id="organisation" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>
<tr class="hiddenOnLoad">
  <td>Product:</td>
  <td>
    <select name="product" id="product" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>

如果有人对为什么发生这种情况以及如何解决有任何想法,将不胜感激!

Answers:


96

尝试使用.click代替.change


3
@samjudson,在我的测试中,这是不正确的,当我使用箭头键选择下一个单选按钮时,jquery的点击确实会触发。(vista,ie7)
svandragt

1
@Pacifika:不适用于IE7。至少它是正确的。“点击”与“更改”是完全不同的事件,至少在某些情况下(如果不是全部),它是不适当的替代。
鲍比·杰克

3
@samjudson:使用键盘选择单选按钮时,单击事件也将触发复选框。适用于所有浏览器
Philippe Leybaert

4
我的立场是正确的-确实如此,但是可能违反直觉!
鲍比·杰克

2
这似乎是对这个特定问题的最流行答案,但这并不完全正确!click区别在于,change单击已选择的选项时也会调用其事件处理程序,而change不会。这个答案有一个示例,说明如何使用jQuery .data比较旧值和新值。
Laoujin 2012年

54

使用click事件而不是事件的问题change是,如果选择了相同的单选框(即实际上未更改),则会得到事件。如果您检查新值是否与旧值不同,则可以将其滤除。我觉得这有点烦人。

如果您使用 change事件,则可能会注意到在单击IE中的任何其他元素后,它将识别出更改。如果您呼叫blur()click事件,则将导致该change事件触发(仅在单选框实际上已更改的情况下)。

这是我的做法:

// This is the hack for IE
if ($.browser.msie) {
  $("#viewByOrg").click(function() {
    this.blur();
    this.focus();
  });
}

$("#viewByOrg").change(function() {
  // Do stuff here
});

现在,您可以像平常一样使用change事件。

编辑:添加了对focus()的调用以防止可访问性问题(请参见下面的Bobby的评论)。


2
这是一个非常邪恶的技巧,因为它会阻止用户使用键盘进行导航,因为选择单选按钮后焦点便消失了。
菲利普·莱伯特

5
这很好,但是会导致键盘可访问性问题。一旦触发了blur()事件,单选按钮就不再聚焦,因此使用键盘在单选按钮之间移动变得非常尴尬。我当前的解决方案是添加对“ this.focus();”的调用 在blur()语句之后。
鲍比·杰克

1
由于可访问性问题,我认为这是目前最糟糕的解决方案。
菲利普·莱伯特

11
但是可访问性问题可以通过调用focus()来解决。至少与对所有内容使用click()一样好。
鲍比·杰克2009年

谢谢鲍比,我将其添加到答案中。
Mark A. Nicolosi

33

您是否尝试过IE的onpropertychange事件?我不知道这是否有所作为,但值得一试。当通过JS代码更新值时,IE不会触发change事件,但是onpropertychange可能在这种情况下有效。

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 

“点击”似乎无效,但“属性更改”却有效。谢谢!
James Kingsbery 2010年

我在IE8中尝试了此操作,但无法正常工作。它不在函数内部。
2014年

14

这也应该工作:

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   $("#viewByOrg, #viewByProduct").bind(($.browser.msie ? "click" : "change"), function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });
});

谢谢码头。这非常有帮助。


至少,这比当前接受/投票最多的答案好得多。它“仅”破坏了IE下的键盘可访问性,而不是所有好的浏览器。
鲍比·杰克2009年

...虽然,这不只是Pier的答案的副本吗?
鲍比·杰克2009年

同意,它是Pier的可读性稍差的版本,但是两个选择器都绑定在一个调用中。
Tristan Warner-Smith,2009年

替换clickclick keyup keypress以添加键盘支持。
aloisdg移至codidact.com,2016年

6

在IE中,必须在其他浏览器onchange中使用click事件。您的功能可能会变成

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   var evt = $.browser.msie ? "click" : "change";
   $("#viewByOrg").bind(evt, function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });

   $("#viewByProduct").bind(evt, function () {
                        $(".visibleOnLoad").hide();
                        $(".hiddenOnLoad").show();
                    });     
});

替换clickclick keyup keypress以添加键盘支持。
aloisdg移至codidact.com,2016年

6

添加此插件

jQuery.fn.radioChange = function(newFn){
    this.bind(jQuery.browser.msie? "click" : "change", newFn);
}

然后

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});

4

输入文字有相同的问题。

我变了:

$("#myinput").change(function() { "alert('I changed')" });

$("#myinput").attr("onChange", "alert('I changed')");

一切对我来说都很好!


2

这是一种告诉IE单击元素时触发更改事件的简单方法:

if($.browser.msie) {
    $("#viewByOrg").click(function() {
        $(this).change();
    });
}

您可以将其扩展为更通用的名称,以使用更多表单元素:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}

1

我很确定这是IE的已知问题。为onclick事件添加处理程序应该可以解决问题:

$(document).ready(function(){

    $(".hiddenOnLoad").hide();

    $("#viewByOrg").change(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByOrg").click(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByProduct").change(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     

    $("#viewByProduct").click(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     
});

1

在IE中,强制广播和复选框触发“更改”事件:

if($.browser.msie && $.browser.version < 8)
  $('input[type=radio],[type=checkbox]').live('click', function(){
    $(this).trigger('change');
  });

1

从jQuery 1.6开始,这不再是一个问题..不确定何时修复..尽管感谢上帝



1

单击的技巧可以起作用...但是,如果您想获得广播或复选框的正确状态,则可以使用以下方法:

(function($) {
    $('input[type=checkbox], input[type=radio]').live('click', function() {
       var $this = $(this);
       setTimeout(function() {
          $this.trigger('changeIE'); 
       }, 10) 
    });
})(jQuery);

$(selector).bind($.browser.msie && $.browser.version <= 8 ? 'changeIE' : 'change', function() {
  // do whatever you want
})

0

使用点击而不是更改的imo使ie行为有所不同。我宁愿使用计时器(setTimout)来模拟更改事件的行为。

类似于(警告-记事本代码)的内容:

if ($.browser.msie) {
  var interval = 50;
  var changeHack = 'change-hac';
  var select = $("#viewByOrg");
  select.data(changeHack) = select.val();
  var checkVal=function() {
    var oldVal = select.data(changeHack);
    var newVal = select.val();
    if (oldVal !== newVal) {
      select.data(changeHack, newVal);
      select.trigger('change')
    }
    setTimeout(changeHack, interval);
  }
  setTimeout(changeHack, interval);
}

$("#viewByOrg").change(function() {
  // Do stuff here
});

哇...有点笨拙,不是吗?
orip

0

试试这个,对我有用

$("#viewByOrg")
        .attr('onChange', $.browser.msie ? "$(this).data('onChange').apply(this)" : "")
        .change( function(){if(!$.browser.msie)$(this).data('onChange').apply(this)} )
        .data('onChange',function(){alert('put your codes here')});

0

这可能对某人有帮助:与其以表单的ID开始,不如以选择ID为目标并在更改时提交表单,如下所示:

<form id='filterIt' action='' method='post'>
  <select id='val' name='val'>
    <option value='1'>One</option>
    <option value='2'>Two</option>
    <option value='6'>Six</option>
  </select>
  <input type="submit" value="go" />
</form>

和jQuery:

$('#val').change(function(){
  $('#filterIt').submit();
});

(很明显,如果禁用了javascript,则提交按钮是可选的)



0

避免在jquery的.change()函数之前使用.focus().select()在IE,然后它可以正常工作,可以在我的网站中使用它。

谢谢


0
//global
var prev_value = ""; 

$(document).ready(function () {

 if (jQuery.browser.msie && $.browser.version < 8)
      $('input:not(:submit):not(:button):not(:hidden), select, textarea').bind("focus", function () { 
         prev_value = $(this).val();

       }).bind("blur", function () { 
         if($(this).val() != prev_value)
         has_changes = true;
       });
}

0

请尝试使用每一个,而不是使用change / click,即使在IE和其他浏览器中首次使用也能正常工作

第一次不工作

$("#checkboxid").**change**(function () {

});

即使第一次也可以正常工作

$("#checkboxid").**each**(function () {

});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.