Jquery - Trigger on View and Determine Everything that was "read"
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Imagine we have an article page that contains h1, h2, div, and p elements.:
<div class="article">
<h1>Title</h1>
<h2>Subtitle<h2>
<p>Some Text</p>
<div class="imageBox"><img src="Some Image"></div>
<p>Some Text</p>
</div>

We want to

  • 1) Count how many elements there are inside $(".article") and number them so we can trigger events with each one of them as explained next.

  • 2) For each element (p, img, div, h1, h2, etc) determine if it has been read or not. When I say "read" I mean that the element has been seen (in technical terms, this would be equivalent as if it has been on the viewport). There are many libraries which trigger an event every time an element is into viewport. Use this or anything similar, and trigger a waypoint for every single element inside class .article. You will want to change the class to ".read" for every element that met the condition and change color to green (as a test), so that if an element enters the viewport OR was in the viewport as soon as the page loaded, it should be colored to background green..

  • 3) Save into array var elementsRead the order in which elements where seen (waypoints where triggered) by storing the element number.

Example: elementsRead: {1,2,3,4,5,6, 25,26,27,28} would mean that the user loaded the page and saw elements 1,2,3 (without any action) and then scrolled to the next 3 paragraphs (4,5,6) and then jumped by clicking on the scroll bar to the bottom of the article to the paragraphs 25, 26,27,28.

Please create sample working demo where you show how the elementsRead variable changes as the user scrolls and how the paragraphs or elements color themselves with the .read class.

Viewport detection plugins which you may find useful:

This might also be useful:
http://jsbin.com/ugupa/1/edit?html,js,output

Your solution should work on mobile. Use a library that works on mobile.

Please solve using Jquery.

awarded to farolanf

Crowdsource coding tasks.

1 Solution


Check if the elements had been read

Only depends on jQuery.

http://codepen.io/farolan/pen/NpKQrw

Changes

  • Use timing to determine if elements were truly had been "read"
  • Don't generate elements dynamically
  • Index the elements (store the index on the element.index and on its class, e.g. .0 .1 .2 and so on)
  • Set background color to green for elements that had been read
  • Save the read order in the elementsRead
Hi Farolanf, thanks for the solution. Your solution works good except that you are creating the elements randomly. Suppose that they are not created randomly, your solution does not number the elements. So what I need you to do is to analyze the current text, and index the elements and make this into a different function than generateElements. Thanks
georgefountain 8 months ago
If I remove generateElements and create the elments myself, the array does not contain the index of each element. So what I am asking is to modify the classes of all elements and number them from 1 to N.
georgefountain 8 months ago
You are storing the elements themselves on elementsRead. I don't want the element. I just want the index number.
georgefountain 8 months ago
Hi Farolanf, the solution is perfect and it makes you the winner of the bounty. However, I want to ask you for an additional feature and if you solve it I will pay you 100% additional tip. Can you put a condition so that element gets marked as read only if it is on viewport for more than X seconds? This would be helpful as right now, if I scroll really fast, everything is marked as "read" when it wasn't read, it was just glimpsed. Thanks
georgefountain 8 months ago
I have updated the script to use timing, please check it out.
farolanf 8 months ago
The solution works fantastic! I am giving you the tip as promised as well as awarding you the bounty. Now that you finished the prototype can you fully organize the code, and make it into a closure and rename init to trackReadProgress(".article", /* number of seconds to consider read /, / callback function on update */) so I can use this on production? Separate test code from "library" code. Sample call would be trackReadProgress(".article", 2000, function(elementsRead){ console.log(elementsRead);} Separate the debug output code from the actual code. You could replicate the same layout you have having trackReadProgress(".article", 2000, updateLeftPanel); function updateLeftPanel(elementsRead) { /* your debug code */}
georgefountain 8 months ago
Thanks. I have organized the code, please check it out.
farolanf 8 months ago
Fantastic job! Thank you!!!
georgefountain 8 months ago