ทำให้ jQuery รู้จัก .change () ใน IE


131

ฉันใช้ jQuery เพื่อซ่อนและแสดงองค์ประกอบเมื่อมีการเปลี่ยนแปลง / คลิกกลุ่มปุ่มตัวเลือก ใช้งานได้ดีในเบราว์เซอร์เช่น Firefox แต่ใน IE 6 และ 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 เข้มงวด

<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>

หากใครมีความคิดว่าเหตุใดจึงเกิดขึ้นและจะแก้ไขอย่างไรพวกเขาจะชื่นชมมาก!

คำตอบ:


96

ลองใช้.clickแทน.change.


3
@samjudson ในการทดสอบของฉันสิ่งนี้ไม่ถูกต้องและการคลิกของ jquery จะทริกเกอร์เมื่อฉันเลือกปุ่มตัวเลือกถัดไปโดยใช้ปุ่มลูกศร (vista, ie7)
svandragt

1
@Pacifika: ไม่ใช่สำหรับฉันใน IE7 อย่างน้อยมันก็ได้รับสิทธินั้น "คลิก" เป็นเหตุการณ์ที่แตกต่างจาก "การเปลี่ยนแปลง" โดยสิ้นเชิงและอย่างน้อยก็มีบางกรณี (ถ้าไม่ใช่ทั้งหมด) ที่เป็นสิ่งทดแทนที่ไม่เหมาะสม
Bobby Jack

3
@samjudson: คลิกเหตุการณ์บนปุ่มตัวเลือกและช่องทำเครื่องหมายจะเริ่มทำงานเมื่อเลือกโดยใช้แป้นพิมพ์ ใช้ได้กับทุกเบราว์เซอร์
Philippe Leybaert

4
ฉันยืนอยู่ได้รับการแก้ไข - ดูเหมือนจะเป็นเช่นนั้น แต่มันอาจจะสวนทางกับธรรมชาติ!
Bobby Jack

2
ดูเหมือนจะเป็นคำตอบที่ได้รับความนิยมมากที่สุดสำหรับคำถามนี้ แต่ก็ไม่ถูกต้องทั้งหมด! clickแตกต่างจากตรงchangeที่ตัวจัดการเหตุการณ์จะถูกเรียกเมื่อคลิกตัวเลือกที่เลือกไว้แล้วในขณะที่changeไม่มี คำตอบนี้มีตัวอย่างวิธีใช้ jQuery .dataเพื่อเปรียบเทียบค่าเก่าและใหม่
Laoujin

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

ตอนนี้คุณสามารถใช้เหตุการณ์การเปลี่ยนแปลงได้ตามปกติ

แก้ไข: เพิ่มการโทรเพื่อโฟกัส () เพื่อป้องกันปัญหาการเข้าถึง (ดูความคิดเห็นของ Bobby ด้านล่าง)


2
นั่นเป็นการแฮ็กที่ชั่วร้ายมากเพราะมันป้องกันไม่ให้ผู้ใช้ของคุณนำทางโดยใช้แป้นพิมพ์เนื่องจากโฟกัสจะหายไปหลังจากเลือกปุ่มตัวเลือก
Philippe Leybaert

5
วิธีนี้ยอดเยี่ยม แต่ทำให้เกิดปัญหาการเข้าถึงแป้นพิมพ์ เมื่อเหตุการณ์เบลอ () เริ่มทำงานปุ่มตัวเลือกจะไม่ถูกโฟกัสอีกต่อไปดังนั้นการเลื่อนไปมาระหว่างปุ่มตัวเลือกด้วยแป้นพิมพ์จึงเป็นเรื่องที่น่าอึดอัดมาก วิธีแก้ไขปัจจุบันของฉันคือเพิ่มการเรียกไปที่ "this.focus ();" ทันทีหลังจากคำสั่งเบลอ ()
Bobby Jack

1
ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่แย่ที่สุดเนื่องจากปัญหาการเข้าถึง
Philippe Leybaert

11
แต่ปัญหาการเข้าถึงสามารถแก้ไขได้ด้วยการโทรเพื่อโฟกัส () อย่างน้อยก็ดีพอ ๆ กับการใช้ click () สำหรับทุกสิ่ง
Bobby Jack

ขอบคุณบ๊อบบี้ฉันจะเพิ่มคำตอบให้
Mark A. Nicolosi

33

คุณเคยลองกิจกรรม onpropertychange ของ IE หรือไม่? ฉันไม่รู้ว่ามันสร้างความแตกต่างได้หรือเปล่า แต่ก็น่าลอง IE ไม่ทริกเกอร์เหตุการณ์การเปลี่ยนแปลงเมื่อมีการอัปเดตค่าผ่านรหัส JS แต่บางที onpropertychange จะทำงานในอินสแตนซ์นี้

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

"คลิก" ดูเหมือนจะไม่ทำงาน แต่ "propertychange" ทำได้ ขอบคุณ!
James Kingsbery

ฉันลองสิ่งนี้ใน IE8 แล้วมันไม่ทำงาน มันไม่ได้อยู่ในฟังก์ชัน
อรุณ

14

สิ่งนี้ควรใช้งานได้เช่นกัน:

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

ขอบคุณท่าเรือ สิ่งนี้มีประโยชน์มาก


อย่างน้อยก็เป็นคำตอบที่ดีกว่าคำตอบที่ได้รับการยอมรับ / ได้รับการโหวตสูงสุดในปัจจุบัน 'เท่านั้น' จะแบ่งการเข้าถึงแป้นพิมพ์ภายใต้ IE แทนที่จะเป็นเบราว์เซอร์ที่ดีทั้งหมดด้วย
Bobby Jack

... แม้ว่านี่จะไม่ใช่แค่คำตอบของ Pier?
Bobby Jack

เห็นด้วยเป็นรุ่นที่อ่านได้น้อยกว่าเล็กน้อยของ Pier แต่มีตัวเลือกทั้งสองถูกผูกไว้ในการโทรครั้งเดียว
Tristan Warner-Smith

แทนที่clickด้วยclick keyup keypressเพื่อเพิ่มการรองรับแป้นพิมพ์
aloisdg ย้ายไปที่ codidact.com

6

ใน IE คุณต้องใช้เหตุการณ์การคลิกในเบราว์เซอร์อื่น onchange ฟังก์ชันของคุณอาจกลายเป็น

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

แทนที่clickด้วยclick keyup keypressเพื่อเพิ่มการรองรับแป้นพิมพ์
aloisdg ย้ายไปที่ codidact.com

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)

บางอย่างเช่น (คำเตือน - รหัส notepad):

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 ของแบบฟอร์มให้กำหนดเป้าหมายรหัสที่เลือกและส่งแบบฟอร์มเมื่อมีการเปลี่ยนแปลงดังนี้:

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

(เห็นได้ชัดว่าปุ่มส่งเป็นทางเลือกในกรณีที่จาวาสคริปต์ถูกปิดใช้งาน)



0

หลีกเลี่ยงการใช้. focus ()หรือ . select ()ก่อน. เปลี่ยนฟังก์ชั่น()ของjqueryสำหรับ 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

โปรดลองใช้แต่ละรายการแทนการเปลี่ยนแปลง / คลิกซึ่งใช้งานได้ดีแม้เป็นครั้งแรกใน IE และเบราว์เซอร์อื่น ๆ

ไม่ทำงานในครั้งแรก

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

});

ทำงานได้ดีแม้ในครั้งแรก

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

});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.