2008-12-09 8 views
11

Al utilizar Google Reader y explorar las entradas de RSS en la vista "Ampliada", las entradas se marcarán automáticamente como "leídas" una vez que un determinado porcentaje de div esté visible en la pantalla (es difícil decir qué porcentaje debe ser visible en el caso de Google Reader). Por lo tanto, a medida que me desplazo línea por línea, el código de JavaScript puede determinar que a) la entrada se representa en la ventana visible yb) se ve una cierta cantidad y cuando se cumplen esas condiciones, se alterna el estado para leer .¿Detecta los divs tal como se muestran en la ventana para implementar Auto-mark-as-read similar a Google Reader?

¿Alguien tiene alguna idea de cómo se implementa esta característica? Específicamente, ¿alguien aquí sabe cómo saber si un div se desplazó a la vista y cuánto de div es visible?

Como un lado, estoy usando jQuery, así que si alguien tiene algún ejemplo específico de jQuery, sería muy apreciado.

Respuesta

4

El verdadero truco es hacer un seguimiento de dónde está la barra de desplazamiento en el elemento que contiene sus elementos. Aquí hay un código que una vez disfruté para hacerlo: http://pastebin.com/f4a329cd9

Puede ver que a medida que se desplaza cambia el enfoque. Solo necesita agregar más código de controlador a la función que maneja cada cambio de enfoque. Funciona desplazarse en ambas direcciones, y también al hacer clic derecho en la barra de desplazamiento, que el simple seguimiento del mouse no le dará (aunque en este caso dado que los elementos de ejemplo son todos del mismo tamaño, con el mismo texto, es difícil decir que de hecho se ha desplazado). El otro problema es qué hacer cuando el contenedor toca fondo. La solución que tengo ahora solo funciona en FF. Si quieres que se vea bien en IE, tendrás que usar un elemento ficticio que se mezcle con el fondo, como el que he comentado en el código.

0

En mi experiencia, Reader solo ha marcado algo como leído si lo he pasado por encima o he hecho clic en él. Asumir que a medida que desplazas el mouse está sobre el div (yo tiendo a colocar el mouse en el borde derecho de la pantalla cuando me desplazo) eso podría explicar la apariencia de que solo se marca cuando se muestra un cierto%.

Sin embargo, podría estar (y probablemente estoy) equivocado. Solo sé que el simple hecho de desplazarse por mis elementos en el lector no los marca. Tengo que asegurarme de que el mouse pase sobre ellos mientras se desplaza para hacerlo.

+0

Esa fue una hipótesis interesante, así que esta vez tuve mucho cuidado de evitar cruzar a cualquier contenido. Pasé del botón de desplazamiento hacia abajo y luego a la parte exterior de la ventana y dejé caer al área que me permite cambiar entre vistas ampliadas/de lista y las entradas se marcaron como leídas. – smoody

0

El dom y Javascript le permiten calcular un desplazamiento del elemento desde su elemento primario. Para calcular el desplazamiento desde la ventana, necesita usar la recursión y escalar hacia la ventana superior, y también compararla con el tamaño de la ventana. Se vuelve más complicado debido a problemas e iframes entre navegadores.

Según mi mejor conocimiento, el prototipo ofrece un método simple viewportOffset que hace la mayor parte del trabajo por usted. También puede consultar la fuente de getOffsetParent y scrollTo. No sé sobre jquery, pero espero que ofrezca métodos similares.

Supongo que el script en google reader simplemente se ejecuta en un tiempo de espera, probablemente unas pocas veces por segundo, o tal vez en respuesta a un evento de desplazamiento. En ambos casos, estoy seguro de que es adaptativo (los cambios de tiempo de espera se basan en la velocidad con la que el usuario se desplaza, etc.) y que es lo suficientemente inteligente como para no ser un cerdo de recursos (es decir, no solo verifica todos los divs en el documento)

0

Con el fin de calcular si un elemento es visible, puede crear una función de este tipo (de crédito es debido aquí https://stackoverflow.com/a/22480938/825240):

function isScrolledIntoView(element) { 
    var elementTop = element.getBoundingRect().top; 
    var elementBottom = element.getBoundingRect().bottom; 

    var isVisible = (elementTop <= window.innerHeight) && (elementBottom >= 0); 
    return isVisible; 
} 

puede personalizar esa función a su situación mediante el cálculo de si un elemento ha sido leída:

function isRead(element) { 
    var elementTop = element.getBoundingRect().top; 
    var elementBottom = element.getBoundingRect().bottom; 
    var elementHeight = elementBottom - elementTop; 

    // if 75% of the document has been scrolled, we'll assume it's been read 
    var readIfPercentage = 0.75; 

    // an element has been read if the top has been scrolled up out of view 
    // and at least 75% of the element is no longer visible 
    var isRead = (elementTop < 0 && Math.abs(elementTop)/elementHeight >= readIfPercentage); 
    return isRead; 
} 

A continuación, puede llamar a las funciones anteriores, pasando de un nodo DOM como el elemento:

isScrolledIntoView(document.getElementById('targetDiv'); 
//or 
isRead(document.getElementById('targetDiv'); 

Puede unirlo todo mediante la creación de un oyente de desplazamiento (jQuery hace que esta bastante fácil):

function setScrollListener() { 

    var scrollEventHandler = function() { 
    if (isRead(document.getElementById('article'))) { 
     // set article to 'read' 
    } 
    } 

    // on scroll, fire the event handler 
    $(document).scroll(scrollEventHandler); 
} 

Vale la pena señalar que si desea desenlazar el oyente de desplazamiento, decir si todos los artículos han sido leídos y ya no necesita escuchar el desplazamiento, puede llamar a la función de deshacer en el scrollEventHandler. Es tan simple como:

function unbindScrollEventHandler() { 
    $(document).unbind('scroll', scrollEventHandler); 
} 
Cuestiones relacionadas