jdo indexOf xdomain.js跨域链接脚本的错误

我正在使用脚本来检测谷歌分析跨域跟踪的跨域链接。 原始脚本(xdomain.js)由Luna Metrics的优秀人员提供。 以下是我修改过的脚本,在StackOverflow上提供了关于educardocereto的脚本,以获取在GATC中启用setAllowAnchor的建议更改(我已经注释了控制台错误首先指向的第40行):

var jQueryXD = jQuery.noConflict(); /* I added var because page loads 2 versions of jquery - not the source of the problem.*/ function listenToClicks() { var domains=["domain1.com", "domain2.com"]; var fileTypes=[".pdf"]; jQueryXD('a').each(function(index) { var link = jQueryXD(this); var href = link.attr('href'); jQueryXD.each(fileTypes, function(i) { if(jQueryXD(link).attr('href').indexOf(this)!=-1){ //this is line 40 valid = false; jQueryXD(link).bind('click', function(c) { c.preventDefault(); _gat._getTrackerByName()._trackEvent('Download', 'Click - ' + jQueryXD(link).attr('href')); setTimeout('document.location = "' + jQueryXD(link).attr('href') + '"', 100); }); } }); var valid = false; jQueryXD.each(domains, function(j) { try { if((jQueryXD(link).attr('href').indexOf(this)!=-1)&&(window.location.href.indexOf(this)==-1)){ valid = true; if (valid) { jQueryXD(link).bind('click', function(l) { if(typeof(_gat)=="object"){ l.preventDefault(); if (jQueryXD(link).attr('target') != "_blank") { // _gaq.push(['_link',jQueryXD(link).attr('href')]); _gaq.push(['_link',jQueryXD(link).attr('href'), true]); // mod } else { var tracker = _gat._getTrackerByName(); //var fullUrl = tracker._getLinkerUrl(jQueryXD(link).attr('href')); var fullUrl = tracker._getLinkerUrl(jQueryXD(link).attr('href'), true); //mod window.open(fullUrl); } } }); } } } catch(e) { //Bad A tag } }); var rootDomain = document.domain.split(".")[document.domain.split(".").length - 2] + "." + document.domain.split(".")[document.domain.split(".").length - 1]; if ( (href.match(/^http/)) && (href.indexOf(rootDomain) == -1) && !valid) { jQueryXD(link).bind('click', function(d) { d.preventDefault(); _gat._getTrackerByName()._trackEvent('Outbound Link', href); setTimeout('document.location = "' + href + '"', 100); }); } }); } jQueryXD(document).ready(function() { listenToClicks(); }); 

Chrome javascript控制台的输出:

  Uncaught TypeError: Cannot call method 'indexOf' of undefined xdomain-nfi-nfs-anchormod-noconflict.js:40 jQueryXD.each.valid xdomain-nfi-nfs-anchormod-noconflict.js:40 jQuery.extend.each jquery-1.2.6.min.js:21 (anonymous function) xdomain-nfi-nfs-anchormod-noconflict.js:39 jQuery.extend.each jquery-1.2.6.min.js:21 jQuery.fn.jQuery.each jquery-1.2.6.min.js:12 listenToClicks xdomain-nfi-nfs-anchormod-noconflict.js:35 (anonymous function) xdomain-nfi-nfs-anchormod-noconflict.js:100 jQuery.fn.extend.ready jquery-1.2.6.min.js:27 jQuery.extend.ready.jQuery.readyList jquery-1.2.6.min.js:27 jQuery.extend.each jquery-1.2.6.min.js:21 jQuery.extend.ready jquery-1.2.6.min.js:27 

所以,至少它似乎没有混合两个jquery实例。 我也用jquery 1.7.1尝试过它。 我正在使用1.2.6,因为该脚本似乎已经在该版本上进行了测试。

在这里缓存jQuerified元素和href attr。

 var link = jQueryXD(this); var href = link.attr('href'); 

为什么你以后这样做:

 jQueryXD(link).attr('href').indexOf(this) 

您可以调用link.attr('href').indexOf(this)因为link已经是一个jQuery对象,或者您可以直接使用您缓存的href并执行此href.indexOf(this)

我仍然认为,当链接没有href属性时,您会看到错误。 因此,在继续逻辑之前,最好先检查href是否未定义。

我在jQuery 1.2.6和1.7上测试过它。 它似乎工作正常。

这是完成的脚本。

 var jQueryXD = jQuery.noConflict(); /* I added var because page loads 2 versions of jquery - not the source of the problem.*/ function listenToClicks() { var domains = ["domain1.com", "domain2.com"]; var fileTypes = [".pdf"]; jQueryXD('a').each(function(index) { var link = jQueryXD(this); var href = link.attr('href'); if(!href){ // This element doesnt have a href return true; } var valid = false; jQueryXD.each(fileTypes, function(i) { if (href.indexOf(this) != -1) { //this is line 40 valid = false; link.bind('click', function(c) { c.preventDefault(); _gat._getTrackerByName()._trackEvent('Download', 'Click - ' + link.attr('href')); setTimeout('document.location = "' + href + '"', 100); }); } }); jQueryXD.each(domains, function(j) { try { if ((href.indexOf(this) != -1) && (window.location.href.indexOf(this) == -1)) { valid = true; if (valid) { link.bind('click', function(l) { if (typeof(_gat) == "object") { l.preventDefault(); if (link.attr('target') != "_blank") { // _gaq.push(['_link',jQueryXD(link).attr('href')]); _gaq.push(['_link', href, true]); // mod } else { var tracker = _gat._getTrackerByName(); //var fullUrl = tracker._getLinkerUrl(href); var fullUrl = tracker._getLinkerUrl(href, true); //mod window.open(fullUrl); } } }); } } } catch (e) { //Bad A tag } }); var rootDomain = document.domain.split(".")[document.domain.split(".").length - 2] + "." + document.domain.split(".")[document.domain.split(".").length - 1]; if ((href.match(/^http/)) && (href.indexOf(rootDomain) == -1) && !valid) { jQueryXD(link).bind('click', function(d) { d.preventDefault(); _gat._getTrackerByName()._trackEvent('Outbound Link', href); setTimeout('document.location = "' + href + '"', 100); }); } }); } jQueryXD(document).ready(function() { listenToClicks(); }); 

但你可能会在这里重新发明轮子。 有一些更好的脚本可以实现同样的目的。 我想你可能有兴趣研究GAS 。 它是ga.js的包装,它扩展并添加了一堆东西,包括crossDomain和downloadTracking。

Spoiler:我是GAS的主要开发者。

https://github.com/CardinalPath/gas