I've recently found that many sites add a pointer to the current reading position (how much you read depends on how much you pull down the scroll bar in this article). Typically, this indicator is used in blog posts or long forms to help read and understand how much more they can do with this article or form.
Problem
To create a reading position indicator, we need to answer the following two questions:
-
How long is the page? the length of the Web page is the same as the current length of the document, which can be computed by JavaScript.
-
where is the user's current reading position? to get the user's current reading position may need to go into the user's mind to look for, within the given range of technologies we can handle, this looks like artificial intelligence and impossible to achieve.
This makes us have to use a completely different way to solve this problem.
Principle
The principle of this technique is based on the simple fact that the user has to scroll to the bottom of the page. Once the user scrolls down to the bottom of the page, we can get the user to have read the completed article. The key to solving the problem of getting the current user's reading position is to resolve the scroll bar scrolling event.
Assuming the user starts reading from the top of the page and he only scrolls through the scroll bar before reaching the bottom of the page, we will answer the following questions:
-
How long does it take the user to scroll to the bottom of the page? the part of the page that hides below the user's viewpoint actually reflects the actual number of users who need to scroll to the bottom of the page. This will become the Max attribute.
-
How many parts has the user scrolled? This can be computed by the vertical offset of the contents of the document in the window to the top, which will be our value attribute.
The example above simulates the behavior of the User scrolling window, and the vertical offset increases as the user scrolls down the scroll bar.
In the context of the browser, document and window are two different objects. window is a visible area of the browser (in the case of the blue window in the example above), document is actually a loaded page in window (the gray box currently scrolling in the example).
Mark
Let's start with the most basic tags:
<progress value= "0" ></progress>
It is important to explicitly specify the Value property. Otherwise, our progress bar will be in an unknown state. We don't want to add unnecessary CSS styles to the agnostic state of the progress bar. Therefore, we chose to ignore the state by adding an initial value. At first, the user starts reading from the top of the page, so the start value is set to 0, by default, the maximum value is 1 (if not specified).
To get the correct value for the max attribute, we need to subtract the height of the window from the document height. This can only be done with JavaScript, and we'll discuss it later in the section.
The position of the tag in the document is heavily dependent on how the remaining elements in the HTML document are placed. Typically, if you don't have a fixed-position container in your document, you can place the progress bar on top of all other elements within the BODY element.
<body>
<progress value= "0" ></progress>
<!--------------------------------
Put extra marks here
--------------------------------->
</body>
Add a style to an indicator
We want our indicator to always appear at the top of the page, even if the user scrolls the window, and we set the progress element to fixed. In addition, we should expect the background of the progress bar to be transparent (transparent), so that when the page scrolls, an empty progress bar is not created to obstruct the user's view. At the same time, this will help us deal with the performance of browsers when JavaScript is disabled, and we'll explain that later.
Progress {
/* positioning * *
position:fixed;
left:0;
top:0;
/* Dimensions * *
width:100%;
height:5px;
* Reset the appearance * *
-webkit-appearance:none;
-moz-appearance:none;
Appearance:none;
/* Get rid of the default border in Firefox/opera. * *
Border:none;
/* Progress bar container for firefox/ie10+ * *
background-color:transparent;
/* Progress Bar value for ie10+ *
/color:red;
}
For Blink/webkit/firefox, we need to add to the progress bar style using the prefix specified by the vendor, which is used to add color to the progress bar.
Progress::-webkit-progress-bar {
background-color:transparent;} Progress::-webkit-progress-value {
background-color:red;
}
Progress::-moz-progress-bar {
background-color:red;
}
Interaction
Using JavaScript to compute the browser's width/height properties is cumbersome, and the performance in different kernel browsers is terrifying. Fortunately, jquery abstracts these complex operations so that we can calculate the window and document metrics in a clear way. So, in the next section, we'll use jquery to process the interaction with the user.
Before you start, don't forget to add JQuery's class library to your document.
<script src= "//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" ></script>
We need to use jquery to get the Max and value properties of the progress bar element.
max-its value is the height of the portion of the page not shown by the height of the document minus the height of the window.
var winheight = $ (window). Height (),
docheight = $ (document). Height ();
max = Docheight-winheight;
$ (progress). attr (' Max ', Max);
Value-just started, the Value property is 0 (already indicated in the tag). Then, as the user scrolls through the scroll bar, the height of the vertical document to the window increases, and if the scroll bar is at the top of the page or is not scrollable, the offset will be 0.
var value = $ (window). scrolltop ();
$ (progress). attr (' value ', value);
Tip: Instead of using $ (document). Height (), we can use the content of the article, such as section,article, or DIV, to compute it so that we can get a higher degree of accuracy in the reading position. This is useful when our article contains comments and other parts of the page that occupy more than 50% of the page.
Now, each time the user scrolls the scroll bar, we need to recalculate values for value and set the progress bar Value property. Note that the Max property is invariant.
$ (document). On (' scroll ', function () {
value = $ (window). scrolltop ();
Progressbar.attr (' value ', value);
};
The direction in which the user scrolls is not important because each time we recalculate value (the offset in the y direction).
Our code needs to be executed after the DOM is loaded, which is very important, otherwise, a premature calculation of the height of the window/document can produce unpredictable results.
$ (document). On (' Ready ', function () {
var winheight = $ (window). Height (),
docheight = $ (document). Height (),
ProgressBar = $ (' progress '),
max, value;
/* Set the max scrollable area * *
max = docheight-winheight;
Progressbar.attr (' Max ', max);
$ (document). On (' scroll ', function () {
value = $ (window). scrolltop ();
Progressbar.attr (' value ', value);
});
});
(or you can have this code load at the bottom of the page so that you can skip ready calls that use the document.)
Browser compatibility
This requires us to create a reading position indicator that will be able to have the same performance in different browsers, and this reading position indicator we have built will work properly in all browsers that support HTML5 progress bar elements. However, this support is available only on Firefox16+,opera 11+, Chrome,safari 6+,ie 10+ browsers. Opera 11 and 12 do not support changing the color of the progress bar. As a result, our progress bar will be the default green.
Boundary issues
In many cases, the above code may crash or not be able to correctly indicate where the user is reading, so let's look at the situation.
Document Height <=window Height
Our code assumes the height of the document is always greater than the height of the window, but this is not always the case. Fortunately, the browser will help us deal with this situation, and when the document is taller than window height, the browser returns the height of the window. Therefore, Docheight and Winheight are the same.
max = Docheight-winheight; Equal to zero.
This will let the progress bar's Max and value properties be 0.
<progress max= "0" value= "0" ></progress>
Therefore, our progress bar is still empty, and our background is transparent so that no progress bar will appear in the page. This creates the feeling that there is no need to add an indicator when the user's viewpoint fills the entire page.
Also, scrolling events are not triggered because the height of the document does not exceed the height of the window. Therefore, there is no need to do any processing, and our code is robust enough to deal with this boundary problem.
User changes the window size
When the user changes the window size, the height of the window and document will change. This means that we have to recalculate the max and value properties to reflect the current correct position of the indicator. We will recalculate the correct location through the Resize event handler.
$ (window). On (' Resize ', function () {
winheight = $ (window). Height (),
docheight = $ (document). Height ();
max = Docheight-winheight;
Progressbar.attr (' Max ', max);
Value = $ (window). scrolltop ();
Progressbar.attr (' value ', value);
};
JavaScript is disabled
When JavaScript is disabled, our progress bar will have a maximum value of 1, and the current default value is 0.
<progress max= "1" value= "0" ></progress>
This means that our progress bar will remain empty and will not affect other parts of the page. This is good because there is no indicator on the page that is not a big flaw for the reader.
Old Browser-compatible
The old browser that does not support HTML5 's progress bar elements will ignore the progress tag. However, for some sites, it is important to provide a consistent experience (this scenario is slightly detailed in the original text).
Performance
In general, adding an event handler to a scrolling event is considered a very bad practice because the browser tries to redraw what appears every time it scrolls. In our example, the structure and style of the DOM are relatively simple, and there is no noticeable delay or lag in the page scrolling. However, when we zoom in here and implement in our site with the complex DOM structure, the scrolling experience will create a lot of performance deficiencies.
If scrolling performance becomes a big problem that you are faced with, you should avoid using this feature as much as possible or try to optimize the code to avoid unnecessary redrawing.
caused by the confusion
I'm not a UX expert, but in some cases, the location and appearance of our indicators may be ambiguous and misleading. Ajax-driven sites, such as Medium,youtube, use a similar progress bar to indicate the progress of the next page load. The Chrome mobile browser uses the blue progress bar locally as the page loads progress. Now, if you add a progress indicator to the frame, I'm sure a lot of people will take a long time to understand how this top indicator works.
You have to weigh whether this is good for your users.
-
Semantic accuracy
-
No introduction to the book Math library or a complex calculation
-
Minimize the necessary markup
-
Seamless and compatible browsers that do not support HTML5 progress bars
-
Seamless browser that disables JavaScript
-
Cross-browser styles are complex
-
The compatibility of old browsers relies on traditional Div/span (s) tagging technology to implement
-
Performance impact (in the case of complex DOM structures)
-
The progress bar with the page load progress is confusing, making it difficult for the user to understand