【问题标题】:Scroll to element inside scrollable div滚动到可滚动 div 内的元素
【发布时间】:2021-06-22 18:58:35
【问题描述】:

我无法滚动到可滚动 div 内的元素。

我的代码非常简单,它模仿了我在更大项目中遇到的确切问题。当我单击左侧的文本时,它应该滚动到右侧具有相同 id 的元素,但它不起作用。它总是滚动到不同的位置,我不知道为什么。

如果您设法帮助我,您还可以提供简短的解释我做错了什么。我是 jQuery 的新手。谢谢

JSFiddle

$('.left span').click(function () {
    var id = $(this).attr('id');
    var element = $('.right span[id="' + id + '"]');
    $('.right').animate({ scrollTop: element.offset().top }, 500);
});

【问题讨论】:

  • 不要给元素相同的 id 首先修复它。
  • 这应该是一个模拟我的问题的例子。在我的项目中,我有更聪明的方法来定位这些元素。修复相同的 id 不会改变任何东西。

标签: javascript jquery html css


【解决方案1】:

好的...所以您的原始代码存在一些问题。

首先不要重复ID,这是不好的做法,而且是无效的。

您遇到的下一个问题是您获得了跨度的偏移顶部。 Offset 会:

获取第一个元素的当前坐标,或者设置 匹配元素集合中每个元素的坐标,相对 到文档。

强调“相对于文档”。

你需要的是位置。 Position 会:

获取匹配集合中第一个元素的当前坐标 元素,相对于偏移父级。

强调“相对于偏移父级”。

现在,主要问题是您在点击后获得了偏移量。哪种方法适合您的第一次点击,但之后偏移顶部的所有值都被新的滚动位置歪斜了。

要解决此问题,您需要在开始点击之前遍历元素并获取它们的位置。

试试这样的:

$('.js_scrollTo').each(function () { // for each span
    var target = $(this).text(); // get the text of the span
    var scrollPos = $('#' + target).position().top; // use the text of the span to create an ID and get the top position of that element
    $(this).click(function () { // when you click each span 
        $('.right').animate({ // animate your right div
            scrollTop: scrollPos // to the position of the target 
        }, 400); 
    });
});
.left {
    position: fixed;
    top: 0;
    left: 0;
}
.right {
    position: relative; /* you'll need some position here for jQuery's position to work, otherwise it will be based on the document */
    width: 50%;
    height: 200px;
    overflow: scroll;
    float: right;
    display: block;
}
.right span {
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="left">
    <div class="js_scrollTo">test1</div>
    <div class="js_scrollTo">test2</div>
    <div class="js_scrollTo">test3</div>
</div>
<div class="right">Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ame<span id="test1">test1</span>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ame<span id="test2">test2</span> 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ame<span id="test3">test3</span>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsumRenaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ame<span id="test3">assasdasdasd</span>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit ameContrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem</div>

【讨论】:

  • 我不希望有更好的答案!我学到了很多。感谢您实际阅读我的要求并在回答之前尝试理解我的问题。谢谢
【解决方案2】:

您不应该在一个页面上两次给出相同的 id。 例如,在右侧给出每个跨度:

<span id="1to"></span>

并用# + id + to

为元素调用动画函数
var element = $('#'+id+'to');
$('.right').animate({ scrollTop: element.offset().top }, 500);

你也可以将你的 .left“菜单”定位在一个固定的位置,并为整个 html 和 body 设置动画。

试试这个小提琴: https://jsfiddle.net/xchqw7uz/

按您的意愿工作。 并且更易于使用,因为您不需要这么多 id

【讨论】:

  • 我做了,它的工作原理和以前一样。 jsfiddle.net/ber63qnz/8
  • 请不要修改规则。当我尝试为整个 html 设置动画时,我可以让它工作。我需要它在 div 中工作。
【解决方案3】:

我无法滚动到可滚动 div(或其他可滚动元素)内的元素,可能在其他可滚动元素内,也可能在可滚动页面或其他可滚动元素内,等等。

我花了一些时间做了以下决定:

utils.scrollVerticallyToElement(jqElement, true);

其中 jqElement 是要滚动到的元素(包装在 jQuery 对象中),第二个参数是一个标志,指示是否对滚动过程进行动画处理(true 进行动画处理) scrollVerticallyToElement 是以下对象的方法:

var utils = {
    clearAllSelections: function() {
        //clearing selected text if any
        if (document.selection && document.selection.empty) {
            document.selection.empty();
        } else if (window.getSelection) {
            var sel = window.getSelection();
            sel.removeAllRanges();
        }
    },

    getWindowClientVisibleRect: function () {
        var html = document.documentElement;
        var body = document.body;
        var doc = (html && html.clientWidth) ? html : body;

        var scrollTop = window.pageYOffset || html.scrollTop || body.scrollTop;
        var scrollLeft = window.pageXOffset || html.scrollLeft || body.scrollLeft;

        var clientTop = html.clientTop || body.clientTop || 0;
        var clientLeft = html.clientLeft || body.clientLeft || 0;

        var windowLeft = scrollLeft - clientLeft;
        var windowRight = doc.clientWidth + windowLeft;
        var windowTop = scrollTop - clientTop;
        var windowBottom = doc.clientHeight + windowTop;

        return { left: windowLeft, top: windowTop, right: windowRight, bottom: windowBottom };
    },

    getScrollableElementVisibleRect: function (element) {
        var left = element.scrollLeft - element.clientLeft;
        var top = element.scrollTop - element.clientTop;

        return { left: left, top: top, right: element.clientWidth + left, bottom: element.clientHeight + top };
    },

    getCoordinates: function (element) {
        var top = 0, left = 0;

        if (element.getBoundingClientRect) {
            var windowRect = this.getWindowClientVisibleRect();
            var elementRect = element.getBoundingClientRect();

            top = Math.round(elementRect.top + windowRect.top);
            left = Math.round(elementRect.left + windowRect.left);
        }
        else {
            while (element) {
                top = top + parseInt(element.offsetTop);
                left = left + parseInt(element.offsetLeft);
                element = element.offsetParent;
            }
        }
        return { top: top, left: left, right: left + element.offsetHeight, bottom: top + element.offsetHeight };
    },

    scrollWindowVerticallyToElement: function (element) {
        var elemCoord = this.getCoordinates(element);
        var wndRect = this.getWindowClientVisibleRect();

        if (elemCoord.top < wndRect.top) {
            window.scrollTo(wndRect.left, elemCoord.top);
        }
        else if (elemCoord.bottom > wndRect.bottom) {
            window.scrollBy(0, elemCoord.bottom - wndRect.bottom);
        }
    },

    scrollVerticallyToElement: function (jqElement, useAnimation) {
        if (!jqElement || !jqElement.parent) {
            return;
        }

        var scrollToElement;
        if (!useAnimation) {
            scrollToElement = function(jq, scrollValue) {
                jq.scrollTop(scrollValue);
            };
        }
        else {
            scrollToElement = function (jq, scrollValue) {
                jq.animate({
                    scrollTop: scrollValue
                }, 'fast');
            };
        }

        jqElement.parents().each(function () {
            var jqThis = $(this);

            var top = Math.round(jqElement.position().top);
            var bottom = top + jqElement.innerHeight();

            var parentTop = Math.round(jqThis.position().top);
            var parentBottom = parentTop + jqThis.innerHeight();

            if (top < parentTop && jqThis.scrollTop() > 0) {
                scrollToElement(jqThis, jqThis.scrollTop() - parentTop + top);
            } else if (bottom > parentBottom) {
                scrollToElement(jqThis, jqThis.scrollTop() - parentBottom + bottom);
            }
        });

        this.scrollWindowVerticallyToElement(jqElement.get(0));
    }
};

此代码在 Opera、Firefox 和 IE 中进行了测试。而且真的很管用!

如果需要,请在您的项目中随意填写使用 utils 对象(如果需要,您甚至可以重命名)。

【讨论】:

    【解决方案4】:

    你应该这样尝试:

    document.getElementById("YOUR ID").scrollIntoView({
       behavior: "smooth",
       block: "start",
       inline: "start"
    });
    

    【讨论】:

      猜你喜欢
      • 2019-12-25
      • 2015-03-14
      • 1970-01-01
      • 2022-09-22
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多