Skip to content

Instantly share code, notes, and snippets.

@ArtemSites
Last active May 4, 2024 13:29
Show Gist options
  • Save ArtemSites/860cfcd079b1f42cace732c31b5e3a29 to your computer and use it in GitHub Desktop.
Save ArtemSites/860cfcd079b1f42cace732c31b5e3a29 to your computer and use it in GitHub Desktop.
<h1 id="как-сделать-плавный-скролл-к-любому-положению-на-html-странице">Как сделать плавный скролл к любому положению на html странице</h1>
<h2 id="1-где-скачать-скрипт-плавной-прокрутки-к-любому-положению-на-странице">1. Где скачать скрипт плавной прокрутки к любому положению на странице</h2>
<p><a href="https://gist.githubusercontent.com/artemsites/860cfcd079b1f42cace732c31b5e3a29/raw/scrollSmoothlyToPosition.js">scrollSmoothlyToPosition.js</a></p>
<h2 id="2-как-подлключить-скрипт-js-к-телу-html-документа">2. Как подлключить скрипт js к телу html документа</h2>
<p>Перед закрывающим тегом <code>&lt;/head&gt;</code>
подключаем скрипт плавного скролла <strong>scrollSmoothlyToPosition.js</strong>
и главный скрипт где будем описывать логику <strong>main.js</strong></p>
<pre><code>&lt;head&gt;
...
&lt;script src=&quot;./scrollSmoothlyToPosition.js&quot; defer&gt;&lt;/script&gt;
&lt;script src=&quot;./main.js&quot; defer&gt;&lt;/script&gt;
&lt;/head&gt;
</code></pre>
<h2 id="3-как-подлючить-js-скрипт-к-модулю-js">3. Как подлючить js скрипт к модулю js</h2>
<p>Подключаем модуль js к телу html документа перед закрывающим тегом <code>&lt;/head&gt;</code> </p>
<pre><code> ...
&lt;script src=&quot;./main.js&quot; type=&quot;module&quot; defer&gt;&lt;/script&gt;
&lt;/head&gt;
</code></pre>
<p>В самом <strong>main.js</strong> импортируем наш скрипт</p>
<pre><code>import { scrollSmoothlyToPosition } from &quot;./scrollSmoothlyToPosition.js&quot;;
</code></pre>
<p>В таком случае в скрипт <strong>scrollSmoothlyToPosition.js</strong> добавляем диррективу export перед объявлением функции</p>
<pre><code>export function scrollSmoothlyToPosition(params) {...
</code></pre>
<h2 id="4-как-пользоваться-скриптом-плавной-прокрутки">4. Как пользоваться скриптом плавной прокрутки</h2>
<p>В <strong>main.js</strong> пишем следуюущую конструкцию:</p>
<ol>
<li>Дожидаемся построения html структуры</li>
<li>Применяем конструкцию <code>try..catch</code> чтобы перехватывать ошибки, чтобы остальной js код не ломался при ошибке </li>
<li>Тут будем использовать скрипт плавной прокрутки</li>
</ol>
<pre><code>// 1. Дожидаемся построения html структуры
document.addEventListener(&quot;DOMContentLoaded&quot;, function () {
// 2. Применяем конструкцию try..catch чтобы перехватывать ошибки, чтобы остальной js код не ломался при ошибке
try {
// 3. Тут будем использовать скрипт плавной прокрутки
} catch (err) {
console.error(err);
}
});
</code></pre>
<h2 id="5-как-плавно-проскроллить-страницу-к-определённому-элементу-с-id">5. Как плавно проскроллить страницу к определённому элементу с id</h2>
<p><code>selector: &quot;#block3&quot;</code> означает что скролл произойдёт к элементу с <code>id=&quot;block3&quot;</code> </p>
<pre><code> scrollSmoothlyToPosition({
// selector: &quot;#block3&quot; означает что скролл произойдёт к элементу с id=&quot;block3&quot;
selector: &quot;#block3&quot;,
});
</code></pre>
<h2 id="6-как-плавно-проскроллить-к-элементу-на-странице">6. Как плавно проскроллить к элементу на странице</h2>
<ol>
<li>Допустим у нас уже есть найденный элемент в коде </li>
<li>Тогда подключение в скрипте будет через свойство <code>el</code></li>
</ol>
<pre><code>// 1. Допустим у нас уже есть найденный элемент в коде
let element = document.querySelector(&#39;#block3&#39;);
scrollSmoothlyToPosition({
// 2. Тогда элемента в скрипте будет через свойство el
el: element,
});
</code></pre>
<h2 id="7-как-при-плавном-скролле-добавить-отступ-сверху-между-элементом-и-верхней-частью-браузера">7. Как при плавном скролле добавить отступ сверху между элементом и верхней частью браузера</h2>
<p>Число 50 означает что при скролле добавится отступ в 50px от верха страницы</p>
<pre><code> scrollSmoothlyToPosition({
selector: &quot;#block3&quot;,
// Число 50 означает что при скролле добавится отступ в 50px от верха страницы
offsetTop: 50,
});
</code></pre>
<h2 id="8-как-при-плавном-скролле-добавить-отступ-сверху-между-элементом-и-верхом-страницы-в-rem">8. Как при плавном скролле добавить отступ сверху между элементом и верхом страницы в <code>rem</code></h2>
<p>Строка <code>&quot;5rem&quot;</code> означает что при скролле добавится отступ в 5rem от верха страницы</p>
<pre><code> scrollSmoothlyToPosition({
selector: &quot;#block3&quot;,
// Строка &quot;5rem&quot; означает что при скролле добавится отступ в 5rem от верха страницы
offsetTop: &quot;5rem&quot;,
});
</code></pre>
<h2 id="9-как-плавно-проскроллить-к-элементу-чтобы-низ-элемента-был-снизу-браузера-видимой-части-страницы">9. Как плавно проскроллить к элементу чтобы низ элемента был снизу браузера (видимой части страницы)</h2>
<p><code>mode: &quot;bottom&quot;</code> - означает что скролл будет нижней части блока к нижней части браузера</p>
<pre><code> scrollSmoothlyToPosition({
selector: &quot;#block3&quot;,
// mode: &quot;bottom&quot; - означает что скролл будет нижней части блока к нижней части браузера
mode: &quot;bottom&quot;,
});
</code></pre>
<h2 id="10-как-плавно-проскроллить-страницу-сайта-к-определённой-точке-y">10. Как плавно проскроллить страницу сайта к определённой точке <code>y</code></h2>
<p><code>y: 500</code> - означает что страница будет просроллена на 500px вниз от верха страницы</p>
<pre><code>scrollSmoothlyToPosition({
// y: 500 - означает что страница будет просроллена на 500px вниз от верха страницы
y: 500,
});
</code></pre>
<h2 id="11-как-на-практике-применять-скрипт-плавного-скролла-к-разным-точкам">11. Как на практике применять скрипт плавного скролла к разным точкам</h2>
<h3 id="111-как-плавно-проскроллить-страницу-к-верху-по-нажатию-на-кнопку">11.1 Как плавно проскроллить страницу к верху по нажатию на кнопку</h3>
<p>На html страницу размещаем кнопку</p>
<pre><code>&lt;button id=&quot;button-up&quot;&gt;UP&lt;/button&gt;
</code></pre>
<p>В <strong>main.js</strong> пишем такую логику</p>
<pre><code>let buttonUp = document.querySelector(&#39;#button-up&#39;);
buttonUp.addEventListener(&quot;click&quot;,function(e) {
scrollSmoothlyToPosition({
y: 0,
});
});
</code></pre>
<h3 id="112-как-плавно-скроллить-к-блокам-по-ссылкам-навигации-a-hrefblock3перейти-к-блоку-3a-способ-№1-на-css">11.2 Как плавно скроллить к блокам по ссылкам навигации <code>&lt;a href=&quot;#block3&quot;&gt;Перейти к блоку 3&lt;/a&gt;</code> способ №1 на CSS</h3>
<p>В файле стилей css прописать правило для html тега:</p>
<pre><code>html {
scroll-behavior: smooth;
}
</code></pre>
<p>Теперь прокрутки на странице с ссылок с хэшами <code>&lt;a href=&quot;#block3&quot;&gt;Перейти к блоку 3&lt;/a&gt;</code> будут происходить плавно.</p>
<h3 id="113-как-плавно-скроллить-к-блокам-по-ссылкам-навигации-a-hrefblock3перейти-к-блоку-3a-способ-№2-на-javascript">11.3 Как плавно скроллить к блокам по ссылкам навигации <code>&lt;a href=&quot;#block3&quot;&gt;Перейти к блоку 3&lt;/a&gt;</code> способ №2 на JavaScript</h3>
<p>В html имеем ссылки на блоки на странице</p>
<pre><code>&lt;a href=&quot;#block1&quot;&gt;Перейти к блоку 1&lt;/a&gt;
&lt;a href=&quot;#block2&quot;&gt;Перейти к блоку 2&lt;/a&gt;
&lt;a href=&quot;#block3&quot;&gt;Перейти к блоку 3&lt;/a&gt;
</code></pre>
<p>И сами блоки</p>
<pre><code>&lt;div id=&quot;block1&quot;&gt;Блок 1&lt;/div&gt;
&lt;div id=&quot;block2&quot;&gt;Блок 1&lt;/div&gt;
&lt;div id=&quot;block3&quot;&gt;Блок 1&lt;/div&gt;
</code></pre>
<p>Тогда в main.js пропишем следующую логику:</p>
<ol>
<li>Соберём все ссылки на странице</li>
<li>Обойдём каждую</li>
<li>Если в ссылке есть хэш (обозначение id на странице - <code>#block3</code>)</li>
<li>То добавляем к этой ссылке плавный скролл</li>
<li>Предотвращаем поведение по умолчанию (без скролла)</li>
<li>Скроллим к элементу по селектору в который кладём хэш ссылки который соответствует селектору блока по id</li>
</ol>
<pre><code>// 1. Соберём все ссылки на странице
let links = document.querySelectorAll(&quot;a&quot;);
// 2. Обойдём каждую
links.forEach(function (link) {
// 3. Если в ссылке есть хэш (обозначение id на странице - **#block3**)
if (link.hash !== &quot;&quot;) {
// 4. То добавляем к этой ссылке плавный скролл
link.addEventListener(&quot;click&quot;, function (e) {
// 5. Предотвращаем поведение по умолчанию (без скролла)
e.preventDefault();
// 6. Скроллим к элементу по селектору в который кладём хэш ссылки который соответствует селектору блока по id
scrollSmoothlyToPosition({
selector: link.hash,
});
});
}
});
</code></pre>
<hr>
<p>Надеюсь данная статья о плавном скролле к любому элементу на странице была вам полезна</p>
<p>Если у вас остались вопросы пожалуйста пишите по <strong><a href="https://practical-web.ru/contacts">контактам</a></strong></p>
<p>И мы разберём более подробно как пользоваться скриптом плавной прокрутки к любому элементу на странице.</p>
<h2 id="код-из-статьи-хранится-в-github-репозитории">Код из статьи хранится в <a href="https://github.com/artemsites/how-to-make-a-smooth-scroll-to-any-position-on-an-html-page/blob/main/main.js">GitHub репозитории</a></h2>

Как сделать плавный скролл к любому положению на html странице

1. Где скачать скрипт плавной прокрутки к любому положению на странице

scrollSmoothlyToPosition.js

2. Как подлключить скрипт js к телу html документа

Перед закрывающим тегом </head> подключаем скрипт плавного скролла scrollSmoothlyToPosition.jserySelector('#block3') и главный скрипт где будем описывать логику main.js

<head>
  ...
  <script src="./scrollSmoothlyToPosition.js" defer></script>
  <script src="./main.js" defer></script>
</head>

3. Как подлючить js скрипт к модулю js

Подключаем модуль js к телу html документа перед закрывающим тегом </head>

  ...
  <script src="./main.js" type="module" defer></script>
</head>

В самом main.js импортируем наш скрипт

import { scrollSmoothlyToPosition } from "./scrollSmoothlyToPosition.js";

В таком случае в скрипт scrollSmoothlyToPosition.js добавляем диррективу export перед объявлением функции

export function scrollSmoothlyToPosition(params) {...

4. Как пользоваться скриптом плавной прокрутки

В main.js пишем следуюущую конструкцию:

  1. Дожидаемся построения html структуры
  2. Применяем конструкцию try..catch чтобы перехватывать ошибки, чтобы остальной js код не ломался при ошибке
  3. Тут будем использовать скрипт плавной прокрутки
// 1. Дожидаемся построения html структуры
document.addEventListener("DOMContentLoaded", function () {
  // 2. Применяем конструкцию try..catch чтобы перехватывать ошибки, чтобы остальной js код не ломался при ошибке 
  try {

		// 3. Тут будем использовать скрипт плавной прокрутки

  } catch (err) {
    console.error(err);
  }
});

5. Как плавно проскроллить страницу к определённому элементу с id

selector: "#block3" означает что скролл произойдёт к элементу с id="block3"

  scrollSmoothlyToPosition({
  	// selector: "#block3" означает что скролл произойдёт к элементу с id="block3"
    selector: "#block3",
  });

6. Как плавно проскроллить к элементу на странице

  1. Допустим у нас уже есть найденный элемент в коде
  2. Тогда подключение в скрипте будет через свойство el
	// 1. Допустим у нас уже есть найденный элемент в коде  
	let element = document.querySelector("#block3");
	
	scrollSmoothlyToPosition({
	  // 2. Тогда элемента в скрипте будет через свойство el  
	  el: element,
	});

7. Как при плавном скролле добавить отступ сверху между элементом и верхней частью браузера

Число 50 означает что при скролле добавится отступ в 50px от верха страницы

  scrollSmoothlyToPosition({
    selector: "#block3",
    // Число 50 означает что при скролле добавится отступ в 50px от верха страницы
    offsetTop: 50, 
  });

8. Как при плавном скролле добавить отступ сверху между элементом и верхом страницы в rem

Строка "5rem" означает что при скролле добавится отступ в 5rem от верха страницы

  scrollSmoothlyToPosition({
    selector: "#block3",
		// Строка "5rem" означает что при скролле добавится отступ в 5rem от верха страницы
    offsetTop: "5rem",
  });

9. Как плавно проскроллить к элементу чтобы низ элемента был снизу браузера (видимой части страницы)

mode: "bottom" - означает что скролл будет нижней части блока к нижней части браузера

  scrollSmoothlyToPosition({
    selector: "#block3",
    // mode: "bottom" - означает что скролл будет нижней части блока к нижней части браузера
    mode: "bottom",
  });

10. Как плавно проскроллить страницу сайта к определённой точке y

y: 500 - означает что страница будет просроллена на 500px вниз от верха страницы

scrollSmoothlyToPosition({
  // y: 500 - означает что страница будет просроллена на 500px вниз от верха страницы
  y: 500,
});

11. Как на практике применять скрипт плавного скролла к разным точкам

11.1 Как плавно проскроллить страницу к верху по нажатию на кнопку

На html страницу размещаем кнопку

<button id="button-up">UP</button>

В main.js пишем такую логику

let buttonUp = document.querySelector('#button-up');

buttonUp.addEventListener("click",function(e) {
  scrollSmoothlyToPosition({
    y: 0,
  });
});

11.2 Как плавно скроллить к блокам по ссылкам навигации <a href="#block3">Перейти к блоку 3</a> способ №1 на CSS

В файле стилей css прописать правило для html тега:

html { 
	scroll-behavior: smooth; 
} 

Теперь прокрутки на странице с ссылок с хэшами <a href="#block3">Перейти к блоку 3</a> будут происходить плавно.

11.3 Как плавно скроллить к блокам по ссылкам навигации <a href="#block3">Перейти к блоку 3</a> способ №2 на JavaScript

В html имеем ссылки на блоки на странице

<a href="#block1">Перейти к блоку 1</a>
<a href="#block2">Перейти к блоку 2</a>
<a href="#block3">Перейти к блоку 3</a>

И сами блоки

<div id="block1">Блок 1</div>
<div id="block2">Блок 1</div>
<div id="block3">Блок 1</div>

Тогда в main.js пропишем следующую логику:

  1. Соберём все ссылки на странице
  2. Обойдём каждую
  3. Если в ссылке есть хэш (обозначение id на странице - #block3)
  4. То добавляем к этой ссылке плавный скролл
  5. Предотвращаем поведение по умолчанию (без скролла)
  6. Скроллим к элементу по селектору в который кладём хэш ссылки который соответствует селектору блока по id
	// 1. Соберём все ссылки на странице
	let links = document.querySelectorAll("a");
	
	// 2. Обойдём каждую
	links.forEach(function (link) {
	
		// 3. Если в ссылке есть хэш (обозначение id на странице - **#block3**)
	  if (link.hash !== "") {
	  
	    // 4. То добавляем к этой ссылке плавный скролл
	    link.addEventListener("click", function (e) {
	    
	      // 5. Предотвращаем поведение по умолчанию (без скролла)
	      e.preventDefault();
	
				// 6. Скроллим к элементу по селектору в который кладём хэш ссылки который соответствует селектору блока по id
	      scrollSmoothlyToPosition({
	        selector: link.hash, 
	      });
	    });
	  }
	});

Надеюсь данная статья о плавном скролле к любому элементу на странице была вам полезна

Если у вас остались вопросы пожалуйста пишите по контактам

И мы разберём более подробно как пользоваться скриптом плавной прокрутки к любому элементу на странице.

Код из статьи хранится в GitHub репозитории

Видео обзор статьи

[[youtube id="ZZ7cNPjKFZU"]]

Сам код функции плавного скролла к любой точке

[[code code="https://gist.githubusercontent.com/artemsites/860cfcd079b1f42cace732c31b5e3a29/raw/scrollSmoothlyToPosition.js"]]

/**
* @title Scroll smoothly to position | Плавная прокрутка к положению
*
* @version 2.2 - 19.09.2023
* @gist https://gist.github.com/artemijeka/860cfcd079b1f42cace732c31b5e3a29
*
* @param {Node} params.el - node
* @param {String} params.selector - '.box'
* @param {String} params.mode - 'bottom'
* @param {Number} params.y - скрол к определённому пикселю - перебивает скрол к селектору или элементу
* @param {Number|String } params.offsetTop - добавочный скрол,
* если установлено число то это значение в px
* если указывается строка то можно применить rem: "5rem" при условии что у :root или html установлен font-size
**/
// Если надо экспортировать скрипт как модуль:
export function scrollSmoothlyToPosition(params) {
// Если нужно просто объявить функцию:
// function scrollSmoothlyToPosition(params) {
params.selector = params.selector || false;
params.offsetTop = params.offsetTop || 0;
let isYScroll = typeof params.y === 'number'
let el = null;
let posOfTop;
if (params.selector) {
el = document.querySelector(params.selector);
}
else if (params.el) {
el = params.el
}
if (isYScroll) {
posOfTop = Number(params.y);
}
else if (!params.mode || params.mode === 'top') {
posOfTop = el.getBoundingClientRect().top;
}
else if (params.mode === 'bottom') {
posOfTop = el.getBoundingClientRect().bottom - window.innerHeight;
}
// Если offsetTop задан в "rem"
if (typeof params.offsetTop === 'string' && params.offsetTop.substring('rem')) {
const elRoot = document.querySelector(':root');
let fs = getComputedStyle(elRoot).getPropertyValue('font-size');
let fsPx = fs.slice(0,-2)// delete 'px'
const countRem = params.offsetTop.slice(0,-3)
params.offsetTop = fsPx * countRem
}
let posOfTopWithOffset = Number(posOfTop - params.offsetTop);
if (isYScroll) {
window.scrollTo({
top: posOfTopWithOffset,
left: 0,
behavior: "smooth",
});
}
else {
window.scrollBy({
top: posOfTopWithOffset,
left: 0,
behavior: "smooth",
});
}
}
<h2>Сам код функции плавного скролла к любой точке</h2>

Usage:

let links = document.querySelectorAll('a');

links.forEach(function(link) {
  if (link.hash!=='') {
    link.addEventListener("click",function(e) {
      e.preventDefault();
      
      new scrollSmoothlyToPosition({ target: {selector: link.hash, position: 'bottom'}, marginTop: -5 });
      // или элемент node
      // new scrollSmoothlyToPosition({ target: {el: elMap, position: 'bottom'}, marginTop: -5 });
      // или marginTop в "rem"
      // marginTop: "10rem",// необходимо чтобы у html (:root) был установлен font-size
    	
    });
  }
});

Bugs:

Нельзя ставить:

html {
    overflow-x: hidden;
}

с ним не работает window.scroll или window.requestAnimationFrame

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment