IE抛出JavaScript TypeError但不在chrome上

描述在我们的Magento购物车上,当用户在任何Internet Explorer浏览器的“产品详细信息”页面上单击“ 添加到购物篮”按钮时,他们会在浏览器中弹出一个弹出窗口,并显示以下错误消息:

exception:TypeError:无法获取未定义或空引用的属性’tagName

起初我虽然这个错误是由于AJAX调用引起的,但是在浏览器调试器中进一步调查之后我可以看到它是在JavaScript试图修改DOM节点/ HTML标签及其属性时引起的。

我在#mdl_ajax_confirm div上的所有子树和属性修改上设置断点,调用堆栈是:

 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 

在IE中它打破ajax_cart.js:104并转到prototype:1617来处理exception。

所以有问题的代码似乎是ajax_cart.js:104 ,它是:

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

在Chrome中它返回它返回HTML但在IE中它在控制台中返回与弹出窗口相同的错误: 无法获取未定义或空引用的属性’tagName’

我检查了IE控制台和mini_cart_txt var是否在ajax_cart.js:104执行之前,问题是我相信来自el ? 我不确定如何修复它或者该代码块究竟发生了什么?

下面是代码的其余部分,在此先感谢:)

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 = '
  • '+return_message + '
'; showConfirm(); } else{ $('mdl-temp-div').innerHTML = data.message; var return_message = data.message; $('mdl_ajax_confirm').innerHTML = '
  • '+return_message + '
'; 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 = '
'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'
'; $('mdl_ajax_confirm').innerHTML = '
'+return_message + middle_text + '
'; 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 = '
'+$('mdl-temp-div').down('.back-ajax-add').innerHTML+'
'; var content_ajax = return_message + middle_text; $('mdl_ajax_confirm').innerHTML = '
'+content_ajax + '
'; 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('
'+$('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); });

当我在ajax_cart.js:104之前浏览调用堆栈中的每行代码时,两个浏览器都会做出同样的反应。

 87: $('mdl_ajax_confirm').innerHTML = '
'+return_message + middle_text + '
';

在所有浏览器上返回HTML

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

全部未定

 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; 

全部未定

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

无法在IE RETURNS HTML ON ALL CHROME上获取未定义或空引用的属性’tagName’

好吧,经过相当多的试验和错误后,我发现问题是什么,并且能够解决它。

该代码打破了ajax_cart.js的第104行,其中包含以下代码块:

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

这段prototype.js正在DOM中搜索.block-cart div,用它的mini_cart_txt变量中的HTML集替换它。 它使用Prototype $$()方法搜索DOM并使用.block-car t类返回所有元素,然后迭代它们中的每一个并用mini_cart_txt变量替换它们的内容。

问题是我们的主题HTML已被修改,现在包含两个带有.block-cart div的div。

 
[OMITTED CODE FOR BREVITY]
[OMITTED CODE FOR BREVITY]

此外, mini_cart_txt变量中的HTML自然也有两个.block_cart类,而在原始主题中只有一个div具有.block-cart类。

 
[CODE WITH SUB_TREE CHANGES OMMITED]

这是导致IE中的exception而不是Chrome中的exception的原因。 我不确定为什么Chrome会跳过这个例外。 也许Chrome取代了第一个.block-cart div,然后没有继续替换第二个.block-cart div,这是第一个的孩子,而IE遇到了一种导致exception的循环。

无论如何,我能够通过从第一个block-cart div的子div中删除block-cart类名来解决问题。

 
[OMITTED CODE FOR BREVITY]
[OMITTED CODE FOR BREVITY]

好的,这是您的代码正在做什么以及为什么您可能会收到错误以及如何防止。

首先是抛出错误的代码块

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

如果mini_cart_txt不存在或者可能是无效的HTML,浏览器可能会在使用mini_cart_txt替换与class block-cart匹配的元素时mini_cart_txt 。 基于上面第97行的结果,它看起来像undefined因此可能是问题。

尝试将替换循环包装在if语句中

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

这可能会解决错误但禁用部分代码,因此另一个故障排除选项是

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

这可能会揭示更多有关问题的信息,并可能引导您找到解决方案

请检查标题类型是否有效

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