老师你好,关于this.itemWidth = sliderItemEls[0].offsetWidth;的问题。

老师你好,关于this.itemWidth = sliderItemEls[0].offsetWidth;的问题。

问题描述:

http://img1.sycdn.imooc.com//climg/6052183c0926245401570200.jpg目录结构

http://img1.sycdn.imooc.com//climg/6052185b095cad4303670029.jpg 

为什么模块里得到的值为1349(浏览器实际可视宽度1366),会少掉17px,导致图片无法填充满页面,第二张图会露出一小部分

如下图:

http://img1.sycdn.imooc.com//climg/6052192c0974a11e13660483.jpg

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

http://img1.sycdn.imooc.com//climg/60521a5b09fe6be006900681.jpg



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

登陆购买课程后可参与讨论,去登陆

2回答
樱桃小胖子 2021-04-16 20:18:14

同学你好,关于同学的问题,老师帮你一步一步来解析:

1、首先,要知道offsetWidth获取的是页面的实际宽度(包含滚动条)

2、右侧出现的空余空间是滚动条的宽度,验证结果如下:

http://img1.sycdn.imooc.com//climg/60797bea0a645bf505000252.jpg

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

http://img1.sycdn.imooc.com//climg/607979840914541203110096.jpg

出现这个问题的原因是浏览器渲染时机不明确,可能在页面加载的一瞬间,样式还没加载完,JS就被执行了,此时页面的内容是竖向依次排列的,会出现滚动条,offsetWidth获取的就是可视区域的宽度,即你电脑的分辨率的宽度是多少,获取到的就是多少,比如老师的电脑分辨是1920x1080,所以获取到的值就是1920,同学的电脑分辨率是1366x768,获取到的就是1366。

备注:这时候,由于代码执行只是一瞬间,我们肉眼是看不到的。

3、在模块中获取的时候会少17像素,就是少了滚动条的宽度,原因是<script type="module">是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,这时结构和样式都加载完了,样式归位,所以在模块中获取的宽度会少17像素。

4、如果想不显示右侧的空余初,解决方案可参考如下:

http://img1.sycdn.imooc.com//climg/60797d7b0981822415040577.jpg

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

http://img1.sycdn.imooc.com//climg/60797e5109816c3211040349.jpg

希望可以帮到你,祝学习愉快!

好帮手慕言 2021-03-18 14:11:53

同学你好,可能是解析问题,建议:可以添加window.onload试试,如下:

http://img1.sycdn.imooc.com//climg/6052e7ca097e5d0905060300.jpg

如果要解决会显示第二张的一部分内容,可以给body添加上溢出隐藏,如下:

http://img1.sycdn.imooc.com//climg/6052ef0309f9c57403730206.jpg

祝学习愉快~

  • hustnzj #1

    第二张图片设置隐藏完全不对啊,请问你测试过吗?

    2021-04-16 11:29:19
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师