我有一个滚动的div,我想有一个事件,当我点击它,它将迫使这个div滚动查看里面的一个元素。 我这样写它的JavasSript:
document.getElementById(chr).scrollIntoView(true);
但这在滚动div本身的同时滚动整个页面。 如何解决这个问题?
我想这样说: MyContainerDiv.getElementById(杆).scrollIntoView(真正的);
我有一个滚动的div,我想有一个事件,当我点击它,它将迫使这个div滚动查看里面的一个元素。 我这样写它的JavasSript:
document.getElementById(chr).scrollIntoView(true);
但这在滚动div本身的同时滚动整个页面。 如何解决这个问题?
我想这样说: MyContainerDiv.getElementById(杆).scrollIntoView(真正的);
当前回答
我需要滚动页面上的动态加载元素,所以我的解决方案有点复杂。
这将适用于静态元素,这些静态元素不是惰性加载数据,也不是动态加载数据。
const smoothScrollElement = async (selector: string, scrollBy = 12, prevCurrPos = 0) => {
const wait = (timeout: number) => new Promise(resolve => setTimeout(resolve, timeout));
const el = document.querySelector(selector) as HTMLElement;
let positionToScrollTo = el.scrollHeight;
let currentPosition = Math.floor(el.scrollTop) || 0;
let pageYOffset = (el.clientHeight + currentPosition);
if (positionToScrollTo == pageYOffset) {
await wait(1000);
}
if ((prevCurrPos > 0 && currentPosition <= prevCurrPos) !== true) {
setTimeout(async () => {
el.scrollBy(0, scrollBy);
await smoothScrollElement(selector, scrollBy, currentPosition);
}, scrollBy);
}
};
其他回答
其他答案都不能解决我的问题。
我摆弄了scrollIntoView参数,并设法找到了一个解决方案。将inline设置为开始并将block设置为最近的位置,以防止父元素(或整个页面)滚动:
document.getElementById(chr).scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start'
});
您必须找到要滚动到的DIV中元素的位置,并设置scrollTop属性。
divElem.scrollTop = 0;
更新:
向上或向下移动的示例代码
function move_up() {
document.getElementById('divElem').scrollTop += 10;
}
function move_down() {
document.getElementById('divElem').scrollTop -= 10;
}
方法1 -平滑滚动到元素中的元素
var box = document.querySelector('.box'), targetElm = document.querySelector('.boxChild'); // <-- Scroll to here within ".box" document.querySelector('button').addEventListener('click', function(){ scrollToElm( box, targetElm , 600 ); }); ///////////// function scrollToElm(container, elm, duration){ var pos = getRelativePos(elm); scrollTo( container, pos.top , 2); // duration in seconds } function getRelativePos(elm){ var pPos = elm.parentNode.getBoundingClientRect(), // parent pos cPos = elm.getBoundingClientRect(), // target pos pos = {}; pos.top = cPos.top - pPos.top + elm.parentNode.scrollTop, pos.right = cPos.right - pPos.right, pos.bottom = cPos.bottom - pPos.bottom, pos.left = cPos.left - pPos.left; return pos; } function scrollTo(element, to, duration, onDone) { var start = element.scrollTop, change = to - start, startTime = performance.now(), val, now, elapsed, t; function animateScroll(){ now = performance.now(); elapsed = (now - startTime)/1000; t = (elapsed/duration); element.scrollTop = start + change * easeInOutQuad(t); if( t < 1 ) window.requestAnimationFrame(animateScroll); else onDone && onDone(); }; animateScroll(); } function easeInOutQuad(t){ return t<.5 ? 2*t*t : -1+(4-2*t)*t }; .box{ width:80%; border:2px dashed; height:180px; overflow:auto; } .boxChild{ margin:600px 0 300px; width: 40px; height:40px; background:green; } <button>Scroll to element</button> <div class='box'> <div class='boxChild'></div> </div>
方法2 -使用Element.scrollIntoView:
请注意,浏览器支持并不适合这个版本
var targetElm = document.querySelector('.boxChild'), // reference to scroll target button = document.querySelector('button'); // button that triggers the scroll // bind "click" event to a button button.addEventListener('click', function(){ targetElm.scrollIntoView() }) .box { width: 80%; border: 2px dashed; height: 180px; overflow: auto; scroll-behavior: smooth; /* <-- for smooth scroll */ } .boxChild { margin: 600px 0 300px; width: 40px; height: 40px; background: green; } <button>Scroll to element</button> <div class='box'> <div class='boxChild'></div> </div>
方法3 -使用CSS滚动行为:
.box { 宽度:80%; 边框:2px虚线; 身高:180 px; overflow-y:滚动; scroll-behavior:光滑;/* <——*/ } # boxChild { Margin: 600px 0 300px; 宽度:40像素; 高度:40像素; 背景:绿色; } <a href='#boxChild'>滚动到元素</a> < div class =“盒子”> < div id =“boxChild”> < / div > < / div >
用户动画滚动
下面是一个如何在没有JQuery的情况下以编程方式横向滚动<div>的示例。要垂直滚动,可以将JavaScript对scrollLeft的写入替换为scrollTop。
JSFiddle
https://jsfiddle.net/fNPvf/38536/
HTML
<!-- Left Button. -->
<div style="float:left;">
<!-- (1) Whilst it's pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
<input type="button" value="«" style="height: 100px;" onmousedown="scroll('scroller',3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
<!-- <3 -->
<img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
<!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
<input type="button" value="»" style="height: 100px;" onmousedown="scroll('scroller',-3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>
JavaScript
// Declare the Shared Timer.
var TIMER_SCROLL;
/**
Scroll function.
@param id Unique id of element to scroll.
@param d Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scroll(id, d, del){
// Scroll the element.
document.getElementById(id).scrollLeft += d;
// Perform a delay before recursing this function again.
TIMER_SCROLL = setTimeout("scroll('"+id+"',"+d+", "+del+");", del);
}
这要归功于Dux。
自动动画滚动
此外,这里还有用于将<div>完全向左和向右滚动的函数。这里我们唯一改变的是,在再次递归调用滚动之前,检查是否已经使用了滚动的完整扩展。
JSFiddle
https://jsfiddle.net/0nLc2fhh/1/
HTML
<!-- Left Button. -->
<div style="float:left;">
<!-- (1) Whilst it's pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
<input type="button" value="«" style="height: 100px;" onclick="scrollFullyLeft('scroller',3, 10);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
<!-- <3 -->
<img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
<!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
<input type="button" value="»" style="height: 100px;" onclick="scrollFullyRight('scroller',3, 10);"/>
</div>
JavaScript
// Declare the Shared Timer.
var TIMER_SCROLL;
/**
Scroll fully left function; completely scrolls a <div> to the left, as far as it will go.
@param id Unique id of element to scroll.
@param d Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyLeft(id, d, del){
// Fetch the element.
var el = document.getElementById(id);
// Scroll the element.
el.scrollLeft += d;
// Have we not finished scrolling yet?
if(el.scrollLeft < (el.scrollWidth - el.clientWidth)) {
TIMER_SCROLL = setTimeout("scrollFullyLeft('"+id+"',"+d+", "+del+");", del);
}
}
/**
Scroll fully right function; completely scrolls a <div> to the right, as far as it will go.
@param id Unique id of element to scroll.
@param d Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyRight(id, d, del){
// Fetch the element.
var el = document.getElementById(id);
// Scroll the element.
el.scrollLeft -= d;
// Have we not finished scrolling yet?
if(el.scrollLeft > 0) {
TIMER_SCROLL = setTimeout("scrollFullyRight('"+id+"',"+d+", "+del+");", del);
}
}
另一个使用jQuery和动画的例子。
var container = $('#container');
var element = $('#element');
container.animate({
scrollTop: container.scrollTop = container.scrollTop() + element.offset().top - container.offset().top
}, {
duration: 1000,
specialEasing: {
width: 'linear',
height: 'easeOutBounce'
},
complete: function (e) {
console.log("animation completed");
}
});