Skip to content

Instantly share code, notes, and snippets.

@enniosousa
Created November 26, 2017 22:06
Show Gist options
  • Save enniosousa/ff2cccd56b62cac11ab2b87568ea98da to your computer and use it in GitHub Desktop.
Save enniosousa/ff2cccd56b62cac11ab2b87568ea98da to your computer and use it in GitHub Desktop.

Scroll infinito para uCoz

O infinite scroll permite que novas postagens sejam mostradas no final da página a menida que o usuário vem alcançando o fim do conteudo.

Eu fiz este Script pensando em fatores de usabilidade, SEO (seguindo orientações do Google) e rastreamento no Google Analytics.

O que ele faz

  • Ao chegar no fim da página, novas postagens serão carregadas automaticamente.
  • Quando o usuário estiver visualizando a postagem da página 5, por exemplo, o URL irá muda para a /board/?page5 sem carregar a página.
  • Quando o usuário visualiza uma nova paginação carregada via infinite scroll é enviado pageview para o Google Analytics.

Vantagens

  • O usuário não precisa clicar (sendo opcional), trazendo uma boa usuabilidade.
  • É SEO friendly.
  • Envia pageview para o Google Analytics (caso esteja usando), assim, você pode acompanhar melhor as visualizações das páginas.

Desvantagens

  • É necessário usar o PHP do uCoz

Observações

  • Só foi testado nos seguintes módulos: board, dir, load e publ
  • Peço desculpas pelos comentários estarem em português e inglês, depois deixo só em inglês.

Código

Server Side
<?if($PAGE_ID$ == 'main' || $PAGE_ID$ == 'section' || $PAGE_ID$ == 'category')?>
<script>
    var infiniteScroll = {
	page_corrent: <?if(substr($CURRENT_PAGE$,28,-28-7) > $NUM_PAGES$)?>1<?else?><?substr($CURRENT_PAGE$,28,-28-7)?><?endif?>, 
	page_total: $NUM_PAGES$, 
	main_page_url: "<?if($PAGE_ID$ == 'main')?>$MODULE_URL$<?endif?><?if($PAGE_ID$ == 'section')?>$SECTION_URL$<?endif?><?if($PAGE_ID$ == 'category')?>$CAT_URL$<?endif?>",
	cat_id: <?if($PAGE_ID$ == 'section' || $PAGE_ID$ == 'category')?><?substr($URI_ID$,5)?><?else?>0<?endif?>
    };
</script>
<?endif?>
Biblioteca Javascript
infiniteScroll.isLoading = false;
infiniteScroll.spages = function () {
    infiniteScroll.page_corrent++;
    
    //Verificando se a página a ser carregada é maior do que o total de páginas existentes
    if (infiniteScroll.page_corrent > infiniteScroll.page_total) {
        return;
    }
    
    //criando o loader
    try {
        document.getElementById('myGrid').style.cssText = 'position:absolute; z-index:8; top:0;left:0; display:normal; background: url(\'/.s/img/fr/g.gif\'); text-align:center; width:' + document.body.scrollWidth + 'px; height:' + document.body.scrollHeight + 'px;';
    } catch (e) {
    }
    
    
    infiniteScroll.isLoading = true;
    var postSettings = {
        url: '/php/infinite-scroll/infinite-scroll.php',
        data: {
            page: infiniteScroll.page_corrent,
            mainpage: infiniteScroll.main_page_url,
            catid: infiniteScroll.cat_id,
            insert: "after" //before || after
        },
        cache: true
    };
    _uPostForm('', postSettings);
};
infiniteScroll.replaceState = function () {
    $('div[id*="entryID"]').each(function (index) {
        if (infiniteScroll.mostlyVisible(this)) {
            var url = $(this).attr("data-page-url");
            /**
             * send Google Analytics Page View
             * Check if Google Analytics exists
             * Check if current URL is different for new
             */
            if (typeof ga === "function" && window.location.href !== url) {
                ga('send', 'pageview', url);
                //console.log("send page view to GA: " + url);
            }

            /**
             * change url on address bar
             */
            history.replaceState(null, null, url);

            return(false);
        }
    });
};
infiniteScroll.mostlyVisible = function (element) {
    // if ca 25% of element is visible
    var scroll_pos = $(window).scrollTop();
    var window_height = $(window).height();
    var el_top = $(element).offset().top;
    var el_height = $(element).height();
    var el_bottom = el_top + el_height;
    return ((el_bottom - el_height * 0.25 > scroll_pos) &&
            (el_top < (scroll_pos + 0.5 * window_height)));
};
infiniteScroll.init = function () {
    if(typeof infiniteScroll !== 'object')
        return;
    /**
     * Quando a página é carregada pela primeira vez não tem o atributo <code>data-page-url'</code>
     * Por isso a inserção via jQuery
     */
    var mainpage = infiniteScroll.main_page_url;
    if (infiniteScroll.page_corrent !== 1) {
        mainpage += '?page' + infiniteScroll.page_corrent;
    }
    $('div[id*="entryID"]').attr('data-page-url', mainpage);

    /**
     * Quando a barra de rolagem da página funcionar
     */
    $(window).scroll(function (e) {
        //Not always the pos == h statement is verified, expecially on mobile devices, that's why a 300px of margin are assumed.
        if ($(window).scrollTop() + $(window).height() >= $(document).height() - 300) {
            //console.log("bottom of the page reached!");
            if (!infiniteScroll.isLoading) {
                infiniteScroll.spages();
            }
        }
        if (!infiniteScroll.isLoading) {
            infiniteScroll.replaceState();
        }
    });
};

jQuery(document).ready(function () {
    infiniteScroll.init();
});
PHP
<?php

/*
 * @autor_name Ennio Sousa
 * @autor_site http://uid.me/shzlot
 *
 * Copyright (c) 2016 Ennio.
 * All rights reserved. This program and the accompanying materials
 */

$___notjson = 1;
header("Content-type: text/xml");

/**
 * Validating input data
 * 
 * $mainpage is like http://site.ucoz.com.br/[module]/ (it needs to be a valid URL)
 * $page is the page requested (it needs to be integer number)
 * $catid is the category or section ID, if the page is the module main page it is zero
 * $insert is that option [before||after]
 */
$mainpage = filter_input(INPUT_GET, "mainpage", FILTER_VALIDATE_URL); //url 
$page = filter_input(INPUT_GET, "page", FILTER_VALIDATE_INT); //int
$catid = filter_input(INPUT_GET, "catid", FILTER_VALIDATE_INT); //int
$insert = filter_input(INPUT_GET, "insert", FILTER_SANITIZE_STRING); //string
if ($page && $mainpage) {
    $a = getXML();
    if ($a)
        echo $a;
    else
        echo '<?xml version="1.0" encoding="UTF-8"?><ajax></ajax>';
} else {
    echo '<?xml version="1.0" encoding="UTF-8"?><ajax><cmd e="error">Invalid parameters</cmd></ajax>';
}

/**
 * Original URL: http://[site]/[module]/0-[page]-[randon numbers]
 * * E.g. http://brcraft.ucoz.com.br/dir/0-2-33886755
 */
function getXML() {
    global $page, $mainpage, $catid, $insert;
    if($catid === 0){
        $requestUrl = "$mainpage/0-$page-". time();
    }else{
        //http://wmonline.com.br/artigos/design/[secao_id]-[page]-2-0-0-[randon numbers]
        $requestUrl = "$mainpage/$catid-$page-2-0-0-". time();
    }
    
    $xml = file_get_contents($requestUrl);

    /**
     * The uCoz Ajax pagination replace the content page on click.
     * For does not replace content and to append is necessary 
     * Replace <code>innerHTML</code>to:
     * * <code>innerHTML</code> replace the HTML
     * * <code>innerHTML+</code> insert before
     * * <code>+innerHTML</code> insert after
     */
    $innerHTML = $insert == "before" ? "+innerHTML" : "innerHTML+";
    $xml = str_replace('<cmd t="allEntries" p="innerHTML">', '<cmd t="allEntries" p="'.$innerHTML.'">', $xml);
    
    
    
    /**
     * Is necessary informer <code>infiniteScroll.isLoading = false;</code>
     * To infiniteScroll JS library
     */
    $xml = str_replace("document.getElementById('myGrid').style.display='none';", "document.getElementById('myGrid').style.display='none';infiniteScroll.isLoading = false;", $xml);
    /**
     * It is necessary add de attr <code>data-page-url="/[module]/?page[pageid]
     * When entry is visible change page URL by pagination
     * Inspired http://scrollsample.appspot.com/items
     */
    $return = preg_replace("/(id=\"entryID)/i", "data-page-url=\"$mainpage?page$page\" $1", $xml);
    
    
    return $return;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment