Иногда на одной странице имеется множество разделов, заголовок каждого из которого имеет якорь. Задача состоит в том, чтобы при прокрутке страницы посредством колёсика мышкой или полосы прокрутки в адресной строке изменялся бы хэш, добавляемый к адресу. Здесь описаны 4 способа решить эту задачу. Такой скрипт может работать совместно с оглавлением с плавной прокруткой страницы до якоря по нажатию пункта оглавления (TOC – table of contents).
jQuery:
//uses on instead of bind, so it works with 1.9.1/2.0 +
$(document).on('scroll',function(e)
{
$('section').each(function()
{
if ( $(this).offset().top < window.pageYOffset + 10
&& $(this).offset().top +
$(this).height() > window.pageYOffset + 10
)
{
var data = $(this).data('id');
window.location.hash = data;
}
});
});HTML:
<div id="" data-id="">Содержимое div</div>Вариант 2
jQuery:
$(document).ready(function(){
var sections = {};
$(".section").each(function(){
var hash = $(this).data("hash"),
topOffset = $(this).offset().top;
sections[topOffset] = hash;
});
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
setHash(scrollTop);
});
function setHash(st){
var hash = "";
for(section in sections){
if (section < st + ($(window).height()/2)) hash = sections[section];
}
console.log(`SETTING HASH: ${hash}`);
window.location.hash = hash;
}
});CSS:
section{
position: relative;
display: block;
width: 100%;
height: 800px;
background: #fff;
border-bottom: 1px solid #000;
}HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="section" data-hash="about">
#about
</section>
<section class="section" data-hash="works">
#works
</section>
<section class="section" data-hash="contact">
#contact
</section>Вариант 3
jQuery:
$(document).bind('scroll',function(e){
$('section').each(function(){
if (
$(this).offset().top < window.pageYOffset + 10
//begins before top
&& $(this).offset().top + $(this).height() > window.pageYOffset + 10
//but ends in visible area
//+ 10 allows you to change hash before it hits the top border
) {
window.location.hash = $(this).attr('id');
}
});
});HTML:
<section id="home">
Home
</section>
<section id="works">
Works
</section>
<section id="about">
About
</section>Вариант 4
Последний, четвёртый вариант корректно работает в браузере IE 11 (а не только в Google Chrome и ему подобных).
jQuery:
(function () {
//Find all top,bottom and Hash of each sections
var section = $.map($("section"), function (e) {
var $e = $(e);
var pos = $e.position();
return {
top: pos.top - 100,
bottom: pos.top - 100 + $e.height(),
hash: $e.attr('id')
};
});
//Checking scroll
var top = null;
var changed = false;
var currentHash = null;
$(window).scroll(function () {
var newTop = $(document).scrollTop();
changed = newTop != top;
if (changed) {
top = newTop;
}
});
//set up for Hash while start scroll and the checking only every 300ms to prevent FPS
function step() {
if (!changed) {
return setTimeout(step, 200);
console.log("End");
}
var count = section.length;
var p;
while (p = section[--count]) {
if (p.top >= top || p.bottom <= top) {
continue;
}
if (currentHash == p.hash) {
break;
}
var scrollTop = $(document).scrollTop();
window.location.hash = currentHash = p.hash;
// prevent browser to scroll
$(document).scrollTop(scrollTop);
}
setTimeout(step, 200);
}
setTimeout(step, 200);
})();HTML:
<section class="block" id="block-1" data-program="block-1">Block 1</section>
<section class="block" id="block-2" data-program="block-2">Block 2</section>
<section class="block" id="block-3" data-program="block-3">Block 3</section>
<section class="block" id="block-4" data-program="block-4">Block 4</section>CSS:
.block {
border: 1px solid #666;
box-shadow: 2px 2px 2px #333;
background: #f1f1f1;
height: 979px;
padding: 100px;
font-size: 20px;
color: #333;
max-height: 100%;
text-align: center;
}
.block:nth-child(1) {
background-color: red;
}
.block:nth-child(2) {
background-color: green;
}
.block:nth-child(3) {
background-color: blue;
}
.block:nth-child(4) {
background-color: yellow;
}