javascript 滚动到可滚动 div 内的元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28969592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scroll to element inside scrollable div
提问by Hnus
I'm having trouble scrolling to element inside scrollable div.
我在滚动到可滚动 div 内的元素时遇到问题。
My code is quite simple and it mimics exact problem I'm having in my bigger project. When I click on text on the left side it should scroll to element with the same id
on the right side but its not working. It always scrolls to different position and I dont know why.
我的代码非常简单,它模仿了我在更大的项目中遇到的确切问题。当我点击左侧的文本时,它应该滚动到id
右侧相同的元素,但它不起作用。它总是滚动到不同的位置,我不知道为什么。
If you manage to help me can you also provide short explanation what I'm doing wrong. I'm new to jQuery. Thanks
如果您设法帮助我,您还可以简要说明我做错了什么。我是 jQuery 的新手。谢谢
$('.left span').click(function () {
var id = $(this).attr('id');
var element = $('.right span[id="' + id + '"]');
$('.right').animate({ scrollTop: element.offset().top }, 500);
});
回答by apaul
Ok... So you had a few issues with your original code.
好的...所以你的原始代码有一些问题。
First don't duplicate ID's, it is bad practice and it is invalid.
首先不要复制 ID,这是不好的做法,而且是无效的。
The next issue you were having is that you were getting the offset top of your spans. Offsetwill:
您遇到的下一个问题是您获得了跨度的偏移量顶部。抵消将:
Get the current coordinates of the first element, or set the coordinates of every element, in the set of matched elements, relative to the document.
获取第一个元素的当前坐标,或设置匹配元素集中每个元素相对于文档的坐标。
Emphasis on "relative to the document."
强调“相对于文件”。
What you need is position. Positionwill:
你需要的是位置。职位将:
Get the current coordinates of the first element in the set of matched elements, relative to the offset parent.
获取匹配元素集中第一个元素的当前坐标,相对于偏移量 parent。
Emphasis on "relative to the offset parent."
强调“相对于抵消父”。
Now, the main issue was that you were getting the offset after the click. Which sort of worked for your first click, but after that all of the values for offset top were skewed by the new scroll position.
现在,主要问题是您在点击后获得了偏移量。哪种类型适用于您的第一次点击,但之后偏移顶部的所有值都被新的滚动位置倾斜。
To fix this you need to loop through the elements and get their position before you start clicking.
要解决此问题,您需要在开始单击之前遍历元素并获取它们的位置。
Try something like this:
尝试这样的事情:
$('.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>
回答by Doml The-Bread
you should not give the same id twice on a page. give each span in the right for instance:
你不应该在一个页面上两次给出相同的 id。例如,在右侧给出每个跨度:
<span id="1to"></span>
and call the animate function for the element with # + id + to
并调用元素的动画函数# + id + to
var element = $('#'+id+'to');
$('.right').animate({ scrollTop: element.offset().top }, 500);
also you could position your .left "menu" at a fixed position and animate the whole html, body to the certain position.
你也可以将你的 .left “菜单”定位在一个固定的位置,并将整个 html, body 动画到某个位置。
try this fiddle: https://jsfiddle.net/xchqw7uz/
试试这个小提琴:https: //jsfiddle.net/xchqw7uz/
works as you intend it to. and is easier to use, since you dont need so many ids
按您的意愿工作。并且更容易使用,因为你不需要这么多的 id
回答by Alex Padabed
I had trouble scrolling to element inside scrollable div (or other scrollable element) witch may be inside other scrollable element witch may be inside scrollable page or other scrollable element and so on.
我无法滚动到可滚动 div(或其他可滚动元素)内的元素,女巫可能在其他可滚动元素内,女巫可能在可滚动页面或其他可滚动元素内,等等。
I have spent some time and made the following decision:
我花了一些时间并做出以下决定:
utils.scrollVerticallyToElement(jqElement, true);
where jqElementis an element (wrapped in jQuery object) to scroll to, the second argument is a flag that indicates whether to animate scrolling process (trueto animate) and scrollVerticallyToElementis a method of the following object:
其中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));
}
};
This code was tested in Opera, Firefox and IE. And it really works!
此代码已在 Opera、Firefox 和 IE 中进行了测试。它真的有效!
Please, fill free to use utilsobject in your project if you need (you may even rename it if you need).
如果需要,请在您的项目中免费使用utils对象(如果需要,您甚至可以重命名它)。