jQuery scrollLeft()取值始终显示为0的问题排查与实现
scrollLeft() 始终返回0的原因说明
问题诱因
- 取值时机完全错误
你初始代码里var leftOffset = $('.categories__list').scrollLeft();是写在点击事件绑定逻辑之外的,这行代码会在页面加载完成、DOM刚渲染完的时候立刻执行,此时元素还没有发生任何滚动,滚动位置本来就是0。你把这个初始的0存在变量里,后续不管元素怎么滚动,点击事件里弹出的永远是页面初始化时存的固定值,根本不是元素实时的滚动位置。
你提到W3School的示例可以正常弹出取值,核心差异就是示例里的scrollLeft()调用是写在事件回调函数内部的,每次触发点击/滚动事件时,都会重新去读取元素当下的滚动位置,不会提前把初始值缓存下来,自然能拿到正确结果。 - 目标元素默认不具备横向滚动能力
你代码里的.categories__list是普通ul块级元素,默认样式下内部内容溢出会自动换行,根本不会产生横向滚动条,没有滚动行为自然也就不存在非0的滚动偏移量。要让横向滚动逻辑生效,必须先给元素添加对应的CSS样式,开启横向滚动能力:.categories__list { overflow-x: auto; white-space: nowrap; /* 如果要隐藏原生滚动条,完全用自定义箭头控制,可以加以下样式 */ scrollbar-width: none; } .categories__list::-webkit-scrollbar { display: none; } - 额外的DOM结构问题
你提供的HTML代码里存在标签嵌套、闭合顺序错误的问题,比如<a href="categories__link">Počítače</li></a>这种写法会导致浏览器自动修正DOM结构,可能出现元素层级不符合预期的情况,建议把所有a标签都放在li标签内部,保证开标签和闭合标签顺序对应,避免出现意外的渲染问题。
现有代码优化建议
你后续写的动画滚动代码已经能实现基础交互,但还有两个可以调整的点:
- 目前
scrollEnd取值为容器自身宽度,当列表总长度远大于容器宽度时,点击一次右箭头无法滚动到列表最右侧,可以把滚动终点改为元素的最大可滚动距离:var $categoryList = $('.categories__list'); // 最大滚动距离 = 元素总内容宽度 - 元素可视区域宽度 var maxScroll = $categoryList[0].scrollWidth - $categoryList.width(); $('.right-arrow').click(function (e) { e.preventDefault(); $categoryList.animate({scrollLeft: maxScroll}, 1000) }) $('.left-arrow').click(function (e) { e.preventDefault(); $categoryList.animate({scrollLeft: 0}, 1000) }) - 事件回调里建议显式传入事件对象(比如上面代码里的
e),再调用e.preventDefault(),避免部分浏览器下无法直接读取全局event对象导致的报错。
内容的提问来源于stack exchange,提问作者Dump
相关产品推荐
相关产品推荐

