滚动时动态切换关注链接颜色的实现方案问询
实现社交图标随重叠区块单独切换颜色
需求:固定定位的社交图标,在滚动过程中,当单个图标与.intro、.intro2区块重叠时,单独为该图标添加/移除use-inverted-colors类,实现颜色切换,而非一次性修改所有图标。
完整代码实现
HTML 结构
<section class="intro"> <div class="content "> <h1>无需JavaScript即可创建全屏区块。</h1> <p>高度设置为90vh,即视口高度的90%。</p> </div> </section> <section class="intro1"> <div class="content "> <h1>调整浏览器窗口大小,看看区块如何自适应。</h1> </div> </section> <section class="intro2"> <div class="content"> <h1>简单又高效。</h1> </div> </section> <section> <div class="content"> <h1>查看<a href="http://caniuse.com/#feat=viewport-units">浏览器支持情况</a>。</h1> </div> </section> <footer> 由<a href="https://www.twitter.com/ckor">@ckor</a>制作 </footer> <ul class="et_pb_module et_pb_social_media_follow et_pb_social_media_follow_0 clearfix et_pb_text_align_center et_pb_bg_layout_light"> <li class="et_pb_social_media_follow_network_0 et_pb_social_icon et_pb_social_network_link et-social-facebook"><a href="#" class="icon et_pb_with_border" title="关注Facebook" target="_blank"><span class="et_pb_social_media_follow_network_name" aria-hidden="true">关注</span></a></li><li class="et_pb_social_media_follow_network_1 et_pb_social_icon et_pb_social_network_link et-social-instagram"><a href="#" class="icon et_pb_with_border" title="关注Instagram" target="_blank"><span class="et_pb_social_media_follow_network_name" aria-hidden="true">关注</span></a></li> </ul>
CSS 样式
* { box-sizing: border-box; } body { margin: 0; font-weight: 500; font-family: "HelveticaNeue"; } section { width: 100%; padding: 0 7%; display: table; margin: 0; max-width: none; background-color: #373B44; height: 100vh; } section:nth-of-type(2n) { background-color: #FE4B74; } .intro { height: 90vh; } .content { display: table-cell; vertical-align: middle; } h1 { font-size: 3em; display: block; color: white; font-weight: 300; } p { font-size: 1.5em; font-weight: 500; color: #C3CAD9; } a { font-weight: 700; color: #373B44; position: relative; } a:hover { opacity: 0.8; } a:active { top: 1px; } footer { padding: 1% 5%; text-align: center; background-color: #373B44; color: white; } footer a { color: #FE4B74; font-weight: 500; text-decoration: none; } .et_pb_social_media_follow { position: fixed; left: 30px; top: 50%; transform: translateY(-50%); /* 让图标垂直居中更精准 */ } .icon { color: #373B44; /* 默认图标颜色 */ transition: color 0.2s ease; /* 添加入色过渡动画 */ } .icon.use-inverted-colors { color: #fff; /* 重叠时的反转颜色 */ }
JavaScript 核心逻辑
class BarracudaOverlapping{ constructor(){ this.setOverlaping(); window.addEventListener("scroll", this.setOverlaping.bind(this)); window.addEventListener("resize", this.setOverlaping.bind(this)); } setOverlaping(){ // 选择每个社交图标元素 document.querySelectorAll(".et_pb_social_media_follow .icon").forEach(el=>{ let isOverlapping = false; // 遍历所有目标背景区块 document.querySelectorAll(".intro,.intro2").forEach(background=>{ if(this.isOverlapping(el, background)){ isOverlapping = true; } }); // 根据重叠状态单独切换类名 if(isOverlapping){ el.classList.add("use-inverted-colors"); } else { el.classList.remove("use-inverted-colors"); } }); } check(){ this.setOverlaping(); } isOverlapping(el1, el2){ // 处理集合类元素,取第一个 if (el1.length && el1.length > 1) { el1 = el1[0]; } if (el2.length && el2.length > 1){ el2 = el2[0]; } // 获取元素的边界矩形 const rect1 = el1 instanceof Element ? el1.getBoundingClientRect() : false; const rect2 = el2 instanceof Element ? el2.getBoundingClientRect() : false; let overlap = false; if (rect1 && rect2) { // 判断两个矩形是否重叠 overlap = !( rect1.right < rect2.left || rect1.left > rect2.right || rect1.bottom < rect2.top || rect1.top > rect2.bottom ); return overlap; } console.warn('传入的不是有效的HTML元素'); return overlap; } } // 初始化实例 new BarracudaOverlapping();
关键修改说明
- 选择器修正:原JS中的选择器与HTML结构不匹配,改为
.et_pb_social_media_follow .icon,确保正确选中每个图标。 - 逐个处理逻辑:遍历每个图标,单独判断其与目标区块的重叠状态,实现单个图标的颜色切换,而非批量操作。
- 体验优化:CSS中添加了颜色过渡动画,让颜色切换更平滑;给固定图标添加
transform: translateY(-50%),确保垂直居中更精准。
内容的提问来源于stack exchange,提问作者Sushil Thapa
相关产品推荐
相关产品推荐

