如何为Lightbox弹出图片添加第二个水平滚动条?
为Lightbox弹出图片添加顶部水平滚动条解决方案
问题描述
我需要给Lightbox生成的弹出图片添加第二个水平滚动条(顶部),虽然Lightbox默认不会使用滚动条(图片会适配窗口尺寸),但这是客户明确要求。目前图片底部已有滚动条,想在顶部再添加一个。参考了双滚动条的实现方案,但不确定要定位Lightbox里的哪个容器,也想知道能不能用jQuery的append/prepend方法把滚动容器添加到Lightbox生成的标记里,我可以修改本地加载的Lightbox脚本。
实现步骤
1. 定位目标容器
Lightbox中承载图片的核心容器是.lb-outerContainer,我们需要在.lightbox内部、.lb-outerContainer上方插入顶部滚动容器,并让它和底部的滚动容器(将.lightbox改造为底部滚动容器)同步滚动。
2. 动态改造DOM结构
在Lightbox打开后,动态插入顶部滚动容器,并复制图片宽度到该容器,保证滚动范围完全一致。
3. 同步滚动事件
监听两个滚动容器的滚动事件,让它们的滚动位置实时保持同步。
4. 调整样式适配
给顶部滚动容器设置专属样式,隐藏垂直滚动条,只保留水平滚动条,同时调整容器间距避免布局错乱。
完整代码
HTML
<a href="https://fastly.picsum.photos/id/11/2500/1667.jpg?hmac=xxjFJtAPgshYkysU_aqx2sZir-kIOjNR9vx0te7GycQ" data-lightbox="1"> <img src="https://fastly.picsum.photos/id/11/2500/1667.jpg?hmac=xxjFJtAPgshYkysU_aqx2sZir-kIOjNR9vx0te7GycQ" width="300"> </a>
修改后的CSS
body.lb-disable-scrolling { overflow: hidden; } .center { text-align: center; } /* 顶部滚动容器样式 */ .lb-top-scroll { overflow-x: scroll; overflow-y: hidden; margin: 0 auto; margin-top: 30px; } .lb-top-scroll-inner { height: 1px; /* 仅保留滚动条,不需要额外高度 */ } .lightboxOverlay { position: absolute; top: 0; left: 0; z-index: 9999; background-color: black; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); opacity: 0.8; display: none; } .lightbox { position: absolute; left: 0; width: 100%; z-index: 10000; text-align: center; line-height: 0; font-weight: normal; outline: none; overflow-x: auto; /* 底部滚动条 */ } .lightbox .lb-image { display: block; width: 100% !important; height: auto !important; border-radius: 3px; border: 4px solid white; } .lightbox a img { border: none; } .lb-outerContainer { position: relative; *zoom: 1; margin: 0 auto; border-radius: 4px; background-color: white; } .lb-outerContainer:after { content: ""; display: table; clear: both; } .lb-loader { position: absolute; top: 43%; left: 0; height: 25%; width: 100%; text-align: center; line-height: 0; } .lb-cancel { display: block; width: 32px; height: 32px; margin: 0 auto; background: url(../images/loading.gif) no-repeat; } .lb-nav { position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; } .lb-container > .nav { left: 0; } .lb-nav a { outline: none; background-image: url("data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="); } .lb-prev, .lb-next { height: 100%; cursor: pointer; display: block; } .lb-nav a.lb-prev { width: 20%; left: 0; float: left; background: url(../images/prev.png) left 48% no-repeat; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); opacity: 0; -webkit-transition: opacity 0.6s; -moz-transition: opacity 0.6s; -o-transition: opacity 0.6s; transition: opacity 0.6s; } .lb-nav a.lb-prev:hover { filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); opacity: 1; } .lb-nav a.lb-next { width: 20%; right: 0; float: right; background: url(../images/next.png) right 48% no-repeat; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); opacity: 0; -webkit-transition: opacity 0.6s; -moz-transition: opacity 0.6s; -o-transition: opacity 0.6s; transition: opacity 0.6s; } .lb-nav a.lb-next:hover { filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); opacity: 1; } .lb-dataContainer { margin: 0 auto; padding-top: 5px; *zoom: 1; width: 100%; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } .lb-dataContainer:after { content: ""; display: table; clear: both; } .lb-data { padding: 0 4px; color: #ccc; } .lb-data .lb-details { width: 85%; float: left; text-align: left; line-height: 1.1em; } .lb-data .lb-caption { font-size: 13px; font-weight: bold; line-height: 1em; } .lb-data .lb-caption a { color: #4ae; } .lb-data .lb-number { display: block; clear: left; padding-bottom: 1em; font-size: 12px; color: #999999; } .lb-data .lb-close { display: block; float: right; width: 30px; height: 30px; background: url(../images/close.png) top right no-repeat; text-align: right; outline: none; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70); opacity: 0.7; -webkit-transition: opacity 0.2s; -moz-transition: opacity 0.2s; -o-transition: opacity 0.2s; transition: opacity 0.2s; position: absolute; top: 10px; right: 20px; } .lb-data .lb-close:hover { cursor: pointer; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); opacity: 1; } .lb-linkContainer { position: relative; } #lightbox.active { cursor: grabbing; } .lb-closeContainer { background: rgba(0, 0, 0, 0.5); left: 0; width: 100%; height: 50px; position: fixed; top: 0; z-index: 99; } .admin-bar .lb-closeContainer { top: 32px; } .lb-closeContainer:before { content: "<-- Esc to close image. Use scroll bar to move left and right on wide images -->"; color: white; font-size: 18px; position: relative; top: 25px; }
jQuery脚本
// 监听Lightbox打开事件 $(document).on('click', '[data-lightbox]', function() { // 延迟执行,确保Lightbox DOM已完全生成 setTimeout(function() { const $lightbox = $('.lightbox'); const $lbOuter = $('.lb-outerContainer'); const imgWidth = $('.lb-image').width(); // 插入顶部滚动容器 $lightbox.prepend(` <div class="lb-top-scroll"> <div class="lb-top-scroll-inner" style="width: ${imgWidth}px;"></div> </div> `); const $topScroll = $('.lb-top-scroll'); // 双向同步滚动位置 $lightbox.on('scroll', function() { $topScroll.scrollLeft($(this).scrollLeft()); }); $topScroll.on('scroll', function() { $lightbox.scrollLeft($(this).scrollLeft()); }); // 调整图片容器的margin,避免顶部滚动容器导致间距过大 $lbOuter.css('margin-top', '0'); }, 300); }); // 关闭Lightbox时移除顶部滚动容器,避免残留 $(document).on('click', '.lb-close', function() { $('.lb-top-scroll').remove(); });
说明
- 利用Lightbox打开后的DOM生成时机,动态插入顶部滚动容器,通过复制图片宽度保证滚动范围一致。
- 通过监听两个容器的
scroll事件,实现滚动位置的双向同步,操作任意一个滚动条都会同步到另一个。 - 调整了
.lb-outerContainer的margin-top,避免顶部滚动容器和图片容器之间出现多余间距,保证布局美观。
内容的提问来源于stack exchange,提问作者user5853892
相关产品推荐
相关产品推荐

