Javascript 如果元素不可见则滚动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6215779/
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 if element is not visible
提问by macpak
how to determine, using jquery, if the element is visible on the current page view. I'd like to add a comment functionality, which works like in facebook, where you only scroll to element if it's not currently visible. By visible, I mean that it is not in the current page view, but you can scroll to the element.
如何使用 jquery 确定元素在当前页面视图中是否可见。我想添加一个评论功能,它的工作方式类似于 Facebook,如果元素当前不可见,您只能滚动到元素。可见,我的意思是它不在当前页面视图中,但您可以滚动到该元素。
回答by Loktar
Basically you just check the position of the element to see if its within the windows viewport.
基本上,您只需检查元素的位置,看看它是否在 Windows 视口内。
function checkIfInView(element){
var offset = element.offset().top - $(window).scrollTop();
if(offset > window.innerHeight){
// Not in view so scroll to it
$('html,body').animate({scrollTop: offset}, 1000);
return false;
}
return true;
}
回答by digitalPBK
Improving Loktar's answer, fixing the following:
改进 Loktar 的回答,修复以下问题:
- Scroll up
Scroll to a display:none element (like hidden div's etc)
function scrollToView(element){ var offset = element.offset().top; if(!element.is(":visible")) { element.css({"visibility":"hidden"}).show(); var offset = element.offset().top; element.css({"visibility":"", "display":""}); } var visible_area_start = $(window).scrollTop(); var visible_area_end = visible_area_start + window.innerHeight; if(offset < visible_area_start || offset > visible_area_end){ // Not in view so scroll to it $('html,body').animate({scrollTop: offset - window.innerHeight/3}, 1000); return false; } return true; }
- 向上滚动
滚动到 display:none 元素(如隐藏的 div 等)
function scrollToView(element){ var offset = element.offset().top; if(!element.is(":visible")) { element.css({"visibility":"hidden"}).show(); var offset = element.offset().top; element.css({"visibility":"", "display":""}); } var visible_area_start = $(window).scrollTop(); var visible_area_end = visible_area_start + window.innerHeight; if(offset < visible_area_start || offset > visible_area_end){ // Not in view so scroll to it $('html,body').animate({scrollTop: offset - window.innerHeight/3}, 1000); return false; } return true; }
回答by user1806949
After trying all these solutions and many more besides, none of them satisfied my requirement for running old web portal software (10 years old) inside IE11 (in some compatibility mode). They all failed to correctly determine if the element was visible. However I found this solution. I hope it helps.
在尝试了所有这些解决方案以及更多其他解决方案之后,没有一个能够满足我在 IE11 中(在某些兼容模式下)运行旧 Web 门户软件(10 年)的要求。他们都未能正确确定元素是否可见。但是我找到了这个解决方案。我希望它有帮助。
function scrollIntoViewIfOutOfView(el) {
var topOfPage = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var heightOfPage = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var elY = 0;
var elH = 0;
if (document.layers) { // NS4
elY = el.y;
elH = el.height;
}
else {
for(var p=el; p&&p.tagName!='BODY'; p=p.offsetParent){
elY += p.offsetTop;
}
elH = el.offsetHeight;
}
if ((topOfPage + heightOfPage) < (elY + elH)) {
el.scrollIntoView(false);
}
else if (elY < topOfPage) {
el.scrollIntoView(true);
}
}
回答by jaggedcow
I made a slightly more generic version of digitalPBK's answer that minimally scrolls an element contained within a div or some other container (including the body). You can pass DOM elements or selectors to the function, as long as the element is somehow contained within the parent.
我制作了一个稍微更通用的 digitalPBK 答案,它最低限度地滚动包含在 div 或其他一些容器(包括主体)中的元素。您可以将 DOM 元素或选择器传递给函数,只要该元素以某种方式包含在父元素中。
function scrollToView(element, parent) {
element = $(element);
parent = $(parent);
var offset = element.offset().top + parent.scrollTop();
var height = element.innerHeight();
var offset_end = offset + height;
if (!element.is(":visible")) {
element.css({"visibility":"hidden"}).show();
var offset = element.offset().top;
element.css({"visibility":"", "display":""});
}
var visible_area_start = parent.scrollTop();
var visible_area_end = visible_area_start + parent.innerHeight();
if (offset-height < visible_area_start) {
parent.animate({scrollTop: offset-height}, 600);
return false;
} else if (offset_end > visible_area_end) {
parent.animate({scrollTop: parent.scrollTop()+ offset_end - visible_area_end }, 600);
return false;
}
return true;
}
回答by Leniel Maccaferri
You can take a look at his awesome link from the jQuery Cookbook:
您可以从 jQuery Cookbook 中查看他的精彩链接:
Determining Whether an Element Is Within the Viewport
Test if Element is contained in the Viewport
测试元素是否包含在视口中
jQuery(document).ready(function() {
var viewportWidth = jQuery(window).width(),
viewportHeight = jQuery(window).height(),
documentScrollTop = jQuery(document).scrollTop(),
documentScrollLeft = jQuery(document).scrollLeft(),
$myElement = jQuery('#myElement'),
elementOffset = $myElement.offset(),
elementHeight = $myElement.height(),
elementWidth = $myElement.width(),
minTop = documentScrollTop,
maxTop = documentScrollTop + viewportHeight,
minLeft = documentScrollLeft,
maxLeft = documentScrollLeft + viewportWidth;
if (
(elementOffset.top > minTop && elementOffset.top + elementHeight < maxTop) &&
(elementOffset.left > minLeft && elementOffset.left + elementWidth < maxLeft)
) {
alert('entire element is visible');
} else {
alert('entire element is not visible');
}
});
Test how much of the element is visible
测试元素有多少可见
jQuery(document).ready(function() {
var viewportWidth = jQuery(window).width(),
viewportHeight = jQuery(window).height(),
documentScrollTop = jQuery(document).scrollTop(),
documentScrollLeft = jQuery(document).scrollLeft(),
$myElement = jQuery('#myElement'),
verticalVisible, horizontalVisible,
elementOffset = $myElement.offset(),
elementHeight = $myElement.height(),
elementWidth = $myElement.width(),
minTop = documentScrollTop,
maxTop = documentScrollTop + viewportHeight,
minLeft = documentScrollLeft,
maxLeft = documentScrollLeft + viewportWidth;
function scrollToPosition(position) {
jQuery('html,body').animate({
scrollTop : position.top,
scrollLeft : position.left
}, 300);
}
if (
((elementOffset.top > minTop && elementOffset.top < maxTop) ||
(elementOffset.top + elementHeight > minTop && elementOffset.top +
elementHeight < maxTop))
&& ((elementOffset.left > minLeft && elementOffset.left < maxLeft) ||
(elementOffset.left + elementWidth > minLeft && elementOffset.left +
elementWidth < maxLeft)))
{
alert('some portion of the element is visible');
if (elementOffset.top >= minTop && elementOffset.top + elementHeight
<= maxTop) {
verticalVisible = elementHeight;
} else if (elementOffset.top < minTop) {
verticalVisible = elementHeight - (minTop - elementOffset.top);
} else {
verticalVisible = maxTop - elementOffset.top;
}
if (elementOffset.left >= minLeft && elementOffset.left + elementWidth
<= maxLeft) {
horizontalVisible = elementWidth;
} else if (elementOffset.left < minLeft) {
horizontalVisible = elementWidth - (minLeft - elementOffset.left);
} else {
horizontalVisible = maxLeft - elementOffset.left;
}
var percentVerticalVisible = (verticalVisible / elementHeight) * 100;
var percentHorizontalVisible = (horizontalVisible / elementWidth) * 100;
if (percentVerticalVisible < 50 || percentHorizontalVisible < 50) {
alert('less than 50% of element visible; scrolling');
scrollToPosition(elementOffset);
} else {
alert('enough of the element is visible that there is no need to scroll');
}
} else {
// element is not visible; scroll to it
alert('element is not visible; scrolling');
scrollToPosition(elementOffset);
}
回答by Ashok Gj
The following code helped me achieve the result
以下代码帮助我实现了结果
function scroll_to_element_if_not_inside_view(element){
if($(window).scrollTop() > element.offset().top){
$('html, body').animate( { scrollTop: element.offset().top }, {duration: 400 } );
}
}
回答by Riccardo Volpe
There is a jQuery pluginwhich allows us to quickly check if a whole element (or also only part of it) is within the browsers visual viewport regardless of the window scroll position. You need to download it from its GitHub repository:
有一个jQuery 插件,它允许我们快速检查整个元素(或它的一部分)是否在浏览器的可视视口中,而不管窗口滚动位置如何。您需要从其GitHub 存储库下载它:
Suppose to have the following HTML and you want to alert when footer is visible:
假设有以下 HTML 并且您想在页脚可见时发出警报:
<section id="container">
<aside id="sidebar">
<p>
Scroll up and down to alert the footer visibility by color:
</p>
<ul>
<li><span class="blue">Blue</span> = footer <u>not visible</u>;</li>
<li><span class="yellow">Yellow</span> = footer <u>visible</u>;</li>
</ul>
<span id="alert"></span>
</aside>
<section id="main_content"></section>
</section>
<footer id="page_footer"></footer>
So, add the plugin before the close of body tag:
所以,在 body 标签结束前添加插件:
<script type="text/javascript" src="js/jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="js/jquery_visible/examples/js/jq.visible.js"></script>
After that you can use it in a simple way like this:
之后,您可以像这样以简单的方式使用它:
<script type="text/javascript">
jQuery( document ).ready(function ( $ ) {
if ($("footer#page_footer").visible(true, false, "both")) {
$("#main_content").css({"background-color":"#ffeb3b"});
$("span#alert").html("Footer visible");
} else {
$("#main_content").css({"background-color":"#4aafba"});
$("span#alert").html("Footer not visible");
}
$(window).scroll(function() {
if ($("footer#page_footer").visible(true, false, "both")) {
$("#main_content").css({"background-color":"#ffeb3b"});
$("span#alert").html("Footer visible");
} else {
$("#main_content").css({"background-color":"#4aafba"});
$("span#alert").html("Footer not visible");
}
});
});
</script>
Here a demo
这里有一个演示