xdomain.js 跨域链接脚本的 jQuery indexOf 错误
我正在使用脚本来检测跨域链接以进行谷歌分析跨域跟踪。原始脚本 (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 是因为该脚本似乎已经在该版本上进行了大部分测试。
I'm using a script to detect cross-domain links for google analytics cross-domain tracking. The original script (xdomain.js) was provided by the great folks at Luna Metrics. Here is the script with my modifications, hat-tip to educardocereto here on StackOverflow for the suggested changes to enable setAllowAnchor in the GATC (I've commented line 40 where the console error first points to):
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();
});
The output from the Chrome javascript console:
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
So, atleast it seems to be not mixing up the two jquery instances. I've also tried it with jquery 1.7.1. I'm using 1.2.6 because the script seems to have been moste tested on that version.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这里,您缓存了 jQuerified 元素和 href 属性。
那么为什么你以后要这样做:
你可以调用
link.attr('href').indexOf(this)
因为link
已经是一个 jQuery 对象,或者你可以使用直接使用您缓存的 href 并执行此href.indexOf(this)
。不过,我认为当链接没有 href 属性时,您看到的错误就会发生。因此,在继续您的逻辑之前,您最好检查 href 是否未定义。
我在 jQuery 1.2.6 和 1.7 上测试了它。看起来运行良好。
这是完成的脚本。
但你可能会在这里重新发明轮子。有一些更好的脚本可以实现同样的目的。我想您可能有兴趣研究 GAS。它是 ga.js 的包装器,扩展并添加了一些内容,包括 crossDomain 和 downloadTracking。
剧透:我是 GAS 的主要开发人员。
https://github.com/CardinalPath/gas
Here you cache both the jQuerified element and the href attr.
Than why do you later do this:
You could either call
link.attr('href').indexOf(this)
sincelink
is already a jQuery object or you could use directly the href you cached and do thishref.indexOf(this)
.Still I think the error you see happens when a link doesn't have an href attribute. So you better check if the href is not undefined before continuing your logic.
I tested it on both jQuery 1.2.6 and 1.7. It seems to be working fine.
Here's the finished script.
But you might be reinventing the wheel here. There are some better scripts out there to achieve the same thing. I think you might be interested in looking into GAS. It's a wrapper around ga.js that extends and add a bunch of stuff including crossDomain and downloadTracking.
Spoiler: I'm the main developer of GAS.
https://github.com/CardinalPath/gas