angularjs 指令实现自定义滚动条

news2024/11/24 2:01:41

场景:横向商品栏,把原有的滚动条改成自定义的样式,并且给两边加上箭头可以调整,可以拖动商品和滚轮实现滚动条效果。

js

appService.directive('customScrollbar', function() {
    return {
        restrict: 'A',
        transclude: true,
        scope: {
            enableMouseWheel: '=?' // default false
        },
        template: `
            <div class="customScrollbar">
                <div class="scrollContent">
                    <div class="detailContent" ng-mouseenter="enableMouseWheel === true && enableWheelScroll()" ng-mouseleave="enableMouseWheel === true && disableWheelScroll()" id="detailContent" ng-transclude>
                    </div>
                    <div class="scrollBarContent">
                        <div class="scrollbar">
                            <div class="scrollbar-thumb"></div>
                        </div>
                        <img src="./images/home/icon_left.png" alt="Left Arrow" class="scroll-arrow left">
                        <img src="./images/home/icon_right.png" alt="Right Arrow" class="scroll-arrow right">
                    </div>
                </div>
            </div>

        `,
        link: function(scope, element) {
            if (scope.enableMouseWheel === undefined) {
                scope.enableMouseWheel = false;
            }
            var content = element.find('.detailContent');
            var scrollbar = element.find('.scrollbar');
            var thumb = element.find('.scrollbar-thumb');
            var leftArrow = element.find('.scroll-arrow.left');
            var rightArrow = element.find('.scroll-arrow.right');

            checkArrowVisibilityByInit();

            content.scroll(function() {
                var scrollLeft = content.scrollLeft();
                var scrollRatio = scrollLeft / (content[0].scrollWidth - content.width());
                var newLeft = scrollRatio * (scrollbar.width() - thumb.width());
                thumb.css('left', newLeft);
                checkArrowVisibilityByScroll(scrollLeft);
            });

            leftArrow.click(function() {
                var newScrollLeft = content.scrollLeft() - 500;
                content.animate({scrollLeft: newScrollLeft}, 500);
            });

            rightArrow.click(function() {
                var newScrollLeft = content.scrollLeft() + 500;
                content.animate({scrollLeft: newScrollLeft}, 500);
            });


            var isDragging = false;
            var startX, startLeft;
            thumb.mousedown(function(e) {
                isDragging = true;
                startX = e.pageX;
                startLeft = thumb.position().left;
                e.preventDefault();
            });

            $(document).mousemove(function(e) {
                if (isDragging) {
                    var offsetX = e.pageX - startX;
                    var newLeft = Math.min(Math.max(0, startLeft + offsetX), scrollbar.width() - thumb.width());
                    var scrollRatio = newLeft / (scrollbar.width() - thumb.width());
                    var newScrollLeft = scrollRatio * (content[0].scrollWidth - content.width());
                    thumb.css('left', newLeft);
                    content.scrollLeft(newScrollLeft);
                }
            }).mouseup(function() {
                isDragging = false;
            });

            function checkArrowVisibilityByInit() {
                if (content.width() >= content[0].scrollWidth) {
                    leftArrow.hide();
                    rightArrow.hide();
                } else {
                    leftArrow.hide(); //init content.scrollLeft() = 0;
                    rightArrow.show();
                }
            }

            function checkArrowVisibilityByScroll(scrollLeft) {
                if (scrollLeft === 0) {
                    leftArrow.hide();
                } else {
                    leftArrow.show();
                }
                if (scrollLeft >= content[0].scrollWidth - content.width()) {
                    rightArrow.hide();
                } else {
                    rightArrow.show();
                }
            }
            //============ Enable wheel scrolling when mouse enters
            scope.enableWheelScroll = function() {
                element.on('wheel', function(e) {
                    e.preventDefault();
                    const delta = e.originalEvent.deltaY;
                    content.scrollLeft(content.scrollLeft() + delta);
                });
            };
            scope.disableWheelScroll = function() {
                element.off('wheel');
            };
            //============ end
            //============ Implement scrollbar effect when dragging products with the mouse
            var isFinancialContentMouseDown = false;
            var startX;
            var scrollLeft;

            content.on('mousedown', function(e) {
                isFinancialContentMouseDown = true;
                startX = e.pageX - $(this).offset().left;
                scrollLeft = $(this).scrollLeft();
            });

            content.on('mousemove', function(e) {
                if (!isFinancialContentMouseDown) return;
                e.preventDefault();
                const x = e.pageX - $(this).offset().left;
                const walk = (x - startX) * 3;
                $(this).scrollLeft(scrollLeft - walk);
            });

            $(document).on('mouseup', function() {
                isFinancialContentMouseDown = false;
            });

            content.on('mouseleave', function() {
                isFinancialContentMouseDown = false;
            });
            //============end
        }
    };
});

css

/*customscroll*/
.customScrollbar .detailContent{width: 100%;display: flex;margin-top: 102px;gap: 30px;overflow-y: auto;overflow-x: hidden;}
.customScrollbar .scrollContent{position: relative}
.customScrollbar .scrollBarContent{width: 100%;display: flex;justify-content: center;margin-top: 40px}
.customScrollbar .scrollbar {width: 410px;height: 6px;background-color: #DAD2D2;position: absolute;bottom: 0;left: 50%;cursor: pointer;border-radius: 15px;transform: translateX(-50%);}
.customScrollbar .scrollbar-thumb {width: 96px;height: 133%;background-color: #E43134;position: absolute;left: 0;cursor: pointer;border-radius: 15px;top:-1px}
.customScrollbar .scroll-arrow {position: absolute;top:  calc(50% - 40px);;transform: translateY(-50%);cursor: pointer;}
.customScrollbar .scroll-arrow.left {left: 0;transform: translateX(-150%);width: 44px;height: 44px;}
.customScrollbar .scroll-arrow.right {right: 0;transform: translateX(150%);width: 44px;height: 44px;}

html

						<!--  custom-scrollbar="home"可以改成 custom-scrollbar,
						加了home是为了后面可能有多个滚动条的时候添加的唯一标识,但代码还没实现,遇到再改-->
				<div custom-scrollbar="home">
				<!-- 里面的item自己填上,一般都是循环load items出来-->
					<div class="box textBg fundBg">
						<span class="text">{{'webPage.body.home.A'|translate}}</span>
					</div>
					<div class="box textBg bondBg">
						<span class="text">{{'webPage.body.home.B'|translate}}</span>
					</div>
					<div class="box textBg structureBg">
						<span class="text">{{'webPage.body.home.C'|translate}}</span>
					</div>
					<div class="box textBg cryptocurrencyBg">
						<span class="text">{{'webPage.body.home.D'|translate}}</span>
					</div>
					<div class="box textBg swapsBg">
						<span class="text">{{'webPage.body.home.E'|translate}}</span>
					</div>
				</div>

效果

效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1528420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB环境下基于离散小波变换和主成分平均的医学图像融合方法

随着计算机技术和生物影像工程的日趋成熟&#xff0c;医学图像为医疗诊断提供的信息越来越丰富。目前&#xff0c;由于医学成像的设备种类繁多&#xff0c;导致医生获得的图像信息差异较大。如何把这些信息进行整合供医生使用成为当务之急。基于此&#xff0c;医学图像融合技术…

php 对接Mintegral汇量海外广告平台收益接口Reporting API

今天对接的是Mintegral广告reporting api接口&#xff0c;拉取广告收益回来自己做统计。记录分享给大家 首先是文档地址,进入到Mintegral后台就能看到文档地址以及参数&#xff1a; 文档地址&#xff1a;https://cdn-adn-https.rayjump.com/cdn-adn/reporting_api/MintegralRA.…

2024你值得拥有,Go语言入门学习线路推荐

“小众”的编程语言的Go语言在今年2月成功挤进TOIBE排行榜前10&#xff0c;3月稳居第8名。从最低时的第122名&#xff0c;到现在第8名&#xff0c;Go 的身影越来越清晰。 其实它早已被广泛应用于云计算、大数据、区块链、微服务、游戏开发等领域&#xff0c;因而也有越来越多的…

相比于 HTTP 协议,WebSocket协议的必要性体现在哪里?

HTTP 协议的一个缺点 从 HTTP 协议的角度来看&#xff0c;就是点一下网页上的某个按钮&#xff0c;前端发一次 HTTP请 求&#xff0c;网站返回一次 HTTP 响应。这种由客户端主动请求&#xff0c;服务器响应的方式也满足大部分网页的功能场景。但是有没有发现&#xff0c;在HTTP…

WiFi7为什么需要6G频谱

从5925MHz到7125MHz&#xff0c;整整1200MHz的频谱&#xff0c;都被分配给了WiFi7。非常得豪&#xff01; 只是国内还没有这个东西。 为什么要这么宽的频谱呢&#xff1f; Intel作过实验&#xff0c;发现在日常的场合下 一定是3个320MHz宽的不重叠信道&#xff0c;方能达到AV/…

小游戏实战-Python实现石头剪刀布+扫雷小游戏

小游戏实战-Python实现石头剪刀布扫雷小游戏 我想说废话止于此石头剪刀布-入门必学游戏游戏规则实现思路示例代码知识要点运行效果 扫雷-内网摸鱼必备游戏游戏规则实现思路示例代码知识要点运行效果 进阶练习-走迷宫&#xff08;预留&#xff09;游戏规则预期效果 总结 我想说 …

算法第三十天-矩阵中移动的最大次数

矩阵中移动的最大次数 题目要求 解题思路 网格图 DFS 从第一列的任一单元格 ( i , 0 ) (i,0) (i,0) 开始递归。枚举往右上/右/右下三个方向走&#xff0c;如果走一步后&#xff0c;没有出界&#xff0c;且格子值大于 g r i d [ i ] [ j ] grid[i][j] grid[i][j]&#xff0c;则…

Java使用itextpdf往pdf中插入图片

引入maven依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.9</version> </dependency>java代码 import cn.hutool.extra.qrcode.QrCodeUtil; import com.itextpdf.text.*; i…

华为携手8家企业打造“AI大模型+行业”生态网络 | 百能云芯

据媒体报道&#xff0c;在“大模型行业创新合作计划”签约仪式上&#xff0c;华为云携手循环智能、迪安诊断、零浩网络、云译科技、蓝青教育、航天天目、标普云、乐聚机器人等8家企业&#xff0c;共同开启了一段全新的合作旅程。 这次合作将聚焦于“AI大模型行业”的应用开发&a…

IP代理的认证方式和协议介绍

“IP代理是指使用固定的IP地址作为代理服务器进行代理访问的方式。在网络应用中&#xff0c;IP代理可以为用户提供更加稳定的代理服务&#xff0c;同时也提高了访问网站的安全性。IP代理的认证方式和协议是实现代理服务的重要组成部分。” 一、认证方式 1.用户名和密码认证&am…

RK平台第一次开机速度优化 “Large app, accepted running with swap.“

RK平台第一次开机速度优化 "Large app, accepted running with swap." 问题描述解决方法 郑重声明:本人原创博文&#xff0c;都是实战&#xff0c;均经过实际项目验证出货的 转载请标明出处:攻城狮2015 Platform: Rockchip OS:Android 6.0.1 CPU:3368 Kernel: 3.10 问…

Elasticsearch:使用 OpenAI、LangChain 和 Streamlit 的基于 LLM 的 PDF 摘要器和 Q/A 应用程序

嘿&#xff01; 您是否曾经感觉自己被淹没在信息的海洋中&#xff1f; 有这么多的书要读&#xff0c;而时间却这么少&#xff0c;很容易就会超负荷&#xff0c;对吧&#xff1f; 但猜猜怎么了&#xff1f; 你可以使用大型语言模型创建自定义聊天机器人&#xff0c;该模型可以帮…

重磅升级!P230焕新而来,支持双目SLAM+YOLO点击跟踪,算力高达100TOPS

全新升级的Prometheus 230科研无人机&#xff08;简称P230&#xff09;是一款专为科研工作者及开发者设计的小型&#xff08;250mm轴距&#xff09;无人机实验平台。机载计算机升级为算力100TOPS的Allspark2-Orin NX&#xff0c;结合Prometheus自主无人机开源项目和Prometheus专…

H4010耐压40V降压恒压芯片 40V降12V降5V 支持电流2.5A

H4010是一种内置30V耐压MOS&#xff0c;并且能够实现精确恒压以及恒流的同步降压型 DC-DC 转换器&#xff1b; 支持 1A 持续输出电流输出电压可调&#xff0c;最大可支持 100%占空比&#xff1b;通过调节 FB 端口的分压电阻&#xff0c;可以输出 2.5V到 22V 的稳定电压 。H4010…

一文快速掌握docker的理念和基本使用

写在文章开头 写于一个周末&#xff0c;在复盘梳理文章时候发现这一篇关于早期了解docker时记录的文档&#xff0c;仔细阅读了一下&#xff0c;为了保证文章更加清晰以便读者使用。故再次重新一次梳理一次&#xff0c;通过这篇文章&#xff0c;你将会对docker的基本理念和基础…

Machine Learning ---- Gradient Descent

目录 一、The concept of gradient&#xff1a; ① In a univariate function&#xff1a; ②In multivariate functions&#xff1a; 二、Introduction of gradient descent cases&#xff1a; 三、Gradient descent formula and its simple understanding: 四、Formula o…

GPIO和Pinctrl子系统的使用

一、 Pinctrl子系统 1、基本架构 现在的芯片动辄几百个引脚&#xff0c;在使用到GPIO功能时&#xff0c;让你一个引脚一个引脚去找对应的寄存器&#xff0c;说实话很烦。所以&#xff0c;要把引脚的复用、配置抽出来&#xff0c;做成Pinctrl子系统&#xff0c;给GPIO、UART等模…

2082.找单词

动态规划问题&#xff1a; 先声明两个数组&#xff1a; 数组 a&#xff1a;存储当前状态下&#xff0c;所有可能的单词价值总和的计数。在每次迭代开始时&#xff0c;我们使用 a 数组来跟踪包含当前字母之前的所有可能单词的价值总和。 数组 b&#xff1a;在处理每个字母时&a…

XMind for mac/Win:解锁思维新境界,让思维导图成为你的创意引擎

在信息爆炸的时代&#xff0c;如何高效地整理思绪、捕捉灵感&#xff0c;成为每个人都需要面对的挑战。而XMind&#xff0c;作为一款功能强大的思维导图软件&#xff0c;正以其独特的魅力&#xff0c;帮助无数用户解锁思维新境界&#xff0c;让思维导图成为他们的创意引擎。 无…

idea远程试调jar、远程试调war

idea远程试调jar、远程试调war 目的&#xff1a;测试运行时与ide开发时是否一致。 配置jar Maven中添加 <packaging>jar</packaging>将其打包为jar。 设置运行入口main 编译jar 看到jar输出 配置试调 添加jar运行 远程试调 先在源码中打好断点试调 debug运行…