jQuery Accordion - прокрутится ли он до верхней части открытого элемента? - PullRequest
28 голосов
/ 01 сентября 2010

С помощью аккордеонного элемента управления jQuery, как сделать так, чтобы он выделил элемент, который я выбрал, когда он не на экране?

Когда:

  • У меня есть элемент аккордеона с содержанием больше, чем видимое окно
  • Прокручиваю вниз ко второму аккордеонному предмету
  • Я нажимаю на второй элемент аккордеона, чтобы отобразить его
  • Первый вариант аккордеона сворачивается, а второй открывается, но соскользнет с экрана.

Есть ли у аккордеона возможность прокрутки ко второму предмету?

Ответы [ 11 ]

22 голосов
/ 15 октября 2014

у меня работает и проверено,

$( "#accordion" ).accordion({
    heightStyle: "content",
    collapsible: true,
    active: false,
    activate: function( event, ui ) {
        if(!$.isEmptyObject(ui.newHeader.offset())) {
            $('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top }, 'slow');
        }
    }
});

http://jsfiddle.net/ilyasnone/aqw613em/

20 голосов
/ 02 сентября 2010

Вы можете попробовать использовать scrollTo jQuery плагин .Это позволяет вам делать такие вещи:

$.scrollTo('div#foo'); // scroll the browser window so div#foo is in view
$('div#foo').('#bar'); // scroll within div#foo so #bar is in view

Привязать ScrollTo() к событию accordionactivate, например:

$('#youraccordion').bind('accordionactivate', function(event, ui) {
  /* In here, ui.newHeader = the newly active header as a jQ object
              ui.newContent = the newly active content area */
  $( ui.newHeader ).ScrollTo(); // or ui.newContent, if you prefer
});

Когда срабатывает событие accordionactivate?

Срабатывает после активации панели (после завершения анимации).Если аккордеон был ранее свернут, ui.oldHeader и ui.oldPanel будут пустыми объектами jQuery.Если аккордеон рушится, ui.newHeader и ui.newPanel будут пустыми объектами jQuery.

Ссылки: JQuery UI Accordion

11 голосов
/ 05 марта 2012

Поскольку я хочу, чтобы свернуть было правдой, я добавил тест if, чтобы отменить ошибку всех свернутых элементов.Я также не хотел, чтобы заголовок был точно вверху страницы, поэтому я уменьшил местоположение scrollTop на 100:

  $(document).ready(function() {
    $(".ui-accordion").bind("accordionchange", function(event, ui) {
      if ($(ui.newHeader).offset() != null) {
        ui.newHeader, // $ object, activated header
        $("html, body").animate({scrollTop: ($(ui.newHeader).offset().top)-100}, 500);
      }
    });
  });
8 голосов
/ 27 января 2012

Я знаю, что этот вопрос старый, но ничего из вышеперечисленного не сработало для меня. Вот как я это сделал. Значение -50 было на тот случай, если оно появится в веб-приложении для iPad или iPhone, чтобы страница не прокручивалась вверху заголовка аккордеона за строкой состояния.

$('#accordion').accordion({
  collapsible: true,
  autoHeight: false,
  animated: false
});
$('.ui-accordion-header').bind('click',function(){
    theOffset = $(this).offset();
    $(window).scrollTop(theOffset.top - 50);
});
3 голосов
/ 18 декабря 2015

Пожалуйста, обратитесь этот ответ techfoobar

$(function() {
    $("#accordion").accordion({
        autoHeight: false,
        collapsible: true,
        heightStyle: "content",
        active: 0,
        animate: 300 // collapse will take 300ms
    });
    $('#accordion h3').bind('click',function(){
        var self = this;
        setTimeout(function() {
            theOffset = $(self).offset();
            $('body,html').animate({ scrollTop: theOffset.top - 100 });
        }, 310); // ensure the collapse animation is done
    });
});

Это работает для меня с вышеуказанной модификацией.

$("#accordion").accordion({
                    heightStyle: "content",
                    collapsible: true,
                    activate: function (event, ui) {

                        try
                        {
                            var self = this;
                            theOffset = $(self).offset();
                            $('body,html').animate({ scrollTop: theOffset.top - 100 });
                        } catch (e) {
                            alert(e);
                        }
                    }
                }); 
1 голос
/ 26 ноября 2013

Решение от Мартина прекрасно работает.Однако, когда вы добавите этот код, он всегда будет прокручиваться вверх, независимо от того, виден ли ваш аккордеон на странице или нет.

Если вы хотите прокручивать вверх, только когда содержание аккордеона больше видимогозатем введите следующий код:

$(document).ready(function() {

    function isScrolledIntoView(elem)
    {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();

        var elemTop = $(elem).offset().top;
        var elemBottom = elemTop + $(elem).height();

        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }

    $(".accordion-inner").bind("accordionchange", function(event, ui) {
      if ($(ui.newHeader).offset() != null) {
        if (!isScrolledIntoView(ui.newHeader))
        {
            ui.newHeader, // $ object, activated header
            $("html, body").animate({scrollTop: ($(ui.newHeader).offset().top)-100}, 500);
        }
      }
    });
  });
1 голос
/ 02 ноября 2011

У меня были проблемы с привязкой события, когда вы использовали функцию «Аккордеон», чтобы закрыть функцию. Добавление только одного оператора if исправило его.

$('#accordion').bind('accordionchange', function(event, ui) {
    if(!ui.newHeader.length) { return; }
  /* In here, ui.newHeader = the newly active header as a jQ object
              ui.newContent = the newly active content area */
  $.scrollTo( ui.newHeader ); // or ui.newContent, if you prefer
});  
0 голосов
/ 06 июня 2016

Нет необходимости в scrollTo для плагина, вы можете сделать это:

$('.accordionNormalitzador').bind('accordionactivate', function(event, ui) {
        $( ui.newHeader )[0].scrollIntoView(); 
    });
0 голосов
/ 26 ноября 2013

Просто используйте эту функцию для window.load

$(function() {
    var icons = {
    header: "ui-icon-circle-plus",
    activeHeader: "ui-icon-circle-minus"
    };
    $( "#accordion" ).accordion({
    icons: icons, autoHeight: false, collapsible: true, active: false,
    activate: function(event, ui){
        var scrollTop = $(".accordion").scrollTop();
        var top = $(ui.newHeader).offset().top;
     //do magic to scroll the user to the correct location

     //works in IE, firefox chrome and safari
        $("html,body").animate({ scrollTop: scrollTop + top -35 }, "fast");
       },



    });

    });

perfectl wokring

0 голосов
/ 28 июня 2011

Я реализовал первый ответ и мне больше понравился этот вариант, потому что это одна функция для всех аккордеонных панелей. Но я заметил, что все время получаю сообщение об ошибке при попытке (повторного) закрытия той же панели аккордеона - это останавливает сценарий в этой строке в плагине ScrollTo:

attr[key] = val.slice && val.slice(-1) == '%' ? 

val возвращал пустое значение, поэтому я нашел здесь другой ответ, который сказал, что нужно проверить, не пусто ли, и добавил / заменил эту функцию - теперь она работает.

else{
var val = targ[pos];
// Handle percentage values
if(val) {
    attr[key] = val.slice && val.slice(-1) == '%' ?
    parseFloat(val) / 100 * max
    : val;
    }
}
...