Mon code est à http://jsfiddle.net/mannagod/QT3v5/7/ .
Le JS c'est:
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();
}
}
}
}
J'ai besoin de trouver un moyen de lisser la .scrollintoview()
. En ce moment, il "saute" sur la ligne en surbrillance. J'en ai besoin pour passer en douceur à cette ligne. Cela doit être fait dynamiquement en remplacement de scrollintoview. Des idées? Merci.
Voici le lien vers un de mes articles de blog qui décrit le tout et a un lien vers le projet GitHub où vous pouvez obtenir le plugin.
scrollintoview()
animé.Dans la plupart des navigateurs modernes ( Chrome et Firefox, mais pas Safari, UC ou IE ), vous pouvez passer des options dans un objet à .scrollIntoView()
.
Essaye ça:
Elm.scrollIntoView({ behavior: 'smooth', block: 'center' })
Les autres valeurs sont behavior: 'instant'
ou block: 'start'
ou block: 'end'
. Voir https://developer.mozilla.org/en/docs/Web/API/Element/scrollIntoView
Je cherchais également ce problème et j'ai trouvé cette solution:
$('html, body').animate({
scrollTop: $("#elementId").offset().top
}, 1000);
ressource: http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/
Peut-être que vous ne voulez pas ajouter jQuery uniquement pour implémenter cette fonctionnalité. elem est l'élément à faire défiler. La position de destination peut être extraite de la propriété offsetTop de l'élément à déplacer dans la vue.
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);
}
Défilement fluide en utilisant requestAnimationFrame
sur une durée spécifique sans jQuery.
Démo: http://codepen.io/Shadeness/pen/XXyvKG?editors=001
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);
};
Par exemple:
bringIntoView(document.querySelector('#bottom'), 400)
Elle devrait s'accélérer à mesure que dt
(deltaTime) grossit et ralentit à mesure que distanceLeft
devient plus petit. J'ai envisagé de rompre la boucle si l'utilisateur faisait défiler mais meh. Les variables globales empêchent l'appel précédent de prendre complètement le relais, mais n'annulent pas la boucle récursive précédente, de sorte qu'elle s'animera deux fois plus rapidement.
Il vous suffit d'inclure ce polyfill et cela fonctionne.
https://github.com/iamdustan/smoothscroll
<script src="js/smoothscroll.js"></script>
Ou exigez-le si vous utilisez npm.
require('smoothscroll-polyfill').polyfill();
Utilisez la méthode native scrollIntoView.
document.getElementById('parallax-group-logo').scrollIntoView({
block: "start",
behavior: "smooth"
});
Essaye ça:
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();
}
Juste pour ajouter à cela au cas où cela aiderait quelqu'un,
Je travaillais sur un PWA pour iOS et Android et j'utilisais la méthode scrollIntoView()
jusqu'à ce que je découvre que l'objet scrollIntoViewOptions
n'était pas pris en charge par Safari et donc ne ferait pas défiler en douceur ou quoi que ce soit, etc.
J'ai pu imiter la fonctionnalité de scrollIntoView
, avec un défilement fluide et une option "la plus proche", pour iOS avec JS ordinaire ... enfin, TypeScript simple ...
Cliquez sur gestionnaire ou w/e:
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' });
}
Fonction de défilement manuel:
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);
}
REMARQUE: Le grand si imbriqué et les calculs dans le gestionnaire consistent simplement à trouver la position "la plus proche" alors que j'essayais de reproduire ce comportement, mais en utilisant simplement la fonction scrollToElement pour animer le défilement vers le haut (comportement par défaut sans objet Options), vous pouvez utiliser:
scrollToElement(scrollLayer, element.offsetTop, 200);