根据按钮单击移动到特定div

时间:2015-08-19 11:35:25

标签: javascript jquery html css scroll

我试图根据prev和next按钮移动div(这里是问题编号)。因此,所选问题始终在屏幕上可见。

以下是演示:http://jsfiddle.net/arunslb123/trxe4n3u/12/

屏幕:enter image description here

点击并提问号码,然后点击上一个或下一个按钮以了解我的问题。

我的代码:

$("#next")
.click(function () {
    $(".c.current-question")
        .each(function () {
            var divIdx = $(this)
                .attr('id');
            var scrollTo = $('#' + divIdx)
                .position()
                .left;
            $("#scrollquestion")
                .animate({
                    'scrollLeft': scrollTo
                }, 800);
        });
});

$("#prev")
.click(function () {
    $(".c.current-question")
        .each(function () {
            var divIdx = $(this)
                .attr('id');
            var scrollTo = $('#' + divIdx)
                .position()
                .left;
            $("#scrollquestion")
                .animate({
                    'scrollLeft': -scrollTo
                }, 800);
        });
});

1 个答案:

答案 0 :(得分:2)

使用scrollLeft有点棘手。我根据定位对您的用例进行了一次小重做,然后根据容器的left移动它。棘手的部分是在滚动到最右边时可靠地计算负位置。此外,需要考虑宽度和边距。

检查以下代码段



var $wrap = $("#numWrap"), $strip = $("#strip"), 
    $leftArrow = $(".wrapper > .arrows").first(), 
    wrapWidth = $wrap.width() + $leftArrow.width(), 
    margin = 10;
    
fill(20); select($(".numberItem").first());

$strip.on("click", ".numberItem", function() { select($(this)); });

function select($elem) {
    $(".numberItem").removeClass("selected");
    $elem.addClass("visited").addClass("selected");
    focus($elem[0]);    
}

function focus(elem) {
    var stripPos = $strip.position(), 
        numPos = $(elem).offset(), 
        elemWidth = $(elem).width() + margin, 
        numRight = numPos.left + elemWidth;
    
    if (numRight > wrapWidth) {
        $strip.css({"left": stripPos.left - elemWidth}); 
    }
    if (numPos.left < (margin + $leftArrow.width()))  {
        $strip.css({"left": stripPos.left + elemWidth}); 
    }
}

$(".wrapper").on("click", "a.arrow", function() {
    var stripPos = $strip.position();
    if (this.id == "lft") {
        $strip.css({"left": stripPos.left + (wrapWidth / 2)}); 
    } else {
        $strip.css({"left": stripPos.left - (wrapWidth / 2)});
    }
});

$(".controls").on("click", "a.arrow", function() {
    var $sel = $(".selected"), numPos, $sel, elemWidth; 
    	$elem = $sel.length > 0 ? $sel.first() : $(".numberItem").first();
    if (this.id == "lft") {
        $sel = $elem.prev().length > 0 ? $elem.prev() : $elem;
        select($sel); 
    } else {
        $sel = $elem.next().length > 0 ? $elem.next() : $elem;
        select($sel);
    }
    numPos = $sel.offset(); elemWidth = $sel.width() + margin;
    numRight = numPos.left + elemWidth;
    if (numPos.left > wrapWidth) {
        $strip.css({"left": -($sel.text()) * $sel.width() });
    }
    if (numRight < 0) {
        $strip.css({"left": +($sel.text()) * $sel.width() });
    }
});

function fill(num){
    for (var i = 1; i <= num; i++) {
        var $d = $("<a href='#' class='numberItem'>" + i + "</a>");
        $strip.append($d);
    }
}
&#13;
* { box-sizing: border-box; padding: 0; margin: 0; font-family: sans-serif; }
div.wrapper { 
    background-color: #ddd; width: 100vw; height: 64px; 
    clear: both; overflow: hidden; margin-top: 16px;
}
div.arrows { 
    float: left; width: 10%; min-width: 24px; height: 64px; line-height: 64px;
    text-align: center; vertical-align: middle; overflow: hidden;
}
div.numWrap { 
    float: left; height: 64px; line-height: 64px;
    width: 80%; vertical-align: middle; 
    overflow: hidden; position: relative;
}
div.strip { 
    position: absolute; left: 0px;
    width: auto; white-space: nowrap; 
    transition: left 1s;
}
a.numberItem { 
    display: inline-block; text-align: center; margin: 0px 8px;
    background-color: #fff; border-radius: 50%; width: 48px; height: 48px; 
    font-size: 1.2em; line-height: 48px; text-decoration: none;
}
a.numberItem.visited { background-color: #fff; color: #000; border: 2px solid #01aebc; }
a.numberItem.selected { background-color: #01aebc; color: #fff; }
div.controls { clear: both; }
div.controls > div.arrows { width: auto; margin: 0 12px; }
a, a:focus, a:active, a:link, a:visited { 
    display: inline-block; 
    text-decoration: none; font-weight: 600; 
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
    <div class="arrows">
        <a id="lft" class="arrow" href="#">&#x3008;</a>
    </div>
    <div id="numWrap" class="numWrap">
        <div id="strip" class="strip"></div>
    </div>
    <div class="arrows">
        <a id="rgt" class="arrow" href="#">&#x3009;</a>
    </div>
</div>
<div class="controls">
    <div class="arrows">
        <a id="lft" class="arrow" href="#">&#x3008;&nbsp; Previous</a>
    </div>
    <div class="arrows">
        <a id="rgt" class="arrow" href="#">Next &nbsp;&#x3009;</a>
    </div>    
<div>
&#13;
&#13;
&#13;

<强>解释

  1. 在数字容器上使用absolute定位,数字容器嵌套以获得100%宽度。
  2. 标记:

    <div class="wrapper">
        <div class="arrows"><a id="lft" class="arrow" href="#">&#x3008;</a></div>
        <div id="numWrap" class="numWrap">
            <div id="strip" class="strip"></div> <!-- nesting here -->
        </div>
        <div class="arrows"><a id="rgt" class="arrow" href="#">&#x3009;</a></div>
    </div>
    

    CSS:

    div.wrapper { 
        background-color: #ddd; width: 100vw; height: 64px; 
        clear: both; overflow: hidden; margin-top: 16px;
    }
    div.arrows { 
        float: left; width: 10%; min-width: 24px; height: 64px; line-height: 64px;
        text-align: center; vertical-align: middle; overflow: hidden;
    }
    div.numWrap { 
        float: left; height: 64px; line-height: 64px;
        width: 80%; vertical-align: middle; 
        overflow: hidden; position: relative; /* relatively positioned */
    }
    div.strip { 
        position: absolute; left: 0px;        /* absolutely positioned */
        width: auto; white-space: nowrap; 
        transition: left 1s;                  /* instead of jquery animate */
    }
    

    通过这种结构,我们现在可以使用left来控制滚动。

    1. 对于部分遮挡的数字,请尝试轻轻地聚焦(轻推视图)一个部分遮挡的数字。这可以通过检查相对于父级的position并为其添加宽度/边距并且还考虑左箭头的宽度(它可能会窥视)来完成。
    2. 使用Javascript:

      function focus(elem) {
          var stripPos = $strip.position(), 
              numPos = $(elem).offset(), 
              elemWidth = $(elem).width() + margin, 
              numRight = numPos.left + elemWidth;
      
          // if it is towards right side, nudge it back inside
          if (numRight > wrapWidth) {
              $strip.css({"left": stripPos.left - elemWidth}); 
          } 
          // if it is towards left side, nudge it back inside
          if (numPos.left < (margin + $leftArrow.width()))  {
              $strip.css({"left": stripPos.left + elemWidth}); 
          } 
      }
      
      1. 一旦用户滚动列表太远,然后尝试单击上一个/下一个按钮来选择一个问题,那么我们需要将整个容器移动到所选的数字。我们可以通过将问题编号与元素宽度相乘,然后将left更改为正数(如果朝向右)或更改为负数( if if left )来轻松完成此操作)。
      2. 使用Javascript:

        // if left of element is more than the width of parent
        if (numPos.left > wrapWidth) {
            $strip.css({"left": -($sel.text()) * $sel.width() });
        }
        // if right of element is less than 0 i.e. starting position
        if (numRight < 0) {
            $strip.css({"left": +($sel.text()) * $sel.width() });
        }
        

        这是一个小提琴:http://jsfiddle.net/abhitalks/aw166qhx/

        您需要进一步调整它以适应您的用例,但您明白了。