在jQuery中滚动到分区内的id

时间:2013-11-26 10:31:20

标签: javascript jquery

我有一个选择对象:

<select class="groups" id="groups">
    <option value="index_birmingham">Birmingham</option>
    ...
    <option value="index_wyboston">Wyboston</option>
</select>

我有一个包含几个标题对象的分区,每个标题对象的id都与select中的值相对应:

<div id="previewer">
    <h3 id="index_birmingham">Birmingham</h3>
    ...
    <h3 id="index_wyboston">Wyboston</h3>
</div>

我正在使用以下jQuery:

$(document).ready(
    $(".groups").change(function() {
        var value = $(this).find("option:selected").attr("value");
        scrollToDivision(value);
    })
);
function scrollToDivision (value) {
    $("#previewer").animate({ scrollTop: $('#' + value).position().top }, 'slow');
}

然而,虽然这对于select中的第一个选择非常有效,但在此之后每次选择都会失败;它随着时间的推移而上下跳跃。

我猜是有某种位置指针需要清除,以便jQuery知道下一步跳转到哪里,但经过几天的搜索后,我找不到任何东西。

我尝试了ScrollTo by Ariel Flesler,但它似乎不支持选择对象。

Here is an example of the weirdness我正在体验。

4 个答案:

答案 0 :(得分:2)

  

“虽然此功能完美”

或者如果您实际将函数传递给.ready() - 您当前将返回值从$('.groups').change()(可能是此时的空jQuery对象)传递给.ready()。但假设这只是一个复制/粘贴错误...

.position()方法返回“元素相对于偏移父元素的当前位置”。在你已经做出选择并滚动包含div之后,h3元素的当前位置将会发生变化,例如,如果你滚动到底部,那么顶部的那些可能会有一个负的垂直位置,因为它们已经消失了顶端。您可以在$('#' + value).position().top语句的帮助下确切地看到console.log()返回的值here

您需要考虑当前的滚动位置。或者只记下所有标题的初始位置:

var positions = {};
$(document).ready(function() {
    var offset = $("#previewer").position().top;
    $("#previewer h3").each(function() {
        positions[this.id] = $(this).position().top - offset;
    });
    $(".groups").change(function() {
        var value = $(this).val();
        scrollToDivision(value);
    })
});
function scrollToDivision (value) {
    $("#previewer").animate({ scrollTop: positions[value] }, 'slow');
}

演示(仅在Chrome中测试):http://jsfiddle.net/Q4pKC/1/

您没有显示您的CSS或明确说明,但我假设您的预览器div已overflow:scroll

更新:与上面相同的JS,但使用OP的标记和CSS:http://jsfiddle.net/B3JXA/2/

答案 1 :(得分:0)

解决方案中唯一的问题是

$("#previewer").animate({ scrollTop: $('#' + value).position().top }, 'slow');

您正试图为#previewer制作动画,您必须动画html, body休息是正常的。 为了更好地理解,请查看此fiddle

<强>更新 由于您只需要滚动priewer div,因此必须使用overflow : auto为其提供一些固定高度。 更新小提琴 here

答案 2 :(得分:0)

我试过这个并且效果很好:

$(document).ready(function() {
    var $previewer = $('#previewer'),
        previewerOffsetTop = $previewer.offset().top;

    $('#groups').change(scrollToDivision);

    function scrollToDivision() {
        // this (groups select) .value gets the value of the option selected
        var $division = $('#'+this.value),
            top = $division.offset().top - previewerOffsetTop;

        $previewer.animate( { scrollTop: top }, 'slow' );
    }
});

编辑:我做了一个jsFiddle:http://jsfiddle.net/B3JXA/

希望这会有所帮助;)

答案 3 :(得分:0)

我认为Jquery 不需要,可以使用anchor标记轻松实现。

<select class="groups" id="groups">
<option value="index_birmingham"><a href="#index_birmingham">Birmingham</a></option>
...
<option value="index_wyboston"><a href="#index_wyboston">Wyboston</a></option>

我认为这可能会有所帮助..