冻结jQuery列表上的滚动,同时调整列表顶部的列表元素的大小

时间:2013-12-24 08:32:36

标签: javascript jquery css list scroll

this fiddle中,我使用点击处理程序实现了一个列表。单击列表中的元素时,会向其添加“.selected”类,从而更改其高度。当随后单击其他列表元素时,将从先前单击的元素中删除“.selected”类(从而将其恢复到其原始高度),并将“.selected”类添加到新单击的元素中,以更改其高度。

fiddle中注意,当单击列表元素并且列表中的“.selected”元素位于其下方时,单击的元素在展开时保持完全静止,并且先前选择的元素收缩。但是,当单击列表元素并且列表中的“.selected”元素位于其上方时,列表会向上滚动以补偿收缩元素,从而导致新的“.selected”列表元素向上移动一点。我想要一些机制来平滑地缓解这种行为,因此“。selected”列表元素在这种情况下仍保持完美。

HTML:

<ul>
 <li>1</li>
 <li>2</li>
 <li>3</li>
 <li>4</li>
 <li>5</li>
 <li>6</li>
 <li>7</li>
 <li>8</li>
 <li>9</li>
 <li>10</li>
</ul>

JS:

$(document).ready(function () {
    $("li").click(function () {
        $(".selected").removeClass("selected");
        $(this).addClass("selected");
    });
});

的CSS:

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
}

.selected{
    height:300px;
    background:red;
}

5 个答案:

答案 0 :(得分:2)

因为我看到你需要偏移滚动所以新选择的元素保留在视图中。我建议使用以下代码:

$(document).ready(function () {
    $("li").click(function(){

        var $this = $(this),
            pos = $this.offset().top,
            $doc = $(document);

        $(".selected").removeClass("selected");
        $this.addClass("selected");

        $doc.scrollTop($doc.scrollTop() + $this.offset().top - pos);
        console.log($this.offset().top - pos);
    });
});

DEMO

答案 1 :(得分:0)

到目前为止:

  

我想要一些机制来顺利缓解这种行为   “。selected”列表元素仍保持完美   情况。

我不知道你怎么能保持它“完全静止”,当另一个项目收缩时,如果列表的其余部分以某种方式“固定”到位,则两者之间会有巨大的差距。物品......

有几个想法......这个css:

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
    transition: height 2s;
    -webkit-transition: height 2s;
}

.selected{
    height:300px;
    background:red;
    transition: height 2s;
    -webkit-transition: height 2s;
}

使眼睛易于跟随的不那么刺耳的过渡。

要真正得到你所要求的,“完全静止”,你可以做一些像这样的事情:

    $(document).ready(function () {
$("li").click(function(){
    $(".previouslySelected").removeClass("previouslySelected"); $(".selected").removeClass("selected").addClass("previouslySelected");
    $(this).addClass("selected");
});
    });

CSS

.previouslySelected {
    height:100px;
    margin-bottom:200px;
}

正如你所看到的那样,保持下面的“跳跃”...因为我认为这是一种狡猾的方法我没有花时间检查新点击的那个是否高于或低于之前选择的那个等。 ..但是添加起来是微不足道的。有意义吗?

答案 2 :(得分:0)

为什么不简单地向<li>元素添加转换?
这样,您可以在选定/未选定状态之间获得平滑效果。

li{
    width:100%;
    border-top:solid black 1px;
    height:100px;
    background:green;
    -webkit-transition: all .5s ease-in-out;
    -moz-transition: all .5s ease-in-out;
    -o-transition: all .5s ease-in-out;
    transition: all .5s ease-in-out;
}

.selected{
    height:300px;
    background:red;
}

DEMO

答案 3 :(得分:0)

您可以尝试以下jQuery内容

 $(document).ready(function() {
   $("li").click(function() {

     var selectItemTop = $(this).position().top;

     var windowTop = $(window).scrollTop();
     var selectItemHeight = $(".selected").height();
     var selectionTop = $('li').hasClass('selected') ? $(".selected").position().top : 0;
     console.log(selectionTop);
     if (selectionTop < selectItemTop) {
       selectItemTop = selectItemTop - windowTop;
       $(window).scrollTop(windowTop + selectItemTop - selectItemHeight);

     }


     $(".selected").removeClass("selected");

     $(this).addClass("selected");


   });

我几乎设法满足你的要求。

您可以通过此链接 fiddle

测试示例

答案 4 :(得分:0)

$(document).ready(function () {
$("li").click(function(){    
    var selectItemTop = $(this).position().top;    
    var windowTop = $(window).scrollTop();
    var selectItemHeight = $(".selected").height();
    var selectionTop =  $('li').hasClass('selected') ? $(".selected").position().top : 0;
    console.log(selectionTop);    
    if(selectionTop < selectItemTop){
      selectItemTop = selectItemTop-windowTop;
            $(window).scrollTop(windowTop+selectItemTop-selectItemHeight);        
    }
    $(".selected").removeClass("selected");
    $(this).addClass("selected");    
      });

    });