老师你好,关于this.itemWidth = sliderItemEls[0].offsetWidth;的问题。
问题描述:
目录结构
为什么模块里得到的值为1349(浏览器实际可视宽度1366),会少掉17px,导致图片无法填充满页面,第二张图会露出一小部分
如下图:

而在模块外获得的sliderItemEls[0].offsetWidth却没有这种情况,就是浏览器的可视宽度 1366

index.js中的相关代码:
// 常量
const ELEMENT_NODE_TYPE = 1;
const DEFAULTS = {
// 初始索引
initialIndex: 0,
// 切换时是否有动画
animation: true,
// 切换速度,单位 ms
speed: 300,
// 自动切换,单位 ms
// 如果是非0的正数,就自动开始切换
autoplay: 0
};
class BaseSlider {
constructor(el, options) {
// 判断传入的是否为 DOM元素
if (el.nodeType !== ELEMENT_NODE_TYPE) {
throw new Error('实例化的时候,请传入 DOM元素!');
}
this.options = {
...DEFAULTS,
...options
};
const sliderEl = el;
const sliderContentEl = sliderEl.querySelector('.slider-content');
const sliderItemEls = sliderContentEl.querySelectorAll('.slider-item');
// 将上面获得的 DOM元素添加到this上,为了在方法中使用
this.sliderEl = sliderEl;
this.sliderContentEl = sliderContentEl;
this.sliderItemEls = sliderItemEls;
// 索引范围
this.minIndex = 0;
this.maxIndex = sliderItemEls.length - 1;
// 当前索引
this.currIndex = this.getCorrectedIndex(this.options.initialIndex);
// 获取每个slider-item的宽度
this.itemWidth = sliderItemEls[0].offsetWidth;
// 初始化
this.init();
}
// 获取修正后的索引值
getCorrectedIndex(index) {
if (index < this.minIndex) return this.maxIndex;
if (index > this.maxIndex) return this.minIndex;
return index;
};
// 初始化
init() {
// 为每一个 slider-item 设置宽度
this.setItemWidth();
// 为 slider-content 设置宽度
this.setContentWidth();
}
// 为每一个 slider-item 设置宽度
setItemWidth() {
for (const item of this.sliderItemEls) {
item.style.width = `${this.itemWidth}px`;
}
}
// 为 slider-content 设置宽度
setContentWidth() {
this.sliderContentEl.style.width = `${this.itemWidth * this.sliderItemEls.length}px`;
}
}
export default BaseSlider;
index.html中的相关代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>slider-幻灯片</title>
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
ul {
list-style: none;
}
.banner {
width: 100%;
}
.slider,
.slider-content,
.slider-item,
.slider-img {
width: 100%;
height: 100%;
}
.slider {
overflow: hidden;
}
.slider-item {
float: left;
}
.slider-img {
vertical-align: top;
}
.slider-animation {
transition-property: transform;
transition-duration: 0s;
}
</style>
</head>
<body>
<div class="banner">
<div class="slider">
<ul class="slider-content">
<li class="slider-item">
<a href="javascript:;">
<img src="./images/banner_01.jpg" alt="" class="slider-img">
</a>
</li>
<li class="slider-item">
<a href="javascript:;">
<img src="./images/banner_02.jpg" alt="" class="slider-img">
</a>
</li>
<li class="slider-item">
<a href="javascript:;">
<img src="./images/banner_03.jpg" alt="" class="slider-img">
</a>
</li>
<li class="slider-item">
<a href="javascript:;">
<img src="./images/banner_04.jpg" alt="" class="slider-img">
</a>
</li>
<li class="slider-item">
<a href="javascript:;">
<img src="./images/banner_05.jpg" alt="" class="slider-img">
</a>
</li>
</ul>
</div>
</div>
<script type="module">
import Slider from './index.js';
new Slider(document.querySelector('.slider'));
</script>
</body>
</html>
正在回答 回答被采纳积分+1
同学你好,关于同学的问题,老师帮你一步一步来解析:
1、首先,要知道offsetWidth获取的是页面的实际宽度(包含滚动条)
2、右侧出现的空余空间是滚动条的宽度,验证结果如下:

之所以会看到空余,是因为同学将滚动条隐藏掉了,同学设置的代码如下图所示

出现这个问题的原因是浏览器渲染时机不明确,可能在页面加载的一瞬间,样式还没加载完,JS就被执行了,此时页面的内容是竖向依次排列的,会出现滚动条,offsetWidth获取的就是可视区域的宽度,即你电脑的分辨率的宽度是多少,获取到的就是多少,比如老师的电脑分辨是1920x1080,所以获取到的值就是1920,同学的电脑分辨率是1366x768,获取到的就是1366。
备注:这时候,由于代码执行只是一瞬间,我们肉眼是看不到的。
3、在模块中获取的时候会少17像素,就是少了滚动条的宽度,原因是<script type="module">是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,这时结构和样式都加载完了,样式归位,所以在模块中获取的宽度会少17像素。
4、如果想不显示右侧的空余初,解决方案可参考如下:

5、如果想实现在模块外和在模块里获取到的offsetWidth的值一致,可以使用如下方法:

希望可以帮到你,祝学习愉快!
相似问题
登录后可查看更多问答,登录/注册


恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星