针对xdomain.js跨域链接脚本的jQuery indexOf错误 [英] jQuery indexOf error for xdomain.js cross-domain link script

查看:161
本文介绍了针对xdomain.js跨域链接脚本的jQuery indexOf错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用脚本为谷歌分析跨域跟踪检测跨域链接。原始脚本(xdomain.js)由Luna Metrics的优秀人员提供。这里是我的修改脚本,在StackOverflow的教程中使用了教程,以获得在GATC中启用setAllowAnchor的建议更改(我已经在第40行中将控制台错误首先指向):

  var jQueryXD = jQuery.noConflict(); 
/ *我添加了var,因为页面加载了2个版本
的jquery - 不是问题的根源* /

函数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 ();
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,函数(j){
尝试
{
if((jQueryXD(link).attr('href')。indexOf(this)!= - 1)&&(window。 location.href.indexOf(本)== -1)){
valid = true;

if(valid)
{
jQueryXD(link).bind('click',function(l){
if(typeof(_gat)==对象){
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).a ttr('href'),true); // mod
window.open(fullUrl);
}
}
});



$ b catch(e)
{
//坏标签
}
});

var rootDomain = document.domain.split(。)[document.domain.split(。)。length - 2] +。 + document.domain.split(。)[document.domain.split(。)。length - 1]; ((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);
});
}
});


$ b jQueryXD(document).ready(function(){
listenToClicks();
});

Chrome javascript控制台的输出:

  Uncaught TypeError:
无法调用未定义的方法'indexOf'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
(匿名函数)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
(匿名函数)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属性。

  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(); 
/ *我加了var,因为页面加载了2个版本
的jquery - 不是问题的根源* /

函数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){
//此元素没有href
返回true;
}

var valid = false;
jQueryXD.each(fileTypes,function(i){
if(href.indexOf(this)!= -1){//这是第40行
valid = false;
链接。 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(这个)== -1)){
valid = true;
$ b $ if if(valid){
link.bind('click',function(l){
if(typeof(_gat)==object){
();
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]; ((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);
});
}
});


$ b jQueryXD(document).ready(function(){
listenToClicks();
});

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


$ b 剧透:我是 GAS

https://github.com/CardinalPath/gas


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.

解决方案

Here you cache both the jQuerified element and the href attr.

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

Than why do you later do this:

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

You could either call link.attr('href').indexOf(this) since link is already a jQuery object or you could use directly the href you cached and do this href.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.

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

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

这篇关于针对xdomain.js跨域链接脚本的jQuery indexOf错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆