Skip to content

Instantly share code, notes, and snippets.

@pablen
Last active Sep 24, 2015
Embed
What would you like to do?
Carga de contenido adicional asincrónica y condicional en base al ancho del viewport.
(function(window, document, undefined){
"use strict";
var config = {
selector : "[data-asynccontent-url]",
urlAttr : "data-asynccontent-url",
thrAttr : "data-asynccontent-threshold",
loadTxtAttr : "data-asynccontent-loadtxt",
defaultLoadTxt : "Obteniendo contenido..."
},
elements = document.querySelectorAll(config.selector);
for (var i = elements.length -1; i >= 0; i--){
new AsyncContent(elements[i]);
}
function AsyncContent(element, url, threshold, loadTxt)
{
element = (typeof element === "string") ? document.querySelector(element) : element;
url = url || element.getAttribute(config.urlAttr);
threshold = threshold || element.getAttribute(config.thrAttr);
loadTxt = loadTxt || (element.getAttribute(config.loadTxtAttr) || config.defaultLoadTxt);
var mq = window.matchMedia("(min-width: " + threshold + ")");
if (mq.matches) {
getAndReplace();
} else {
mq.addEventListener("change", handler);
element.addEventListener("click", handler);
}
function handler(e) {
e.preventDefault();
getAndReplace();
mq.removeEventListener("change", handler);
element.removeEventListener("click", handler);
}
function getAndReplace() {
element.classList.add("asynccontent-is-loading");
element.textContent = loadTxt;
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
element.outerHTML = request.responseText;
} else {
console.warn("Algo falló...");
}
};
request.onerror = function() {
console.warn("Error al intentar conectarse con " + url);
};
request.send();
}
}
window.AsyncContent = AsyncContent;
})(window, document);
<!--- Tres ejemplos de inicialización: -->
<!-- 1. Inicialización automática a través de atributos HTML -->
<!-- 1a. Con threshold = 360px y texto "loading" por defecto -->
<a href="http://www.example.com"
data-asynccontent-threshold="360px"
data-asynccontent-url="https://labs.educ.ar/1.0/videos/%7B%22app_key%22:%228f0d681747a7490d1d2138fd3aa1bfc39209f64a%22,%22pretty%22:1,%22fields%22:[%22titulo%22,%22descripcion%22],%22filters%22:%7B%22canal%22:%22Portal%20Encuentro%22%7D,%22limit%22:3,%22offset%22:0%7D">
Un contenido default</a>
<!-- 1b. Automática con threshold = 450px y texto "loading" personalizado -->
<a href="http://educ.ar"
data-asynccontent-threshold="450px"
data-asynccontent-url="https://labs.educ.ar/1.0/videos/%7B%22app_key%22:%228f0d681747a7490d1d2138fd3aa1bfc39209f64a%22,%22pretty%22:1,%22fields%22:[%22titulo%22,%22descripcion%22],%22filters%22:%7B%22canal%22:%22Portal%20Encuentro%22%7D,%22limit%22:3,%22offset%22:10%7D"
data-asynccontent-loadtxt="Obteniendo cositas...">
Otro contenido default</a>
<!-- 2. Inicialización manual por JavaScript -->
<a id="trigger" href="#">Otro contenido default más</a>
<script type="text/javascript">
var url = "https://labs.educ.ar/1.0/videos/%7B%22app_key%22:%228f0d681747a7490d1d2138fd3aa1bfc39209f64a%22,%22pretty%22:1,%22fields%22:[%22titulo%22,%22descripcion%22],%22filters%22:%7B%22canal%22:%22Portal%20Encuentro%22%7D,%22limit%22:3,%22offset%22:20%7D",
loader = new AsyncContent("#trigger3", url, "550px", "Cargando grilla...");
</script>
@pablen
Copy link
Author

pablen commented Sep 24, 2015

Implementación mínima de ejemplo para carga condicional de contenido secundario en base al tamaño del viewport (siguiendo las ideas de https://www.filamentgroup.com/lab/ajax-includes-modular-content.html).

Partimos de un link que apunta a una ruta válida que muestre el contenido secundario en otra pantalla. Si no corre JS el link sigue funcionando y todos contentos.

Si JS corre bien la librería inicializa automáticamente los elementos que tengan los atributos data-asynccontent-threshold y data-asynccontent-url. Los links serán reemplazados por el contenido secundario que se obtenga al hacer una petición a la ruta indicada por el atributo data-asynccontent-url ante alguno de los siguientes escenarios:

  • El viewport tiene un ancho mayor al valor del atributo data-asynccontent-threshold ya sea al cargar la pantalla o después de redimensionarlo.
  • Se hace un click sobre el link.

Demo

Nota: en IE <= 9 no hay soporte para window.matchMedia.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment