Detectando divs como prestado na janela para implementar Google-Reader-como auto-mark-as-ler?

votos
11

Ao usar o Google Reader e navegar entradas RSS na visualização expandida, as entradas serão automaticamente marcados como 'ler' uma vez que uma certa percentagem do div é visível na tela (difícil dizer qual a percentagem tem de ser visível no caso de Leitor do Google). Então, como eu rolar para baixo linha por linha, o código javascript pode determinar que: a) a entrada está sendo processado na janela visível e b) uma certa quantidade é visível e quando essas condições forem satisfeitas, o Estado é alternado para ler .

Alguém tem alguma idéia de como esse recurso é implementado? Especificamente, alguém aqui sabe como dizer se uma div tem rolado em vista um quanto do div é visível?

Como um aparte, eu estou usando jQuery, então se alguém tiver alguma exemplos jQuery específicos de, eles seria muito apreciado.

Publicado 09/12/2008 em 21:33
fonte usuário
Em outras línguas...                            


6 respostas

votos
0

Na minha experiência, leitor tem sempre apenas marcou algo como ler se eu moused-over ou clicado nele. Supondo que ao rolar o mouse está sobre o div (I tendem a colocar o meu mouse para a borda direita da tela quando eu rolar) que pode explicar a aparência de que ele só fica marcada quando uma determinada% foi mostrado.

Eu poderia ser (e provavelmente sou) errado, porém. Eu só sei que o ato de apenas percorrer os meus itens no leitor não marcá-los fora. Eu tenho que ter certeza mouses o mouse sobre eles, uma vez que rola para fazê-lo.

Respondeu 09/12/2008 em 21:43
fonte usuário

votos
0

O dom e javascript permitem calcular um deslocamento de seu pai elemento. Para calcular o deslocamento da janela você precisa usar recursão e escalar o seu caminho até a janela superior, e também comparar isso contra o tamanho da janela. Ele fica mais complicado por causa de questões cross-browser e iframes.

Para o melhor de meu conhecimento, protótipo oferece um simples viewportOffsetmétodo que faz a maioria do trabalho para você. Você também pode verificar a fonte para getOffsetParente scrollTo. Eu não sei sobre jQuery, mas eu esperava que oferecem métodos semelhantes.

Meu palpite é que o script no Google Reader simplesmente é executado em um tempo limite, provavelmente algumas vezes por segundo, ou talvez em resposta a um evento de rolagem. Em ambos os casos, estou certo de que é adaptativo (mudanças de tempo limite com base em quão rápido o usuário rola, etc.), e que é inteligente o suficiente para não ser um devorador de recursos (ou seja, não basta verificar todos os divs em o documento)

Respondeu 14/12/2008 em 00:36
fonte usuário

votos
4

O verdadeiro truque é manter o controle de onde a barra de rolagem está no elemento que contém seus itens. Aqui está algum código uma vez que eu chicoteado até fazê-lo: http://pastebin.com/f4a329cd9

Você pode ver que enquanto você rola ele muda o foco. Você só precisa adicionar mais código do manipulador para a função que lida com cada mudança de foco. Ele funciona rolagem em ambos os sentidos, e também pelo botão direito sobre a barra de rolagem, que rastreamento simples mouse não vai lhe dar (embora, neste caso, uma vez que os elementos exemplo são todos do mesmo tamanho, com o mesmo texto, é difícil dizer que ele de fato rolado). A outra questão é o que fazer quando o recipiente bottoms fora. A solução que eu tenho agora só funciona no FF. Se você quiser tê-lo uma boa aparência no IE, você terá que usar um elemento fictício que combina com o fundo, como a que eu tenho comentado no código.

Respondeu 15/12/2008 em 05:51
fonte usuário

votos
2

Deparei-me com isso como eu preciso a mesma coisa, e parece super útil:

http://www.appelsiini.net/projects/viewport

Respondeu 28/12/2008 em 07:53
fonte usuário

votos
0

Para calcular se um elemento é visível, você pode criar uma tal função (crédito é devido aqui 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;
}

Você pode personalizar essa função à sua situação por meio do cálculo se um elemento foi lido:

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;
}

Você pode, em seguida, chamar as funções acima, passando em um nó DOM como o elemento:

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

Você pode unir tudo isso através da criação de um ouvinte de rolagem (jQuery faz isso muito 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);
}

É importante notar que, se você quer desvincular o ouvinte de rolagem, dizer se todos os artigos foram lidos e você não precisa mais ouvir o livro, você pode chamar a função unbind dentro do scrollEventHandler. É tão simples como:

function unbindScrollEventHandler() {
  $(document).unbind('scroll', scrollEventHandler);
}
Respondeu 03/10/2017 em 13:20
fonte usuário

votos
0

Você pode tentar este, o ponto chave é o elemento deve visível para corpo interior mais e conhecer a relação visível (neste caso, 0,85).

isRead(element) {
   let rect = element.getBoundingClientRect();
   const visibleRatio = 0.85;
   let elementRatio = (window.innerHeight - Math.abs(rect.top))/rect.height;
   let isRead = (rect.top >= 0) && (elementRatio >= visibleRatio);
   return isRead; 
}
Respondeu 28/05/2018 em 19:11
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more