Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Как задать порядок выполнения событий (анимаций) (https://javascript.ru/forum/jquery/75179-kak-zadat-poryadok-vypolneniya-sobytijj-animacijj.html)

RedPython 10.09.2018 16:39

Как задать порядок выполнения событий (анимаций)
 
Доброго времени суток!

Столкнулся с такой проблемой. Делаю скрипт к html-шаблону. Есть фрагмент в коде <div id="target" ...>. Необходимо сделать плавный скроллинг к нему по клику на ссылку <a href="#target">.

Проблема в том, что на этом клике висит ещё одно событие, которое скрывает некоторые элементы со страницы. Из-за этого положение координат целевого элемента смещается.

Каким образом добавить мой скрипт в очередь выполнения функций(событий), чтобы получить координаты для скроллинга после того как ранее установленные скрипты закончат скрытие элементов?

<!DOCTYPE HTML>
<html lang="ru-RU">
<head><title></title><meta charset="UTF-8"></head>
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript">
/* Этот фрагмент нельзя менять */
$(function(){
  $('a[href^="#"]').click( function() {
   $('#hideme').hide(1000);
  });
});

/* Далее всё что угодно */
$(function(){
  $('a[href^="#"]').click( function() {
    var sc = $(this).attr("href");
    var dn = $(sc).offset().top;
    // sc - в переменную заносим информацию о том, к какому блоку надо перейти
    // dn - определяем положение блока на странице

    alert('Положение блока на странице по вертикали '+dn+' (Ошибочное)');
   
    $('html, body').animate({scrollTop: dn}, 1000);
    // 1000 скорость перехода в миллисекундах 
    
    $('a').remove();
  });
});
</script>

<a href="#target">Перейти к фрагменту</a>
<div id="hideme" style="display:block;width: 100%; height: 500px; background: green;"></div>
<div id="other" style="display:block;width: 100%; height: 1200px; background: yellow;"></div>
<div id="target" style="display:block;width: 100%; height: 300px; background: red;"></div>
<div id="other"  style="display:block;width: 100%; height: 700px; background: blue;"></div>
<div id="other"  style="display:block;width: 100%; height: 700px; background: magenta;"></div>

</body>
</html>

laimas 10.09.2018 16:43

RedPython,
опишите в одном обработчике, поставив в очередь анимации или hide(1000, function() { анимация прокрутки})

RedPython 10.09.2018 16:56

laimas, при этом варианте прийдётся править фрагмент в большой js-библиотеке, которую писал сторонний разработчик.

Из костылей можно использовать setTimeout, но на реальной странице выглядит мягко говоря коряво...
$(function(){
     $('a[href^="#"]').click( function() {
       var sc = $(this).attr("href");
       setTimeout(function ()
       {
       
       var dn = $(sc).offset().top;
       // sc - в переменную заносим информацию о том, к какому блоку надо перейти
       // dn - определяем положение блока на странице
      
       $('html, body').animate({scrollTop: dn}, 1000);
       // 1000 скорость перехода в миллисекундах 
       }, 1000);
       
       $('a').remove();
     });
   });

laimas 10.09.2018 17:06

RedPython,
а чего там править, вы же нашли эти два фрагмента, сложно перенести один в другой?

рони 10.09.2018 17:17

плавный переход к блоку
 
RedPython,
<!DOCTYPE HTML>
<html lang="ru-RU">
<head><title></title><meta charset="UTF-8"></head>
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript">
/* Этот фрагмент нельзя менять */
$(function(){
  $('a[href^="#"]').click( function(event) {
   event.preventDefault();
   var id = this.hash;
   $(this).remove();
   $('#hideme').slideUp(1000, function() {
   var dn = $(id).offset().top;
   $('html, body').animate({scrollTop: dn}, 1000);
});
  });
});


</script>

<a href="#target">Перейти к фрагменту</a>
<div id="hideme" style="display:block;width: 100%; height: 500px; background: green;"></div>
<div id="other" style="display:block;width: 100%; height: 1200px; background: yellow;"></div>
<div id="target" style="display:block;width: 100%; height: 300px; background: red;"></div>
<div id="other"  style="display:block;width: 100%; height: 700px; background: blue;"></div>
<div id="other"  style="display:block;width: 100%; height: 700px; background: magenta;"></div>

</body>
</html>

Aetae 10.09.2018 17:19

"Нельзя менять" - это крайне нездоровая хрень.

Из костылей можно сделать так:
/* Далее всё что угодно */
$(function(){
  $('a[href^="#"]')
    .off('click') // отменяем поставленные ранее кем-то обработчики
    .click(function(){ // ставим заново общий
      var sc = $(this).attr("href");
      $('#hideme').hide(1000, function(){
        var dn = $(sc).offset().top;
        // sc - в переменную заносим информацию о том, к какому блоку надо перейти
        // dn - определяем положение блока на странице

        alert('Положение блока на странице по вертикали '+dn+' (Ошибочное)');

        $('html, body').animate({scrollTop: dn}, 1000);
        // 1000 скорость перехода в миллисекундах

        $('a').remove(); // удаляем все ссылки на страницые, это точно нужно?
      });
    });
});


Второй вариант - поменять метод hide jquery добавив какую-нить отсебятину, например:
$.fn.hide = function(hide){
  return function(speed, callback) {
    this.trigger('hide');
    return hide.apply(this, arguments);
  }
}($.fn.hide);
и соответственно на on('hide') повесить всё нужное.

RedPython 10.09.2018 19:19

Цитата:

Сообщение от laimas (Сообщение 494365)
RedPython,
а чего там править, вы же нашли эти два фрагмента, сложно перенести один в другой?

Потому, что это шаблон построен на функционале аккордион (спойлер) из bootstrap + всякие "плюшки"... был сделан примерный код, чтобы не перебирать все 100500 скриптов с html-вёрсткой

рони 10.09.2018 19:44

Цитата:

Сообщение от RedPython
(спойлер) из bootstrap

http://bootstrap-doc.ru/v4/component...pse.php#events
... возможно так
$(function(){
   var id;
   $('#hideme').on('hidden.bs.collapse', function() {
   var dn = $(id).offset().top;
   id && $('html, body').animate({scrollTop: dn}, 1000);
   });
  $('a[href^="#"]').click( function(event) {
   var id = this.hash;
  });
});

RedPython 10.09.2018 19:46

Цитата:

Сообщение от Aetae (Сообщение 494367)
"Нельзя менять" - это крайне нездоровая хрень.

Всё нормально там. Из костылей можно setTimeout использовать, но из-за необходимости допиливания ещё нескольких функций, этот велосипед быстро развалится.

Там на самом деле большая лента из секций, которая представляют собой спойлеры. Разные скрипты, которые обрабатывают в каждой раскрытой секции чекбоксы и прочие меню. После заполнения пользователем секции отрабатывают скрипты, которые проводят валидацию и перенаправляют в нужную секцию (с точки зрения приложения). Вдобавок ко всему ещё внутри секции попадает контент из ajax. Поэтому знать размер секции нельзя знать наверняка.

Дело в том, что из-за того что секции раскрываются то там то здесь (ну на самом деле только предыдущая или следующая). То пользователя сильно напрягает, почему он вдруг застрял с заполнением анкеты.

Код в теме, чисто демонстрационный. Главный вопрос в том, как управлять очередью выполнения анимации событий.

За лазанье в код фреймворков по ушам надают. Так как регламент работ запрещает менять стандартную логику библиотек. Потому, что это приведёт к запаркам у других разработчиков.


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