Как сделать так, чтобы полоса прокрутки перемещалась в точное место

#javascript #jquery #scrollbar

#javascript #jquery #полоса прокрутки

Вопрос:

У меня есть список с полосой прокрутки. Также есть кнопка, при нажатии на которую она перемещается в определенное место #id и полоса прокрутки также перемещается, чтобы сделать этот элемент видимым. Но это не точно. Она перемещается, но не всегда в точное место. Как я могу сделать эту функцию прокрутки точной:

ДЕМОНСТРАЦИЯ http://jsfiddle.net/danials/anpXP/1

Мой код jQuery:

 function next() {
    $(".list li").css("background", "grey");
    goToByScroll(myID);
    $("#"   myID).css("background", "red");
    myID = $("#"   myID).next("li").attr("id");
}

function goToByScroll(id) {
    $('.list').animate({
        scrollTop: $("#"   id).offset().top - $("#"   id).height()
    },
        'slow');
}
  

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

Есть идеи?

Комментарии:

1. Проблема в том, что во всех остальных случаях GoToByScroll , offset().top увеличивается на 1 вместо положенной величины, не уверен почему, но вы можете начать с этого.

2. Этот jsfiddle будет работать. Проблема в том, что при прокрутке экрана смещение элемента изменяется, поскольку он приближается к началу страницы.

Ответ №1:

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

Смещение равно:

 The .offset() method allows us to retrieve the current position of an element
relative to the document.
  

Таким образом, чем дальше по списку вы продвигаетесь, тем меньше offset размер поля.

Что вам нужно сделать, это выяснить, какова высота поле элемента, и выполнить некоторую математику:

 var myID = $(".list").children().first().attr("id");

function next() {
    var li = $("#" myID);
    $(".list li").css("background", "grey");
    var offset = parseInt(li.height()) parseInt(li.css("margin-top"));
    $('.list').animate({scrollTop: offset*(myID-1)},'slow');
    $("#" myID).css("background", "red");
    myID  ;
}
  

Эта скрипка показывает это в действии. Что он делает, так это получает высоту поле текущего элемента, а затем умножает это на то, сколько элементов находится в конце списка.

Это работает только при условии, что все элементы имеют одинаковый размер и что у них есть инкрементные идентификаторы.

Обновить

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

 var myID = $(".list").children().first().attr("id");
var inc = 1;

function next() {
    var li = $("#" myID);
    $(".list li").css("background", "grey");
    var offset = parseInt(li.height()) parseInt(li.css("margin-top"));
    $('.list').animate({scrollTop: offset*(inc-1)},'slow');
    $("#" myID).css("background", "red");
    myID = $("#" myID).next().attr("id");
    inc  ;
}
  

И вот фишка.

Комментарии:

1. Я попытался создать другую версию, которая работает с другими идентификаторами (не инкрементными). Это пока не работает. Не могли бы вы взглянуть на это, пожалуйста? http://jsfiddle.net/danials/anpXP/8

2. @DanielJJ Извините, что мне потребовалось так много времени, чтобы ответить. Я обновил свой ответ версией dynamic ID.