我的代码位于http://jsfiddle.net/mannagod/QT3v5/7/。
JS是:
function delay() {
var INTENDED_MONTH = 7 //August
// INTENDED_MONTH is zero-relative
now = new Date().getDate(),
rows = document.getElementById('scripture').rows;
if (new Date().getMonth() != INTENDED_MONTH) {
// need a value here less than 1,
// or the box for the first of the month will be in Red
now = 0.5
};
for (var i = 0, rl = rows.length; i < rl; i++) {
var cells = rows[i].childNodes;
for (j = 0, cl = cells.length; j < cl; j++) {
if (cells[j].nodeName == 'TD'
&& cells[j].firstChild.nodeValue != ''
&& cells[j].firstChild.nodeValue == now) {
// 'ffff99' // '#ffd700' // TODAY - red
rows[i].style.backgroundColor = 'red'
rows[i].scrollIntoView();
}
}
}
}
我需要找到一种方法来平滑.scrollintoview()
。现在它“跳”到突出显示的行。我需要它顺利过渡到那一行。它需要动态完成以替换scrollintoview。有任何想法吗?感谢。
答案 0 :(得分:52)
在大多数现代浏览器(Chrome and Firefox, but not Safari, UC, or IE)中,您可以将对象中的选项传递给.scrollIntoView()
。
试试这个:
elm.scrollIntoView({ behavior: 'smooth', block: 'center' })
其他值为behavior: 'instant'
或block: 'start'
或block: 'end'
。见https://developer.mozilla.org/en/docs/Web/API/Element/scrollIntoView
答案 1 :(得分:29)
我也在搜索这个问题并找到了这个解决方案:
$('html, body').animate({
scrollTop: $("#elementId").offset().top
}, 1000);
资源: http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/
答案 2 :(得分:13)
也许您不想仅为实现此功能而添加jQuery。 elem是要滚动的元素。目标pos可以从要移动到视图中的元素的offsetTop属性中获取。
function Scroll_To(elem, pos)
{
var y = elem.scrollTop;
y += (pos - y) * 0.3;
if (Math.abs(y-pos) < 2)
{
elem.scrollTop = pos;
return;
}
elem.scrollTop = y;
setTimeout(Scroll_To, 40, elem, pos);
}
答案 3 :(得分:7)
使用requestAnimationFrame
在特定持续时间内平滑滚动而不使用jQuery。
演示:http://codepen.io/Shadeness/pen/XXyvKG?editors=0010
window.bringIntoView_started = 0;
window.bringIntoView_ends = 0;
window.bringIntoView_y = 0;
window.bringIntoView_tick = function() {
var distanceLeft, dt, duration, t, travel;
t = Date.now();
if (t < window.bringIntoView_ends) {
dt = t - window.bringIntoView_started;
duration = window.bringIntoView_ends - window.bringIntoView_started;
distanceLeft = window.bringIntoView_y - document.body.scrollTop;
travel = distanceLeft * (dt / duration);
document.body.scrollTop += travel;
window.requestAnimationFrame(window.bringIntoView_tick);
} else {
document.body.scrollTop = window.bringIntoView_y;
}
};
window.bringIntoView = function(e, duration) {
window.bringIntoView_started = Date.now();
window.bringIntoView_ends = window.bringIntoView_started + duration;
window.bringIntoView_y = Math.min(document.body.scrollTop + e.getBoundingClientRect().top, document.body.scrollHeight - window.innerHeight);
window.requestAnimationFrame(window.bringIntoView_tick);
};
例如:
bringIntoView(document.querySelector('#bottom'), 400)
它应该在dt
(deltaTime)变大时加速,并在distanceLeft
变小时减慢速度。如果用户滚动但我认为我打破了循环。全局变量阻止先前的调用完全接管,但不会取消先前的递归循环,因此它的动画速度提高了两倍。
答案 4 :(得分:3)
您只需要包含此polyfill即可。
https://github.com/iamdustan/smoothscroll
<script src="js/smoothscroll.js"></script>
如果您使用npm,则需要它。
require('smoothscroll-polyfill').polyfill();
使用原生的scrollIntoView方法。
document.getElementById('parallax-group-logo').scrollIntoView({
block: "start",
behavior: "smooth"
});
答案 5 :(得分:2)
这是描述整个内容的链接to a blog post of mine,并且链接到GitHub项目,您可以在其中获取插件。
scrollintoview()
jQuery插件。答案 6 :(得分:2)
试试这个:
function scroll_into_view_smooth(elem)
{ var FPS = 48; // frames per second
var DURATION = 0.6; // sec
var e = elem;
var left = e.offsetLeft;
var top = e.offsetTop;
var width = e.offsetWidth;
var height = e.offsetHeight;
var body = document.body;
var to_scroll = [];
var p, offset;
while ((p = e.offsetParent))
{ var client_width = p.clientWidth;
var client_height = p!=body ? p.clientHeight : Math.min(document.documentElement.clientHeight, window.innerHeight);
if (client_width<p.scrollWidth-1 && ((offset=left-p.scrollLeft)<0 || (offset=left+width-p.scrollLeft-client_width)>0))
{ to_scroll.push({elem: p, prop: 'scrollLeft', from: p.scrollLeft, offset: offset});
}
if (client_height<p.scrollHeight-1 && ((offset=top-p.scrollTop)<0 || (offset=top+height-p.scrollTop-client_height)>0))
{ to_scroll.push({elem: p, prop: 'scrollTop', from: p.scrollTop, offset: offset});
}
e = p;
left += e.offsetLeft;
top += e.offsetTop;
}
var x = 0;
function apply()
{ x = Math.min(x+1/(DURATION * FPS), 1);
for (var i=to_scroll.length-1; i>=0; i--)
{ to_scroll[i].elem[to_scroll[i].prop] = to_scroll[i].from + to_scroll[i].offset*x*x;
}
if (x < 1)
{ setTimeout(apply, 1000/FPS);
}
}
apply();
}
答案 7 :(得分:1)
只需添加此内容以防他人受帮助
我正在开发适用于iOS和Android的PWA,并且一直使用scrollIntoView()
方法,直到发现Safari不支持scrollIntoViewOptions
对象,因此无法流畅滚动或进行其他操作。
对于能够使用普通JS ... iOS,普通TypeScript ...的iOS,我能够通过平滑滚动和“最近”选项来模仿scrollIntoView
的功能。
点击处理程序或带有的
const element = *elementToScrollIntoView*;
const scrollLayer = *layerToDoTheScrolling*
if (/iPad|iPhone|iPod/.test(navigator.userAgent) {
let position;
const top = element.offsetTop - scrollLayer.scrollTop;
if (element.offsetTop < scrollLayer.scrollTop) {
// top of element is above top of view - scroll to top of element
position = element.offsetTop;
} else if (element.scrollHeight + top < scrollLayer.offsetHeight) {
// element is in view - don't need to scroll
return;
} else if (element.scrollHeight > scrollLayer.offsetHeight) {
// element is bigger than view - scroll to top of element
position = element.offsetTop;
} else {
// element partially cut-off - scroll remainder into view
const difference = scrollLayer.offsetHeight - (element.scrollHeight + top);
position = scrollLayer.scrollTop - difference;
}
// custom function for iOS
scrollToElement(scrollLayer, position, 200);
} else {
// just use native function for Android
element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
}
手动滚动功能:
scrollToElement(scrollLayer, destination, duration) {
if (duration <= 0) {
return;
}
const difference = destination - scrollLayer.scrollTop;
const perTick = (difference / duration) * 10;
setTimeout(() => {
scrollLayer.scrollTop = scrollLayer.scrollTop + perTick;
if (scrollLayer.scrollTop === destination) {
return;
}
scrollToElement(scrollLayer, destination, duration - 10);
}, 10);
}
注意:处理程序中嵌套的if和计算只是为了寻找“最接近”的位置,就像我试图复制该行为时一样,但是只是使用scrollToElement函数来动画化滚动到顶部(没有选项对象的默认行为)可以使用:
scrollToElement(scrollLayer, element.offsetTop, 200);
答案 8 :(得分:0)
您可以尝试将evt.preventDefault()添加到函数中。这应该覆盖常规的“点击链接”功能。示例:
// Scroll to anchor ID using scrollTO event
function linkClicked(evt) { // function to listen for when a link is clicked
evt.preventDefault();
evt.scrollIntoView({behavior: 'smooth'});
}
// Scroll to section on link click
navBar.addEventListener('click', linkClicked);