-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DOM基础测试27 #4
Comments
第一题:(Throttle是一个节流函数) (function() {
let backTop = document.getElementById('backTop'),
scrollTop = 0,
windowHeight = window.innerHeight || document.documentElement.clientHeight;
let scroll = Throttle((e) => {
scrollTop = document.documentElement.scrollTop || window.pageYOffset ||
document.body.scrollTop;
if (scrollTop >= windowHeight) {
backTop.classList.add('show');
} else {
backTop.classList.remove('show');
}
}, 300)
document.addEventListener('scroll', scroll);
})(); 第二题:(content是高度小于屏幕高度的元素overflow:hidden; wrapper是content的子元素overflow:auto;) (function() {
let backTop = document.getElementById('backTop'),
content = document.getElementById('content'),
wrapper = document.getElementById('wrapper'),
scrollTop = 0,
windowHeight = content.innerHeight || content.clientHeight;
let scroll = Throttle((e) => {
scrollTop = wrapper.scrollTop;
if (scrollTop >= windowHeight) {
backTop.classList.add('show');
} else {
backTop.classList.remove('show');
}
}, 300);
wrapper.addEventListener('scroll', scroll);
})(); Throttle源码: function Throttle(fn, delay) {
let last = 0,
timer = null;
return function() {
let context = this,
args = arguments,
now = +new Date();
if (now - last < delay) {
clearTimeout(timer)
timer = setTimeout(function() {
last = now;
fn.apply(context, args);
}, delay)
} else {
last = now;
fn.apply(context, args);
}
}
} |
一个通吃两道小题的方案JavaScript(ES6,需兼容自行 babel){
const
$back_to_top = document.getElementById('backTop'),
$parent = $back_to_top.parentElement;
const
getScrollTop = $parent === document.body ?
() => window.scrollY :
() => $parent.scrollTop,
getViewportHeight = $parent === document.body ?
() => window.innerHeight :
() => $parent.offsetHeight,
scrollBackToTop = $parent === document.body ?
() => window.scrollY = 0 :
() => $parent.scrollTop = 0;
$back_to_top.addEventListener('click', scrollBackToTop);
const wheelEventHandler = () => $back_to_top.classList[
getScrollTop() > getViewportHeight() ? 'remove' : 'add'
]('hidden');
// TODO: 节流函数,减少事件触发次数
// 要用的话直接 underscore 或者用原生的 setInterval 实现一个就行
const throttle = (fn, interval) => fn;
$parent.addEventListener('wheel', throttle(wheelEventHandler, 100));
$parent.addEventListener('scroll', throttle(wheelEventHandler, 100));
document.addEventListener('DOMContentLoaded', wheelEventHandler);
} CSS(也可以不用,只是为了方便用 class 管理样式)#backTop {
display: block;
position: fixed;
top: 0;
/* 自定义样式 */
}
#backTop.hidden {
visibility: hidden;
} |
css .hidden{
display: none;
}
#container{
overflow:auto;
height: 300px;
}
#backTop{
/* 若容器是html的时候#backTop是fixed定位 */
/* position: fixed; */
/* 若容器是div的时候#backTop是absolute定位 */
position: absolute;
right:30px;
margin-top:200px;
}
/* 辅助元素 */
.auxiliary{
height: 800px;
} html <!-- 当容器是html的时候 -->
<!-- <a
class="hidden"
id="backTop"
href="#"
>
返回顶部
</a>
<div
class="auxiliary"
>
</div> -->
<!-- 当容器是div的时候 -->
<div
id="container"
>
<a
class="hidden"
id="backTop"
href="#"
>
返回顶部
</a>
<div
class="auxiliary"
>
</div>
</div> js /* 滚动元素是window时 */
/* toggleBackTop(window,document.querySelector("#backTop")); */
/* 滚动元素是div时 */
toggleBackTop(document.querySelector("#container"),document.querySelector("#backTop"));
function toggleBackTop(container,backTopDom){
container.addEventListener("scroll",function(){
let containerHeight,
scrollHeight;
if(this instanceof Window){
containerHeight =
document.documentElement.clientHeight
||
document.body.clientHeight;
}else{
containerHeight = this.clientHeight;
}
scrollHeight = this.scrollY||this.scrollTop||0;
backTopDom.classList.toggle("hidden",scrollHeight<containerHeight);
})
} |
借用一楼的 (function (doc, con) {
var backTop = doc.getElementById('backTop');
var body = con || doc.documentElement;
var setVisible = Throttle(function () {
var h = body.clientHeight;
var scrollTop = body.scrollTop;
if (scrollTop >= h) {
backTop.removeAttribute('hidden');
} else {
backTop.setAttribute('hidden', true)
}
}, 300)
var content = con||doc;
content.addEventListener('scroll', setVisible, false);
window.addEventListener('resize', setVisible, false);//改变窗口大小也需要监听
})(document) 如果滚动容器是 var div = document.getElementById('wrap');
(function (doc, con) {
//...同上
})(document,div) |
对于第一题,分析提议需要注意以下几点:
#backTop {
position: fixed;
bottom: 10px;
right: 10px;
} let backTop = document.getElementById('backTop');
let ticking = false;
window.addEventListener('scroll', function(event) {
if (!ticking) {
window.requestAnimationFrame(function() {
if(window.pageYOffset > document.documentElement.clientHeight) backTop.hidden = false;
else backTop.hidden = true
ticking = false;
});
ticking = true;
}
}) 对于第二题:
#backTop {
position: fixed;
bottom: 10px;
right: 10px;
}
#container {
position: relative;
margin: 20px;
width: 500px;
height: 500px;
border: 1px solid black;
overflow: scroll;
} let backTop = document.getElementById('backTop');
let container = document.getElementById('container');
let ticking = false;
container.addEventListener('scroll', function(event) {
if (!ticking) {
window.requestAnimationFrame(function() {
if(container.scrollTop > container.clientHeight) backTop.hidden = false;
else backTop.hidden = true
ticking = false;
});
ticking = true;
}
})
backTop.addEventListener('click', function() {
container.scrollTop = 0;
}) |
我记得 移动端对 scroll 事件有优化,当在滚动过程中,不会执行 scroll 事件绑定的函数;当滚动停止的时候才会执行。 |
确切的说是 ios 的机型 |
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#container {
width: 100%;
height: 100%;
overflow: scroll;
}
<div id="container">
<a href="#" id="backTop" hidden>返回顶部!</a>
<div class="big"></div>
</div>
let backTop = document.getElementById('backTop')
let viewportHeight = document.documentElement.clientHeight || document.body.clientHeight
window.addEventListener('scroll', function(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
if(scrollTop >= viewportHeight){
if(backTop.hasAttribute('hidden')){
backTop.removeAttribute('hidden')
}
}else if(!backTop.hasAttribute('hidden')){
backTop.setAttribute('hidden', '')
}
}, false)
let container = document.getElementById('container')
container.addEventListener('scroll', function(){
let scrollTop = this.scrollTop
if(scrollTop >= viewportHeight){
if(backTop.hasAttribute('hidden')){
backTop.removeAttribute('hidden')
}
}else if(!backTop.hasAttribute('hidden')){
backTop.setAttribute('hidden', '')
}
}, false) 技术比较菜,不太懂 pc 和移动端关于兼容这块有什么具体的区别, 也没体会出上面使用节流函数的必要性是什么,我觉得没必要用防抖节流来控制啊 |
/*
* 调用:
* backTop({
* wrapEl: el, // 选传
* backTopEl: el
* })
**/
function backTop (obj) {
var wrapEl = obj.wrapEl || window, // 外层元素
backTopEl = obj.backTopEl, // 返回顶部
wH, // 外层元素高度
scrollTop, // 滚动高
timer1, timer2; // 定时器
(wrapEl===document.body || wrapEl===document.documentElement) && (wrapEl = window);
wrapEl===window && (wH=document.documentElement.clientHeight,1) || (wH=wrapEl.clientHeight);
if (backTopEl) {
wrapEl.onscroll = function () {
clearTimeout(timer2);
timer2 = setTimeout(function () { // 节流
scrollTop = wrapEl===window ? (document.documentElement.scrollTop || document.body.scrollTop) : (wrapEl.scrollTop);
(scrollTop-wH>0) ? backTopEl.removeAttribute("hidden") : backTopEl.setAttribute("hidden", "hidden");
}, 200);
}
window.onresize = function () {
clearTimeout(timer1);
timer1 = setTimeout(function () {
wrapEl===window && (wH=document.documentElement.clientHeight,1) || (wH=wrapEl.clientHeight);
}, 200);
}
}
} |
let backTop = document.getElementById('backTop')
let scrollFunction = (box) => {
box.onscroll = () => {
let scrollT = box.scrollTop || document.documentElement.scrollTop || document.body.scrollTop
let clientH = box.clientHeight || document.documentElement.clientHeight
if (scrollT > clientH) {
backTop.style.display = 'block'
} else {
backTop.style.display = 'none'
}
}
}
scrollFunction(window) // 第一种
let divBox = document.getElementById('box')
scrollFunction(divBox) // 第二种 按照自己的理解初步实现了功能,细节方面还存在比较多的问题,请大家指正 |
第一题与第二题的函数 function scroll(node){
let parent = document.querySelector(node)
let h1,scrolltop ;
if(node!="body"){
h1 = parent.offsetHeight
parent.onscroll = function(){
scrolltop = parent.scrollTop
console.log(scrolltop)
checkHeight(h1,scrolltop)
}
}else{
h1 = document.documentElement.clientHeight
window.onscroll=function(){
scrolltop = document.documentElement.scrollTop||document.body.scrollTop;
console.log(scrolltop)
checkHeight(h1,scrolltop)
}
}
}
// 比较检查
function checkHeight(h1,h2){
let backtop = document.querySelector("#backTop")
if(h1>h2){
backtop.style.display="none"
}else{
backtop.style.display="block"
}
} 这里进行调用 //第一题
scroll("body")
//第二题是div盒子,盒子要写上overflow-y:scroll; 此盒字id为scrollBox
scroll("#scrollBox") |
html <body id="wrap" style="height: 1800px;">
<a href="#" id="backTop" style="position: fixed;top: 20px;right: 20px;" hidden>返回顶部!</a>
<a href="#" id="info" style="position: fixed;top:20px;left: 20px;"></a>
<div class="box" style="height: 200px;overflow: auto; width:200px;background-color: #ccc;">
<div class="con" style="height: 1800px">
</div>
</div>
</body> js function scroller(param) {
let {scrollDom, distance, backDom} = param
scrollDom = scrollDom || window
backDom = backDom || document.querySelector('#backTop')
let isDoc = scrollDom.nodeName === undefined || scrollDom.nodeName === 'HTML'
if (isDoc) {
scrollDom = window
}
scrollDom.addEventListener('scroll', () => {
let scrollTop
if (isDoc) {
scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
distance = distance || window.screen.height
} else {
scrollTop = scrollDom.scrollTop
distance = distance || scrollDom.clientHeight
}
document.querySelector('#info').innerHTML = scrollTop + ',' + distance
if (scrollTop > distance) {
backDom.removeAttribute('hidden')
} else {
backDom.setAttribute('hidden', 'hidden')
}
}, false)
} 调用JS new scroller({
scrollDom: document.querySelector('.box'),
distance: 10,
backDom: document.querySelector('#backTop')
})
new scroller({scrollDom: document.querySelector('html')})
//new scroller({ distance: 100,}) |
第一题
css #scrollTop {
display: block;
visibility: hidden;
position: fixed;
bottom: 20px;
right: 0px;
}
#scrollTop.show {
visibility: visible
} ;(function () {
function fn() {
let $scrollTop = document.getElementById('scrollTop')
let top = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
top > 0 ? $scrollTop.classList.add('show') : $scrollTop.classList.remove('show')
}
// 窗口resize需要重新计算各高度
function resizeFn() {
// 实际内容高度
const totalHeight = document.documentElement.offsetHeight || document.body.offsetHeight
// 可视区域高度
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
let scrollFn = _.throttle(fn, 100);
// SCROLL_THRESHOLD是出现滚动到顶部的阈值
const SCROLL_THRESHOLD = 40;
if (totalHeight - windowHeight > SCROLL_THRESHOLD) {
window.removeEventListener('scroll', scrollFn);
window.addEventListener('scroll', scrollFn);
}
}
window.addEventListener('resize', _.throttle(resizeFn, 100));
resizeFn();
// 初始需要执行是因为部分浏览器刷新页面会定位到之前滚动的位置
fn()
})() 第二题
html <div id="container">
<div id="body">
</div>
</div>
<a href="" id="scrollTop">回到顶部</a> css #scrollTop {
visibility: hidden;
position: absolute;
right: 10px;
margin-top: calc(20px - 200px); /*200px 是container的最大高度*/
}
#scrollTop.show {
visibility: visible
} js const $container = document.getElementById('container')
const $body = document.getElementById('body')
const $topBtn = document.getElementById('scrollTop')
const containerHeight = $container.clientHeight;
const bodyHeight = $body.offsetHeight;
// SCROLL_THRESHOLD是出现滚动到顶部的阈值
const SCROLL_THRESHOLD = 40;
if (bodyHeight - containerHeight > SCROLL_THRESHOLD) {
function scrollFn() {
$container.scrollTop > 0 ? $topBtn.classList.add('show') : $topBtn.classList.remove('show')
}
if (bodyHeight > containerHeight) {
$container.addEventListener('scroll', _.throttle(scrollFn, 100))
}
} |
第 1 题和第 2 题,两大问题,一个对策。已封装成组件,只需为构造函数传入需要“返回顶部”功能的容器元素即可,默认为 body 元素。 在线演示.back-top {
position: fixed;
margin-top: -15px;
margin-left: -15px;
transform: translate(-100%, -100%);
white-space: nowrap;
} /**
* 返回顶部
* @descr: 给定一个容器,当滚动高度超出1倍的容器高度,显示返回顶部,否则隐藏
* @param {object HTMLElement} [elm] - HTML元素,可选,默认为 body 元素
*/
function ScrollBackTop(elm) {
var that = this;
var timer = null;
this.elm = elm || document;
this.elmBox = elm || document.documentElement;
this.render();
// 监听容器 scroll 事件
this.elm.addEventListener('scroll', function() {
clearTimeout(timer);
timer = setTimeout(function() {
that.scrolling();
}, 20);
}, false);
// 监听视窗尺寸改变
window.addEventListener('resize', function() {
clearTimeout(timer);
timer = setTimeout(function() {
that.scrolling();
}, 20);
}, false);
}
// 生成按钮
ScrollBackTop.prototype.render = function() {
var that = this;
var btn = document.createElement('a');
var text = document.createTextNode('返回顶部↑');
btn.className = 'back-top';
btn.href = '#';
btn.hidden = true;
// 监听点击
btn.addEventListener('click', function(event) {
if (that.elm === document) {
window.scrollTo(0, 0); // 兼容移动端
} else {
that.elmBox.scrollTop = 0;
}
event.preventDefault();
return false;
}, false);
btn.appendChild(text);
(this.elm === document ? document.body : this.elm).appendChild(btn);
this.btn = btn;
}
ScrollBackTop.prototype.scrolling = function() {
var elmBox = this.elmBox;
var scroll_y = this.elm === document ? window.pageYOffset : elmBox.scrollTop;
var offset_x = elmBox.offsetLeft;
var offset_y = elmBox.offsetTop;
var x = elmBox.clientWidth;
var y = elmBox.clientHeight;
if (scroll_y >= y) {
this.btn.hidden = false;
// 按钮的显示位置
this.btn.style.top = offset_y + y + 'px';
this.btn.style.left = offset_x + x + 'px';
} else {
this.btn.hidden = true;
}
}
new ScrollBackTop(); // 整个文档返回顶部的场景
new ScrollBackTop(document.getElementById('divBox')); // 某个 div 容器的场景 |
var viewHeight = -1; // 一屏的高度
var backTop = document.getElementById('backTop');
var lastModifiedBackTopHidden = true; // 上次缓存的结果,默认进入页面为隐藏状态
// 尺寸变化监听
function resizeObserver() {
var currentEl = this,
isDocumentNode = currentEl instanceof Document;
// 节流方法
window.requestAnimationFrame(function () {
viewHeight = isDocumentNode ? document.documentElement.clientHeight : Math.min(document.documentElement.clientHeight, currentEl.clientHeight)
});
}
// 通用监听
function observer() {
var currentEl = this,
isDocumentNode = currentEl instanceof Document;
// 偏移位置
var offset = isDocumentNode ? window.pageYOffset : currentEl.scrollTop
// 获取一屏的高度 只赋值一次
if (viewHeight < 0) {
resizeObserver.call(currentEl)
}
// 节流方法
window.requestAnimationFrame(function () {
var backTopHidden = offset > viewHeight;
if (lastModifiedBackTopHidden != backTopHidden) {
// 将上次比较的结果缓存,减少设置hidden的频次
lastModifiedBackTopHidden = backTopHidden;
backTop.hidden = !backTopHidden
}
});
}
// 第一题
document.addEventListener('scroll', observer)
// 第二题
document.getElementsByClassName('placeholder')[0].addEventListener('scroll', observer)
// resize 事件监听 当发生 resize 时,会导致一屏的高度变化
document.addEventListener('resize', resizeObserver);
// 初次加载页面时,需要判断滚动条是否在中间状态
document.addEventListener('DOMContentLoaded', observer); |
第一题 var topBtn = document.getElementById('bakcTop');
window.onscroll=function(){
var top = document.documentElement.scrollTop || document.body.scrollTop;
var height = document.documentElement.clientHeight;
if(top>=height){
topBtn.style.display="block"
}else{
topBtn.style.display="none"
}
} 第二题 var contanier = document.querySelectorAll(".contanier")[0];
var topBtn= document.getElementById("backTop")
contanier.onscroll=function(){
var height = contanier.clientHeight;
var top = contanier.scrollTop;
if(top>height){
topBtn.style.display="block"
}else{
topBtn.style.display="none"
}
} |
document.body.onscroll = function(){
var windowHeight = document.body.clientHeight;
var scrollTop = document.body.scrollTop;
document.getElementById("backTop").hidden = scrollTop > windowHeight?false:true;
};
var contentBox = document.getElementById("content");
contentBox.onscroll = function(e){
var boxHeight = parseFloat(window.getComputedStyle(contentBox).height);
var scrollTop = e.target.scrollTop;
document.getElementById("backTop").hidden = scrollTop > boxHeight?false:true;
}; 本地console的时候确实发现滚动事件触发频率很高,看到评论才发现还需要节流等等。。 |
基于CSS世界有6.4节 和 //随便创建个可以滚动的东西
const creatBody = (id, css) => {
const
div = document.createElement('div'),
ul = document.createElement('ul'),
uid = id || 'one',
cid = uid + '_fisrt'
for (let i = 0; i < 30; i++) {
let t = document.createElement('li')
if (i == 0) {
t.id = cid
}
t.innerHTML = `没什么意义的列表`
t.style.padding = '20px'
ul.appendChild(t)
}
const _css = css ? css : {
overflow: 'scroll',
height: '500px',
'scroll-behavior': "smooth",
}
ul.id = uid
addCSS({ position: 'relative' }, div)
addCSS(_css, ul)
div.appendChild(ul)
document.body.appendChild(div)
return ul
}
//创建回到顶部的按钮
const creatHandle = (el, html) => {
let handle = document.createElement('a')
handle.innerHTML = '回到顶部'
const css = {
position: html ? 'fixed' : 'absolute',
top: '70%',
right: '50px',
cursor: 'pointer',
border: '1px solid red',
display: 'none'
}
addCSS(css, handle)
//
if (typeof window.getComputedStyle(document.body).scrollBehavior == 'undefined') {
// 传统的JS平滑滚动处理代码...
console.log('Hellow Edge/IE')
console.log(el)
handle.onclick = backTop(el)
} else {
handle.href = '#' + (html ? el.id : el.childNodes[0].id)
}
if (html)
document.body.appendChild(handle)
else
el.appendChild(handle)
return handle
}
//js滚动动画,在edge试了下能用
const backTop = (el) => {
return e => {
let target
if (el.scrollTop) {
target = el
} else if (document.documentElement.scrollTop) {
target = document.documentElement
} else if (document.body.scrollTop) {
target = document.body
}
console.log("开始滚了")
cancelAnimationFrame(timer);
let timer = requestAnimationFrame(function fn() {
if (target.scrollTop > 0) {
target.scrollTop = target.scrollTop - 20;
timer = requestAnimationFrame(fn);
} else {
cancelAnimationFrame(timer);
}
});
}
}
//滚动事件
const showBackTop = (backTop) => {
return (el) => {
const
target = el.srcElement,//documentElement返回html根元素,再后面的是兼容edge
top = target.scrollTop || document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop,
cHeihgt = target.clientHeight || target.documentElement.clientHeight,
r = Math.floor(top / cHeihgt * 10)
// console.log(r)
// console.log('top:' + top)
if (r < 3 && backTop.style.display !== 'none') {
console.log('none')
addCSS({ display: 'none' }, backTop)
} else if (r >= 3 && backTop.style.display === 'none') {
console.log('该出现backTop了')
addCSS({ display: 'block' }, backTop)
}
}
}
//增加css
const addCSS = (obj, target) => {
//兼容下ie
if (!Object.entries) {
Object.entries = (obj) => {
let arr = [];
for (let key of Object.keys(obj)) {
arr.push([key, obj[key]]);
}
return arr;
}
}
for (let [key, values] of Object.entries(obj)) {
// console.log('key: ' + key + ' values: ' + values)
target.style[key] = values
}
}
addCSS({ 'scroll-behavior': "smooth" }, document.querySelector('html'))
const one = creatBody('one')
const two = creatBody(two, { padding: '50px' })
const h1 = creatHandle(one, false)
const h2 = creatHandle(two, true)
window.onscroll = showBackTop(h2)
one.onscroll = showBackTop(h1) |
偷个懒写在一起啦
var divBody = document.getElementById('bodyDiv')
var isHiddenBody = document.getElementById('backTop').getAttribute('hidden');
var isHiddenBody2 = document.getElementById('backTop2').getAttribute('hidden');
window.addEventListener('scroll', bodyScroll);
divBody.addEventListener('scroll', divScroll);
function bodyScroll (e) {
var windownHeight = window.screen.availHeight;
if (document.body.scrollHeight > windownHeight) {
var top = document.body.scrollTop || document.documentElement.scrollTop;
if (top >= windownHeight && isHiddenBody !== null) {
document.getElementById('backTop').removeAttribute('hidden');
isHiddenBody = null
} else if (top < windownHeight && isHiddenBody === null) {
document.getElementById('backTop').setAttribute('hidden', '');
isHiddenBody = ''
}
}
}
function divScroll (e) {
var divHeight = divBody.offsetHeight;
if (divBody.scrollHeight > divHeight) {
var top = divBody.scrollTop;
if (top >= divHeight && isHiddenBody2 !== null) {
document.getElementById('backTop2').removeAttribute('hidden');
isHiddenBody2 = null
} else if (top < divHeight && isHiddenBody2 === null) {
document.getElementById('backTop2').setAttribute('hidden', '');
isHiddenBody2 = ''
}
}
}
function backTop () {
document.getElementsByTagName('body')[0].scrollTop = 0;
}
function backTop2 () {
document.getElementById('bodyDiv').scrollTop = 0;
} |
|
效果预览:https://output.jsbin.com/lezirisahu# html有两个注意点: body,html {
scroll-behavior: smooth;
}
.btn {
position: fixed;
bottom: 0;
right: 0;
width: 100px;
height: 100px;
background: yellow;
border-radius: 50%;
line-height: 100px;
color: gray;
text-align: center;
text-decoration: none;
} <body style="height:5000px;">
<a hidden id="backTop" href="#" class="btn">返回顶部</a>
<div id="box" style="background:pink;height:100px;overflow: scroll;">
我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div我这个div
</div> function scroll(dom) {
var boxHeight = '',
scrollTop = '';
dom.onscroll = function() {
if (dom.nodeName == 'BODY') {
boxHeight = document.documentElement.clientHeight || dom.clientHeight;
scrollTop = document.documentElement.scrollTop || dom.scrollTop;
} else {
boxHeight = dom.clientHeight;
scrollTop = dom.scrollTop;
}
if (scrollTop > boxHeight) {
backTop.removeAttribute('hidden');
} else {
backTop.setAttribute('hidden', '');
}
};
}
var backTop = document.getElementById('backTop'),
boxContent = document.getElementById('box');
// body滚动调用
scroll(document.body);
// div滚动调用
scroll(boxContent); |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 2000px;
background-color: rgba(0,0,0,0.05);
}
#wrapper {
overflow: scroll;
background-color: rgba(0,0,0,0.05);
width: 500px;
height: 500px;
position: relative;
}
#content {
height: 1000px;
background-color: rgba(0,0,0,0.05);
}
#backTop1, #backTop2 {
position: sticky;
left: 0;
top: 200px;
}
</style>
</head>
<body>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Delectus officia earum expedita, iure qui aut, optio aspernatur, tenetur ad dolorum consequatur saepe excepturi itaque nesciunt molestias distinctio amet exercitationem hic.
<a href="#" id="backTop1" hidden>返回顶部↑</a>
<div id="wrapper" >
<div id="content"></div>
<a href="#" id="backTop2" hidden>返回顶部↑</a>
</div>
</body>
<script>
let backTop1 = document.getElementById('backTop1')
let backTop2 = document.getElementById('backTop2')
let wrapper = document.getElementById('wrapper')
let scorllTop = 0
let windowHeight = window.innerHeight || window.outerHeight || document.documentElement.clientHeight
let wrapperHeight = wrapper.innerHeight || wrapper.clientHeight
function throttle (func, time) {
let memo = null
return function (...args) {
if (!memo) {
memo = setTimeout(() => {
func(...args)
memo = null
}, time)
}
}
}
// 当容器为 window
document.addEventListener('scroll', throttle(() => {
scrollTop = document.documentElement.scrollTop
if(windowHeight < scrollTop) {
backTop1.removeAttribute('hidden')
} else {
backTop1.setAttribute('hidden', true)
}
}, 100))
// 当容器为某个元素
wrapper.addEventListener('scroll', throttle(() => {
scrollTop = wrapper.scrollTop
console.log(scorllTop)
if(wrapperHeight < scrollTop) {
backTop2.removeAttribute('hidden')
} else {
backTop2.setAttribute('hidden', true)
}
}, 100))
document.addEventListener('resize', () => {
windowHeight = window.innerHeight || window.outerHeight || document.documentElement.clientHeight
wrapperHeight = wrapper.innerHeight || wrapper.clientHeight
})
</script>
</html> |
题目如下,入门级难度:
使用原生JS代码实现。
大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。
第二小题细节补充:
网页默认固定是HTML或者body,但有时候也可能是DIV,因为布局需要。和题1唯一不同就是容器变了。不要想太多。
The text was updated successfully, but these errors were encountered: