stopPropagation() not working in IE

2020-07-24 16:11发布

问题:

Having some issues in IE. Things are fin in Chrom/Opera etc. But in IE I go to click and toggleClass but nothing happens. I thought implementing cancel.bubble would help me but that is not the case.

Following is the HTML:

<div class="title">
  <h2>Catamarans</h2>
  <div class="dateSelect">
    <div class="prev">
      <p>Prev</p>
      <a href="#" onClick="dateChange('formattedDate')">< month</a> </div>
    <div class="next">
      <p>Next</p>
      <a href="#" onClick="dateChange('formattedDate')">month ></a> 
    </div>
  </div>

and in the JQuery

function dateChange(dateInput){
    //creating new instance of the date based on the date passed into the function  
    var nextDay = new Date(dateInput); 


//the date will change according to the date passed in from 1 day to 1 month
nextDay.setDate(nextDay.getDate()+1);

//The following will go into another function which formats the date in such a way that vbscript can handle it.
nextDay = dateFormat(nextDay);

//updating the values for the a tag in the onclick attribute. and appending to the strVar variable
var strVar="";
strVar += "             <div class=\"prev\">";
strVar += "                    <p>Prev<\/p>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+prevMonth+"')\">< month<\/a>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+prevWeek+"')\">< week<\/a>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+prevDay+"')\">< day<\/a>";
strVar += "                <\/div>";
strVar += "                ";
strVar += "                <div class=\"next\">";
strVar += "                 <p>Next<\/p>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+nextMonth+"')\">month ><\/a>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+nextWeek+"')\">week ><\/a>";
strVar += "                    <a href=\"javascript:void(0)\" onClick=\"dateChange('"+nextDay+"')\">day ><\/a>";
strVar += "                <\/div>";


//For each .title it finds, it will look for its child .dateselect and remove .dateselect child. It will then append new data to .dateselect with the updated values
$(".title").each(function(index, element) {
    $(this).find('.dateSelect').children().remove();
    $(this).find('.dateSelect').append(strVar);

    var boatName = $(this).next().attr('id');
      if(!$(this).next().hasClass('hide')){
          if(boatName == "SailingCatamaran"){
              $(this).next().load("availability.asp?boatType=SailingCatamaran&date="+dateInput+"");
              //alert(dateInput);
          }
          else if(boatName == "PowerCatamaran"){
              $(this).next().load("availability.asp?boatType=PowerCatamaran&date="+dateInput+"");
          }
          else{
              $(this).next().load("availability.asp?boatType=nothing&date="+dateInput+"");
          }
      }
});
//Stops propagation so when day,week or month are clicked, the table won't disappear 
event.stopPropagation();

}

$(document).ready(function() {

/*$("table").first().load("availability.asp?boatType=PowerCatamaran&date="+current+"", function(response, status, xhr){
    if (status == "error") {
        var msg = "Sorry but there was an error: ";
        $("table").html(msg + xhr.status + " " + xhr.statusText);
    }
});*/

$(".title").click(function(event){


  $(this).next().toggleClass("hide");
  var boatName = $(this).next().attr('id');
  if(!$(this).next().hasClass('hide')){
      if(boatName == "SailingCatamaran"){

          $(this).next().load("availability.asp?boatType=SailingCatamaran&date=");
      }
      else if(boatName == "PowerCatamaran"){

          $(this).next().load("availability.asp?boatType=PowerCatamaran&date=");
      }
      else{

          $(this).next().load("availability.asp?boatType=SailingMonohull&date=");
      }
  }
  $(this).children().last().toggleClass("hide");
  $(this).find('.dateSelect').toggleClass("hide");
  //alert("title being clicked");
});

event.stopPropagation();
}); 

I have stripped out unneccessary/duplicate code so it's a little easier to read. To explain my code in words, I have a div with a class of title, you click it to show/hide its sibling table. when table is shown you will see some A tags and when clicked it will call dateChange() load up the appropriate infomation. the clicking to show hide the table and clicking the A tag doesn't work in IE. I suspect other browsers too. Any ideas? I'm not sure if dateChange() needs an event or something? Still new to this haha! Cheers in advance!

回答1:

It seems like your issue is caused by a difference in the handling of the event object in IE. In IE9 and before, the event object is not a local variable in the event handler's context, but instead a global variable.

Instead of directly calling event.stopPropagation(), try to do this first:

event = event || window.event;
event.stopPropagation();

IE9 apparently populates the window.event object instead of the local variable.


A much better way would be to use jQuery to bind events to buttons, and never to use the onclick attribute in HTML. As pointed out in the comments, jQuery will normalize the event object so that it can be accessed from a common interface. An example of this would be:

HTML:

<a href="#" id="prevMonthBtn">&lt; month</a>

Javascript with jQuery:

$("#prevMonthBtn").click(dateChange);

You can find an alternative way to pass the arguments formattedDate in.



回答2:

What's happening here is that event is not within the scope of dateChange. This works in some browsers because they make it available to the function that is calling dateChange but IE does not do that.

The root of the problem is that you're not appending your links "correctly". It'd be best to not generate html like you're doing with your setVar there, and generate DOM elements with jQuery instead, which would look something like this:

var $prev_container = $( '<div>' )
  .addClass( 'prev' )
  .appendTo( $(this).find('.dateSelect') );

var $prev_month_link = $( '<a>' )
  .html( "month" )
  .click(function(event){
    dateChange( prevMonth ) // I'm not sure where prevMonth comes from, but I would pass it in to dateChange explicitly
    event.stopPropagation();
  })
  .appendTo( $prev_container )

  // and so on for the other links

The reason for this is that you have full control of the scope of your event handling functions while at the same time decoupling your markup from your javascript.

I think in most cases where you find yourself using onClick and writing markup from js you have to stop and think about it because there is almost always a way to do it by interacting with the DOM directly.

I hope that helps!



回答3:

//event.stopPropagation(); --> Comment this line

//Add below line

(event.stopPropagation) ? event.stopPropagation() : event.cancelBubble = true;