Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Плавный Скроллинг дока: JS vs Jquery vs Jquery + Плагины (https://javascript.ru/forum/events/34277-plavnyjj-skrolling-doka-js-vs-jquery-vs-jquery-plaginy.html)

SegaMega 27.12.2012 12:19

Плавный Скроллинг дока: JS vs Jquery vs Jquery + Плагины
 
Маленький оффтоп ))

Добрый времени суток и с наступающим НГ всех, яваскриптеры :) Делал я как-то сайт (юзал вовсю мощь Jquery) и вот дело дошло до модной нынче кнопочки "вверх" с плавным скроллингом документа. Ну, думаю, одна строка кода и всё :write: Набрал для надёжности в Яндексе "плавный скроллинг jquery" :blink: дык там половина ссылок на плагины типа scrollTo (даже платные! например, http://pagescroller.com/)
Думаю... прикольно... неужто великая и могучая библиотека нуждается в целом плагине для такой простой задачи ( которая, кстати даже и без jquery прекрасно решается ИМХО) !? в общем поискал ещё маленько и нашёл вот этот грамотный пост: http://habrahabr.ru/post/120960/ (другие тоже были, но это же Хабр)))

Его мы тоже разбирать не будем - там довольно всё чётко написано по этой теме (я только возьму оттуда пару строк кода на Jquery для примера и вопросов ниже)

Прошёл год...
И вот делаю очередной сайт (одностраничный), но уже без Jquery, и в этот раз тоже захотелось сделать плавный переход к закладкам контента... тут уже посложнее дело оказалось (( почитал http://learn.javascript.ru/js-animation , http://javascript.ru/blog/Andrej-Par...cii-JavaScript ) попробовал сам - ни-ни... что-то не задалось!?

Отсюда первый вопрос экспертам и знатокам:
Как реализовать плавный скролл по документу с помощью библиотеки http://learn.javascript.ru/files/tutorial/js/animate.js !?

Ну, раз не получилось самому - продолжаю поиск по нэту, нахожу:
http://itfound.ru/12-plavnaya-prokrutka-do-yakora.html
http://forum.htmlbook.ru/index.php?showtopic=8571

Отлично :dance: то, что нужно!!! Немного модернизирую код (убираю лишние проверки, переменные, горизонтальную прокрутку и пр) и получаю:

HTML-разметка
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Как докатиться вниз/вверх?!</title>
<!-- библиотека jquery нужна ТОЛЬКО для ссылки, прокручивающей скролл в начало дока !!!-->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<!-- здесь реализованы функции плавного скроллинга с помощью jquery и без -->
<script type="text/javascript" src="scroll.js" ></script>
</head>

<body>
<a name="goup"></a>
<a href="#godown" id="down" onclick="return anchorScroller(this, 800);">Плывём вниз без jquery</a>

<div style="display:block;height:2000px;width:auto;background:#99CC99;">Создаём высоту доку :))</div>

<a name="godown"></a>
<a href="#goup" id="up">Плывём вверх с jquery</a>
</body>
</html>


содержание scroll.js - к сожалению нет времени прокомментировать ф-ю anchorScroller ((
// ф-я для плавного скролла дока - возвращает 1 если баг, и 0 - если всё путём
function anchorScroller(el, duration) {

    if (this.criticalSection) {
    return false;
    }

    /* вот этот красивый код работает ВЕЗДЕ, кроме IE 7 (6 - даже не рассматриваю)
    try {
        if (el.hasAttribute('href'))
        var address = el.getAttribute('href').replace('#','');
        else
        return true;
    }
    catch(err) {
        alert(err); // здесь вылетает ошибка... это всё потому что IE 7 не поддерживает hasAttribute(), а getAttribute('href') вернёт нам протокол+хост+скрипт... и только потом +хэш... вот урод ((
    }*/

    var address = el.href.split('#'); // короче по старинке (special for IE 7, если его ещё кто-то юзает)
    if (address.length < 2) // получаем в массиве элементы el.href, разделённые знаком #
    return true; // если там всего 1 элемент, значит какая-то левая ссылка - переходим по ней

    address = address[address.length-1]; // название нашей закладки - в последнем элементе массива если ссылка вида #anchor или как в IE 7: http://site.com/index.php?id=404#anchor

    el = null;

    for (var i=0; i<document.anchors.length; i++)
    if (document.anchors[i].name == address) {
        el = document.anchors[i];
        break;
    }

    if (el === 0)
    return true;

    stopY = 0;
    do stopY += el.offsetTop;
    while (el = el.offsetParent);

    startY = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
    stopY = stopY - startY;

    if (stopY == 0)
    return false;

    this.criticalSection = true;
    duration = duration||500;

    var date = new Date();
    start = date.getTime();
    timer = setInterval(function () {
        var date = new Date();
        var X = (date.getTime() - start) / duration;
        if (X > 1) X = 1;

        var Y = ((-Math.cos(X*Math.PI)/2) + 0.5);

        cY = Math.round(startY + stopY*Y);

        document.documentElement.scrollTop = cY;
        document.body.scrollTop = cY;

        if (X == 1) {
        clearInterval( timer);
        this.criticalSection = false;
        }
    }, 13);

return false;
}

$(function() {

    $("a#up").click(function(e) {
    e.preventDefault(); // отмена перехода по умолчанию

    var newScroll=$("a[name='goup']").offset().top;  // высота от верхнего края окна до этой ссылки
    $('body,html').animate({scrollTop: newScroll}, 800);  // плавный скролл наверх

    //$('body,html').animate({scrollTop: 0}, 800); // или одной стройкой 

    });

});


Отсюда второй вопрос:
Зачем нужны плагины для плавного скролла если всё и так можно красиво, быстро, легко и кросс-браузерно реализовать!? Мне кажется, для большинства задач этого хватит или я что-то недопонимаю?!:blink:

И ещё:
я где-то в комментах к статье на этом сайте читал, что якобы технология закладок c атрибутом name устарела, и желательно теперь юзать ID... можете плз уточнить почему...

P.S. демка без jquery: здесь
Функцию anchorScroller можно ещё при желании оптимизировать и упростить ))

SegaMega 27.12.2012 13:02

Опаньки ((:-? :-/ ИЕ 7 тест не прошёл (( пока ищу где собака зарыта... видно что-то намутил ))))
вот эта демка работает везде (даже в ИЕ 6 )


Часовой пояс GMT +3, время: 14:47.