Ошибка jQuery indexOf для сценария междоменной ссылки xdomain.js - PullRequest
0 голосов
/ 03 февраля 2012

Я использую скрипт для обнаружения междоменных ссылок для междоменного отслеживания Google Analytics. Оригинальный скрипт (xdomain.js) был предоставлен великими людьми из Luna Metrics. Вот сценарий с моими изменениями, хет-кончик to educardocereto здесь, в StackOverflow, для предлагаемых изменений, чтобы включить setAllowAnchor в GATC (я прокомментировал строку 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, потому что сценарий, похоже, был протестирован на этой версии.

1 Ответ

1 голос
/ 04 февраля 2012

Здесь вы кешируете как элемент 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();
/* 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();
});

Но вы можете изобретать колесо здесь.Есть несколько лучших сценариев для достижения того же.Я думаю, что вам будет интересно посмотреть ГАЗ .Это оболочка для ga.js, которая расширяет и добавляет кучу вещей, включая crossDomain и downloadTracking.

Спойлер: Я главный разработчик GAS .

https://github.com/CardinalPath/gas

...