IE throwing JavaScript TypeError but not on chrome

6.3k views Asked by At

DESCRIPTION On our Magento Shopping Cart when a user clicks the Add to Basket button on the Product Details page on any of the Internet Explorer browsers they get a popup in the browser with the following error message:

Exception : TypeError: Unable to get property 'tagName of undefined or null reference

At first I though this error was due to an AJAX call but after further investigation in the browser debugger I can see that it is being caused when the JavaScript is trying to modify the DOM nodes/ HTML tags and their attributes.

I set the breakpoints on all sub-tree & attribute modifications on the #mdl_ajax_confirm div, the call stack is:

ajax_cart.js:87
ajax_cart.js:89
ajax_cart.js:91
ajax_cart.js:97
ajax_cart.js:99
ajax_cart.js:104
ajax_cart.js:110
ajax_cart.js:112
ajax_cart.js:113

In IE it breaks on ajax_cart.js:104 and goes to prototype:1617 to handle the exception.

So the offending piece of code seems to be ajax_cart.js:104 which is:

$$('.block-cart').each(function (el){
  el.replace(mini_cart_txt);
  //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});

In Chrome this returns it returns HTML but in IE it returns the same error in the console as the pop up: Unable to get property 'tagName' of undefined or null reference

QUESTION

I checked the IE console and the mini_cart_txt var is there before ajax_cart.js:104 is executed, the issue is I believe coming from el? I'm not sure how to fix it or what exactly is happening with that block of code?

Below is the rest of the code, thanks in advance :)

CODE

ajax_cart.js

var inCart = false;

if (window.location.toString().search('/product_compare/') != -1){
  var win = window.opener;
}
else{
  var win = window;
}

if (window.location.toString().search('/checkout/cart/') != -1){
    inCart = true;
}


function setLocation(url){
    if(!inCart && (/*(url.search('/add') != -1 ) || (url.search('/remove') != -1 ) ||*/ url.search('checkout/cart/add') != -1) ){
        sendcart(url, 'url');
    }else if((url.search('catalog/product_compare') != -1) ){
        sendcompare(url, 'url');
    }
  else{
        window.location.href = url;
    }
}
function sendcompare(url, type){
  //alert('test');
   showLoading();
      url = url.replace("catalog/product_compare/add","bestseller/index/compare");
    url += 'isAjax/1/';
    //jQuery('#ajax_loading'+id).show();
    jQuery.ajax( {
        url : url,
        dataType : 'json',
        success : function(data) {
           // jQuery('#ajax_loading'+id).hide();
            if(data.status == 'ERROR'){
                alert(data.message);
            }
      else if(data.already!='')
      {
         $('mdl-temp-div').innerHTML = data.already;
                var return_message = data.already;
                $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper"><div class="f-block"><ul class="messages"><li class="notice-msg">'+return_message + '</li></ul></div></div>';
        showConfirm();
      }
      else{
          $('mdl-temp-div').innerHTML = data.message;
                var return_message = data.message;
                $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper"><div class="f-block"><ul class="messages"><li class="success-msg">'+return_message + '</li></ul></div></div>';
        showConfirm();
                if(jQuery('.header-compare').length){
                    jQuery('.header-compare').replaceWith(data.sidebar);
          // Clear All

                }else{
                    if(jQuery('.col-right').length){
                        jQuery('.col-right').prepend(data.sidebar);
                    }
                }
            }
        }
    });
}

function sendcart(url, type){
    showLoading();
    if (type == 'form'){
        url = ($('product_addtocart_form').action).replace('checkout', 'mdlajaxcheckout/index/cart');
        //url = ($('product_addtocart_form').action);
        var myAjax = new Ajax.Request(
        url,
        {
            method: 'post',
            postBody: $('product_addtocart_form').serialize(),
            parameters : Form.serialize("product_addtocart_form"),
            onException: function (xhr, e)
            {
                alert('Exception : ' + e);
            },
            onComplete: function (xhr)
            {
                $('mdl-temp-div').innerHTML = xhr.responseText;
                var return_message = $('mdl-temp-div').down('.mdl_ajax_message').innerHTML;

                var middle_text = '<div class="mdl-cart-bts">'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'</div>';

                $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+return_message + middle_text + '</div>';

                var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;

                $$('.top-link-cart').each(function (el){
                    el.innerHTML = link_cart_txt;
                });



                var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;

                $$('.mini-cart').each(function (el){
                    el.replace(mini_cart_txt);
                    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
                });

                $$('.block-cart').each(function (el){
                    el.replace(mini_cart_txt);
                    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
                });


                replaceDelUrls();

                if (ajax_cart_show_popup){
                    showConfirm();
                } else {
                    hideMdlOverlay();
                }

            }

        });



    } else if (type == 'url'){

        url = url.replace('checkout', 'mdlajaxcheckout/index/cart');
        //alert(url);
        var myAjax = new Ajax.Request(
        url,
        {
            method: 'post',
            postBody: '',
            onException: function (xhr, e)
            {
                alert('Exception : ' + e);
            },
            onComplete: function (xhr)
            {
                $('mdl-temp-div').innerHTML = xhr.responseText;
                var return_message = $('mdl-temp-div').down('.mdl_ajax_message').innerHTML;
                var middle_text = '<div class="mdl-cart-bts">'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'</div>';


                var content_ajax = return_message + middle_text;

                $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+content_ajax + '</div>';

                var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;

                $$('.top-link-cart').each(function (el){
                    el.innerHTML = link_cart_txt;
                });




                var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;

                //alert(mini_cart_txt);

                $$('.mini-cart').each(function (el){
                    el.replace(mini_cart_txt);
                    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
                });

                $$('.block-cart').each(function (el){
                    el.replace(mini_cart_txt);
                    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
                });


                replaceDelUrls();
                if (ajax_cart_show_popup){
                    showConfirm();
                } else {
                    hideMdlOverlay();
                }
            }

        });

    }

}

function replaceDelUrls(){
    //if (!inCart){
        $$('a').each(function(el){
            if(el.href.search('checkout/cart/delete') != -1 && el.href.search('javascript:cartdelete') == -1){
                el.href = 'javascript:cartdelete(\'' + el.href +'\')';
            }
        });
    //}
}

function replaceAddUrls(){
    $$('a').each(function(link){
        if(link.href.search('checkout/cart/add') != -1){
            link.href = 'javascript:setLocation(\''+link.href+'\'); void(0);';
        }
    });
}

function cartdelete(url){

    showLoading();
    url = url.replace('checkout', 'mdlajaxcheckout/index/cartdelete');
    var myAjax = new Ajax.Request(
    url,
    {
        method: 'post',
        postBody: '',
        onException: function (xhr, e)
        {
            alert('Exception : ' + e);
        },
        onComplete: function (xhr)
        {
            $('mdl-temp-div').innerHTML = xhr.responseText;
            //$('mdl-temp-div').insert(xhr.responseText);

            var cart_content = $('mdl-temp-div').down('.cart_content').innerHTML;

            //alert(cart_content);

            $$('.top-link-cart').each(function (el){
                el.innerHTML = cart_content;
            });



            var process_reload_cart = false;
            var full_cart_content = $('mdl-temp-div').down('.mdl_full_cart_content').innerHTML;
            $$('.cart').each(function (el){
                el.replace(full_cart_content);
                process_reload_cart = true;
            });

            if (!process_reload_cart){
                $$('.checkout-cart-index .col-main').each(function (el){
                    el.replace(full_cart_content);
                    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
                });
            }




            var cart_side = '';
            if ($('mdl-temp-div').down('.cart_side_ajax')){
                cart_side = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;
            }


            $$('.mini-cart').each(function (el){
                el.replace(cart_side);
                //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
            });
            $$('.block-cart').each(function (el){
                el.replace(cart_side);
                //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
            });



            replaceDelUrls();

            //$('mdl_ajax_progress').hide();
            hideMdlOverlay();
        }

    });


}

function showMdlOverlay(){
    new Effect.Appear($('mdl-overlay'), { duration: 0.5,  to: 0.8 });
}

function hideMdlOverlay(){
    $('mdl-overlay').hide();
    $('mdl_ajax_progress').hide();
    $('mdl_ajax_confirm').hide();
}


function mdlCenterWindow(element) {
     if($(element) != null) {

          // retrieve required dimensions
            var el = $(element);
            var elDims = el.getDimensions();
            var browserName=navigator.appName;
            if(browserName==="Microsoft Internet Explorer") {

                if(document.documentElement.clientWidth==0) {
                    //IE8 Quirks
                    //alert('In Quirks Mode!');
                    var y=(document.viewport.getScrollOffsets().top + (document.body.clientHeight - elDims.height) / 2);
                    var x=(document.viewport.getScrollOffsets().left + (document.body.clientWidth - elDims.width) / 2);
                }
                else {
                    var y=(document.viewport.getScrollOffsets().top + (document.documentElement.clientHeight - elDims.height) / 2);
                    var x=(document.viewport.getScrollOffsets().left + (document.documentElement.clientWidth - elDims.width) / 2);
                }
            }
            else {
                // calculate the center of the page using the browser andelement dimensions
                var y = Math.round(document.viewport.getScrollOffsets().top + ((window.innerHeight - $(element).getHeight()))/2);
                var x = Math.round(document.viewport.getScrollOffsets().left + ((window.innerWidth - $(element).getWidth()))/2);
            }
            // set the style of the element so it is centered
            var styles = {
                position: 'absolute',
                top: y + 'px',
                left : x + 'px'
            };
            el.setStyle(styles);




     }
}



function showLoading(){
    showMdlOverlay();
    var progress_box = $('mdl_ajax_progress');
    progress_box.show();
    progress_box.style.width = loadingW + 'px';
    progress_box.style.height = loadingH + 'px';


    $('mdl_ajax_progress').innerHTML = $('mdl-loading-data').innerHTML;
    progress_box.style.position = 'absolute';

    mdlCenterWindow(progress_box);
}


function showConfirm(){
    showMdlOverlay();
    $('mdl_ajax_progress').hide();
    var confirm_box = $('mdl_ajax_confirm');
    confirm_box.show();
    confirm_box.style.width = confirmW + 'px';
    confirm_box.style.height = confirmH + 'px';
    //mdl_ajax_confirm_wrapper
    if ($('mdl_ajax_confirm_wrapper') && $('mdl-upsell-product-table')){
        //alert($('mdl_ajax_confirm_wrapper').getHeight());
        confirm_box.style.height = $('mdl_ajax_confirm_wrapper').getHeight() + 'px';
        decorateTable('mdl-upsell-product-table');
    }

    $('mdl_ajax_confirm_wrapper').replace('<div id="mdl_ajax_confirm_wrapper">'+$('mdl_ajax_confirm_wrapper').innerHTML);

    confirm_box.style.position = 'absolute';
    mdlCenterWindow(confirm_box);
}

document.observe("dom:loaded", function() {
    replaceDelUrls();
    replaceAddUrls();
    Event.observe($('mdl-overlay'), 'click', hideMdlOverlay);

    var cartInt = setInterval(function(){
        if (typeof productAddToCartForm  != 'undefined'){
            if ($('mdl-overlay')){
                Event.observe($('mdl-overlay'), 'click', hideMdlOverlay);
            }
            productAddToCartForm.submit = function(url){
                if(this.validator && this.validator.validate()){
                    sendcart('', 'form');
                    clearInterval(cartInt);
                }

                return false;
            }
        } else {
            clearInterval(cartInt);
        }
    },500);
});

When I go through each line of code in the call stack before ajax_cart.js:104 both browsers react the same.

87: $('mdl_ajax_confirm').innerHTML = '<div id="mdl_ajax_confirm_wrapper">'+return_message + middle_text + '</div>';

RETURNS HTML ON ALL BROWSERS

89: var link_cart_txt = $('mdl-temp-div').down('.cart_content').innerHTML;

UNDEFINED ON ALL

91:$$('.top-link-cart').each(function (el){el.innerHTML = link_cart_txt; });

RETURNS [object Array][] ON ALL

97: var mini_cart_txt = $('mdl-temp-div').down('.cart_side_ajax').innerHTML;

UNDEFINED ON ALL

99: $$('.mini-cart').each(function (el){ el.replace(mini_cart_txt); //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });});

RETURNS [object Array][] ON ALL

104: $$('.block-cart').each(function (el){ el.replace(mini_cart_txt); //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 }); });

Unable to get property 'tagName' of undefined or null reference on IE RETURNS HTML ON ALL CHROME

3

There are 3 answers

0
Holly On BEST ANSWER

Ok, so after quite a bit of trial and error I found out what the issue was and was able to solve it.

The code was breaking an line 104 of ajax_cart.js which had this block of code:

$$('.block-cart').each(function (el){
  el.replace(mini_cart_txt);
  //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});

This piece of prototype.js was searching the DOM for the .block-cart div to replace it with the HTML set in it's mini_cart_txt variable. It uses the Prototype $$() Method method to search the DOM and return all elements with the .block-cart class, it then iterates over each of them and replaces their content with the mini_cart_txt variable.

The issue was that our theme's HTML was modified and now included two div's with the .block-cart div.

<div class="f-right block-cart span5">
    <div class="f-left block-cart header_cart margin-left20">[OMITTED CODE FOR BREVITY]</div>
    <div class="f-right checkout-button">[OMITTED CODE FOR BREVITY]</div>    
</div>

Also the HTML in mini_cart_txt variable naturally also had two .block_cart classes, whereas in the original theme there was only one div with a class of .block-cart.

<div class="f-right block-cart span5">
    <div class="f-left block-cart header_cart margin-left20">[CODE WITH SUB_TREE CHANGES OMMITED]</div>
    <div class="f-right checkout-button"></div>
</div>

<script type="text/javascript">[OMITTED CODE FOR BREVITY]</script>

This was what was causing the exception in IE but not in Chrome. I'm not certain why Chrome skipped past this exception. Perhaps Chrome replaced the first .block-cart div and then did not continue to replace the second .block-cart div which was a child of the first one, whereas IE was running into a kind of loop which caused an exception.

Anyway I was able to fix the issue by removing the block-cart class name from the the child div of the first block-cart div.

<div class="f-right block-cart span5">
    <div class="f-left header_cart margin-left20">[OMITTED CODE FOR BREVITY]</div>
    <div class="f-right checkout-button">[OMITTED CODE FOR BREVITY]</div>    
</div>
4
Emipro Technologies Pvt. Ltd. On

Please check header type will work

header('X-UA-Compatible: IE=edge,chrome=1');
1
Geek Num 88 On

OK here is what your code is doing and why you might be getting an error and how to prevent.

firstly the block of code that is throwing the error

//$$ is the Prototype CSS selector, it returns an array of DOM elements that match the 
//CSS selector
//.each() loops through those DOM elements, el is each DOM element
$$('.block-cart').each(function (el){
  //el.replace attempts to replace the original element with the HTML of mini_cart_text
  el.replace(mini_cart_txt);
  //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});

If mini_cart_txt does not exist or possibly is invalid HTML the browser might have a problem replacing the elements matching with class block-cart with mini_cart_txt. Based on the results of line 97 above it looks like its undefined so that might be the issue.

Try to wrap the replacement loop in an if statement

if(mini_cart_txt != undefined)
{
    $$('.block-cart').each(function (el){
        el.replace(mini_cart_txt);
        //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
    });
}

This might solve the error but disable a part of the code, so another troubleshooting option is

$$('.block-cart').each(function (el){
    //change the replace method with
    //el.replace(mini_cart_txt);
    //the update method which replaces the content of the element, instead of replacing the element
    el.update(mini_cart_txt);
    //new Effect.Opacity(el, { from: 0, to: 1, duration: 1.5 });
});

this might reveal more about the problem and might lead you to a solution