0

I have been battling like crazy with a javascript that allows for infinite scrolling in Tumblr. Call me a newbie but this feels like an old nasty dinosaur compared to what i'm used to with jQuery.

My attempts to make this script talk with my jQuery functions or to recognise DOM elements on the page has proved utterly useless. Since this is the only known working infinite scroll script for tumblr out there, i have to live with it.

I now want to add a spinner that appears when it's loading new content, and hide the spinner when it's not. And also, change the preloader to an "end of posts" message once we reached the end.

Below is the entire script, I'd love if someone could show me how to refer to DOM elements and or .classes and #ids in this page http://syndex.me

Edit: Please not on the site you'll see a preloader but this isn't 'smart' it's just a div tied to the end of the page.

var tumblrAutoPager = {
    url: "http://proto.jp/",
    ver: "0.1.7",
    rF: true,
    gP: {},
    pp: null,
    ppId: "",
    LN: location.hostname,
    init: function () {
        if ($("autopagerize_icon") || navigator.userAgent.indexOf('iPhone') != -1) return;
        var tAP = tumblrAutoPager;
        var p = 1;
        var lh = location.href;
        var lhp = lh.lastIndexOf("/page/");
        var lht = lh.lastIndexOf("/tagged/");
        if (lhp != -1) {
            p = parseInt(lh.slice(lhp + 6));
            tAP.LN = lh.slice(7, lhp);
        } else if (lht != -1) {
            tAP.LN = lh.slice(7);
            if (tAP.LN.slice(tAP.LN.length - 1) == "/") tAP.LN = tAP.LN.slice(0, tAP.LN.length - 1);
        } else if ("http://" + tAP.LN + "/" != lh) {
            return;
        };
        var gPFncs = [];
        gPFncs[0] = function (aE) {
            var r = [];
            for (var i = 0, l = aE.length; i < l; i++) {
                if (aE[i].className == "autopagerize_page_element") {
                    r = gCE(aE[i]);
                    break;
                }
            }
            return r;
        };
        gPFncs[1] = function (aE) {
            var r = [];
            for (var i = 0, l = aE.length; i < l; i++) {
                var arr = aE[i].className ? aE[i].className.split(" ") : null;
                if (arr) {
                    for (var j = 0; j < arr.length; j++) {
                        arr[j] == "post" ? r.push(aE[i]) : null;
                    }
                }
            }
            return r;
        };
        gPFncs[2] = function (aE) {
            var r = [];
            var tmpId = tAP.ppId ? [tAP.ppId] : ["posts", "main", "container", "content", "apDiv2", "wrapper", "projects"];
            for (var i = 0, l = aE.length; i < l; i++) {
                for (var j = 0; j < tmpId.length; j++) {
                    if (aE[i].id == tmpId[j]) {
                        r = gCE(aE[i]);
                        tAP.ppId = aE[i].id;
                        break;
                    }
                }
            }
            return r;
        };
        for (var i = 0; i < gPFncs.length; i++) {
            var getElems = gPFncs[i](document.body.getElementsByTagName('*'));
            if (getElems.length) {
                tAP.gP = gPFncs[i];
                tAP.pp = getElems[0].parentNode;
                break;
            }
        }

        function gCE(pElem) {
            var r = [];
            for (var i = 0, l = pElem.childNodes.length; i < l; i++) {
                r.push(pElem.childNodes.item(i))
            }
            return r;
        }
        if (!tAP.pp) {
            return;
        }
        sendRequest.README = {
            license: 'Public Domain',
            url: 'http://jsgt.org/lib/ajax/ref.htm',
            version: 0.516,
            author: 'Toshiro Takahashi'
        };

        function chkAjaBrowser() {
            var A, B = navigator.userAgent;
            this.bw = {
                safari: ((A = B.split('AppleWebKit/')[1]) ? A.split('(')[0].split('.')[0] : 0) >= 124,
                konqueror: ((A = B.split('Konqueror/')[1]) ? A.split(';')[0] : 0) >= 3.3,
                mozes: ((A = B.split('Gecko/')[1]) ? A.split(' ')[0] : 0) >= 20011128,
                opera: ( !! window.opera) && ((typeof XMLHttpRequest) == 'function'),
                msie: ( !! window.ActiveXObject) ? ( !! createHttpRequest()) : false
            };
            return (this.bw.safari || this.bw.konqueror || this.bw.mozes || this.bw.opera || this.bw.msie)
        }

        function createHttpRequest() {
            if (window.XMLHttpRequest) {
                return new XMLHttpRequest()
            } else {
                if (window.ActiveXObject) {
                    try {
                        return new ActiveXObject('Msxml2.XMLHTTP')
                    } catch (B) {
                        try {
                            return new ActiveXObject('Microsoft.XMLHTTP')
                        } catch (A) {
                            return null
                        }
                    }
                } else {
                    return null
                }
            }
        };

        function sendRequest(E, R, C, D, F, G, S, A) {
            var Q = C.toUpperCase() == 'GET',
                H = createHttpRequest();
            if (H == null) {
                return null
            }
            if ((G) ? G : false) {
                D += ((D.indexOf('?') == -1) ? '?' : '&') + 't=' + (new Date()).getTime()
            }
            var P = new chkAjaBrowser(),
                L = P.bw.opera,
                I = P.bw.safari,
                N = P.bw.konqueror,
                M = P.bw.mozes;
            if (typeof E == 'object') {
                var J = E.onload;
                var O = E.onbeforsetheader
            } else {
                var J = E;
                var O = null
            }
            if (L || I || M) {
                H.onload = function () {
                    J(H);
                    H.abort()
                }
            } else {
                H.onreadystatechange = function () {
                    if (H.readyState == 4) {
                        J(H);
                        H.abort()
                    }
                }
            }
            R = K(R, D);
            if (Q) {
                D += ((D.indexOf('?') == -1) ? '?' : (R == '') ? '' : '&') + R
            }
            H.open(C, D, F, S, A);
            if ( !! O) {
                O(H)
            }
            B(H);
            H.send(R);

            function B(T) {
                if (!L || typeof T.setRequestHeader == 'function') {
                    T.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
                }
                return T
            }

            function K(X, V) {
                var Z = [];
                if (typeof X == 'object') {
                    for (var W in X) {
                        Y(W, X[W])
                    }
                } else {
                    if (typeof X == 'string') {
                        if (X == '') {
                            return ''
                        }
                        if (X.charAt(0) == '&') {
                            X = X.substring(1, X.length)
                        }
                        var T = X.split('&');
                        for (var W = 0; W < T.length; W++) {
                            var U = T[W].split('=');
                            Y(U[0], U[1])
                        }
                    }
                }

                function Y(b, a) {
                    Z.push(encodeURIComponent(b) + '=' + encodeURIComponent(a))
                }
                return Z.join('&')
            }
            return H
        }

        function addNextPage(oj) {
            if (oj.status == 404) {
                tAP.remainFlg = false;
                return;
            }
            var d = document.createElement("div");
            d.innerHTML = oj.responseText;
            var posts = tAP.gP(d.getElementsByTagName("*"));
            if (posts.length < 2) {
                tAP.rF = false;
                return;
            }
            d = document.createElement("div");
            d.className = "tumblrAutoPager_page_info";
            tAP.pp.appendChild(d);
            for (var i = 0; i < posts.length; i++) {
                tAP.pp.appendChild(posts[i]);
            }
            var footer = $("footer");
            footer ? footer.parentNode.appendChild(footer) : null;
            tAP.rF = true;
        }
        watch_scroll();

        function watch_scroll() {
            var d = document.compatMode == "BackCompat" ? document.body : document.documentElement;
            var r = d.scrollHeight - d.clientHeight - (d.scrollTop || document.body.scrollTop);
            if (r < d.clientHeight * 2 && tAP.rF) {
                tAP.rF = false;
                p++;
                sendRequest(addNextPage, "", "GET", "http://" + tAP.LN + "/page/" + p, true);
            }
            setTimeout(arguments.callee, 200);
        };

        function $(id) {
            return document.getElementById(id)
        };
    },
    switchAutoPage: function () {
        this.rF = !this.rF;
        var aE = document.getElementsByTagName('*');
        for (var i = 0, l = aE.length; i < l; i++) {
            if (aE[i].className == "tAP_switch") {
                aE[i].firstChild.nodeValue = this.rF ? "AutoPage[OFF]" : "AutoPage[ON]";
            }
        }
    }
};
window.addEventListener ? window.addEventListener('load', tumblrAutoPager.init, false) : window.attachEvent ? window.attachEvent("onload", tumblrAutoPager.init) : window.onload = tumblrAutoPager.init;
RGBK
  • 2,048
  • 5
  • 35
  • 55
  • If you are already using jQuery, why not use a jQuery infinite scroll plugin instead? – DA. Oct 28 '11 at 15:06
  • Good question. It can't be done. It's a tumblr thing (tumblr is amazing but it has a lot to work around unfortunately. So this is the only script on the net right now that allows your tumblr to infinite scroll. – RGBK Oct 28 '11 at 15:11
  • 2
    I hate almost every variable name in there except `tmpId` and `url`. Well, and `i`. – Dave Newton Oct 28 '11 at 15:16
  • Yeah it's impenetrable isn't it? But what i just can't figure out is why i can't just say to this script something like $(".theImage") do something (that is a class in my page). I know the $("x") format is jquery, fine, but what's the equivalent for this kind of javascipt? Is it possible to actually refer to elements so easily in JS? Maybe i'm not understanding something fundamental here? Also why does JS not have a class selector? there is no getElementbyClass. Seems insane to me. Like let's make this as hard as possible! Viva jQuery. – RGBK Oct 28 '11 at 15:19
  • @RGBK You can `getElementById`, [or by class (ew)](http://stackoverflow.com/questions/1933602/how-to-getelementbyclass-instead-of-getelementbyid-with-javascript/1933623#1933623). – Dave Newton Oct 28 '11 at 15:26
  • I tried that, it just doesn't know what i'm taling about. It's as though anything on the page besides the one div id'ed "#autopagerize_page_element" can't be called directly, but through abstract expressions. I'd just liek to know why it's not playing nice. Why is it that i can't just talk directly with id or class names? – RGBK Oct 28 '11 at 15:31
  • Ugh. Tumblr. I admit Tumblr is great from a generic UX standpoint and up-and-running speed, but the source is painful. (Not as painful as SharePoint, mind you, but yea, I empathize...it's not going to be the easiest thing to hack) – DA. Oct 28 '11 at 15:43

1 Answers1

1

You might have better luck extracting just the Tumblr bits from the script and putting them in a JQuery shell you are more familiar with. There are a bunch of stuff in "plain JS", like DOM events AJAX and element selection that are way more simple with a JS framework (and that is not even counting how obfuscated the current script is... blergh!).

Anyway, if I had to minimally modify this code, I'd try adding the spinner just before he calls sendRequest in the watchScroll function and I'd try removing it in the start of the addNextPage function.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • Thanks missingno, i'll give that a shot and get back to you with some console.logs :-) – RGBK Oct 28 '11 at 15:44
  • I've added console logs which trigger at the right times (helped by your advice there, thank you. However, I've tried just about every if statement it get a "complete" status with no luck. Any ideas how to get that? http://syndex.me (check console logs) – RGBK Oct 28 '11 at 16:21
  • What do you mean by "it get a complete status"? If all you want is check if the AJAX call suceeded then there is nothing to do (since the lib is already doing that in the readyState==4 part) – hugomg Oct 28 '11 at 16:24
  • Sorry, to clarify, i'd like to log "End of Page, no further posts to load". Once i have these console.logs firing at the right times, i can then go ahead and figure out how to make that appear on the actual site. Thanks! – RGBK Oct 28 '11 at 16:30
  • I would have assumed it to be within if (oj.status == 404) { which is in the addNextPage function. However thats not being seen. Weird. – RGBK Oct 28 '11 at 16:41