- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
本随笔只是记录一下大概的实现思路,如果感兴趣的小伙伴可以通过代码和本随笔的说明去理解实现过程。👉我的 Gitee 和 GitHub 地址。注意哦:这个只是 PC 上的标签页,手机端的没用,因为监听器是 mouse,而不是手势.
在线浏览地址: 10.标签页 .
可滑动的页面需要 5 个 div,标签也需要 5 个。只有页面是随着我们操作而变化,标签处于静态,标签下面有一个滑块也是随着我们操作而变化。所以,构建基本的 HTML 骨架如下:
<div>
<!-- 标签 -->
<div class="tab-bar flex-space">
<div class="bar-item flex-center">标签5</div>
<div class="bar-item flex-center">标签1</div>
<div class="bar-item flex-center">标签2</div>
<div class="bar-item flex-center">标签3</div>
<div class="bar-item flex-center">标签4</div>
<!-- 滑块 -->
<div class="slider"></div>
</div>
<!-- 标签页 -->
<div class="tab-page">
<div class="page-item page-5">Index 5</div>
<div class="page-item page-1">Index 1</div>
<div class="page-item page-2">Index 2</div>
<div class="page-item page-3">Index 3</div>
<div class="page-item page-4">Index 4</div>
</div>
</div>
我写的这个标签页的起始标签是5,而不是标签1。下面直接给上默认的 CSS,如果不全,就去仓库找:
.tab-bar {
width: 100%;
height: 40px;
position: relative;
margin-bottom: 8px;
}
.bar-item {
margin: 0;
padding: 0;
cursor: pointer;
}
.slider {
position: absolute;
background-color: #5677fc;
transform: translateX(0%);
width: 35px;
height: 3px;
background-color: blue;
border-radius: 3px;
bottom: 0;
transition: all 0.2s ease-in-out;
}
.tab-page {
overflow-x: hidden;
position: relative;
width: 100%;
height: calc(100vh - 64px);
transition: all 0.2s ease-in-out;
transform: translate(0%, 0px) translateZ(0px);
}
.page-item {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
transition: all 0.5s ease-in-out;
text-align: center;
font-size: 50px;
}
.page-1 {
background-color: rgb(169, 187, 228);
}
.page-2 {
background-color: #5677fc;
}
.page-3 {
background-color: rgb(101, 192, 225);
}
.page-4 {
background-color: rgb(153, 60, 235);
}
.page-5 {
background-color: coral;
}
slider 滑块通过 transform: translateX() 来平移,默认滑块所在位置是标签1 的位置,现在的问题是如何定义滑块默认的位置、以及每一次往前移动一个标签需要多少距离.
获取 tab-bar 滑块容器的宽度,并且去除容器的 padding 和 margin 值,计算每一个标签所占的长度是多少:
let tabbarWidth = $(".tab-bar").width();
let barItemLength = $(".tab-bar").find("div").length - 1;
let barItemPerWidth = tabbarWidth / barItemLength;
滑块的宽度是 35px,假设一个标签的宽度是 99px。要让这个滑块处于标签的中间,就得让滑块左边缘定在如下图所示的地方:
标签的一半再减去滑块的一半就是滑块左边缘的位置,从而使得滑块处于标签的中央。滑块的宽度可以用一个变量来代替,可以考虑让滑块自适应 tab-bar 容器宽度,这里就用实际数字了:
let sliderTranslateX = barItemPerWidth / 2 - 35 / 2;
滑块往前移动,移动多少呢?实际可以如下图这样思考,第一个标签往前移动了一个标签的长度,相当于滑块也跟随着这个标签往前移动,来到了下一个标签的位置。当然,这个标签是不会动的,只有滑块在移动.
滑块往前移动一次,到下一个标签,实际就是 sliderTranslateX + barItemPerWidth 。前面说了,滑块默认在标签1 的下面:
$(".slider").css({ transform: `translateX(${sliderTranslateX + barItemPerWidth}px)` });
刷新页面,如下图所示,滑块来到了标签1 的下面:
现在,实现点击事件,往前(往右)挨个点击标签,滑块跟随我们点击的位置进行平移.
let moveTranslateX = 0;
function moveSlider(index) {
// 0 1 2 3 4 5 6
// 17 77 137 207 .. .. ..
moveTranslateX = sliderTranslateX + barItemPerWidth * index;
$(".slider").css({ transform: `translateX(${moveTranslateX}px)` });
}
$(".tab-bar")
.find(".bar-item")
.each((index, elem) => {
// 平均地设置每一个 tabBar 的宽度
$(elem).css({ width: `${barItemPerWidth}px` });
// 给每一个 tabBar 添加踢点击事件
$(elem).on("click", e => {
moveSlider(index);
});
});
主要看 moveSlider() 这个函数,通过 each 遍历每一个标签,并给其注册一个点击事件,点击事件中,给 moveSlider 传递当前标签的 index(索引值)。假设,index 大于 0,说明我们是往前挨个点击着走的,那么,moveTranslateX 的值就是 sliderTranslateX 加上 barItemPerWidth,以及乘以 index.
index 是 1,就是往前滑动一个标签的距离。但目前,我们只可能(只考虑往前点击)从 index 1 开始点击,所以 index 是 2,滑块从标签5 的位置往前移动了两个标签的距离,来到了标签3 的底下:
Now!滑块的移动功能就已经实现了:
我是把页面放在数组里面进行思考的。第一行是初始的状态,5、1、2、3、4 标签页在数组中排着。往前拉(鼠标往右滑动)标签页1、2、3、4 的 index 依次往前 +1;唯独标签页5 排在数组末尾处.
继续往前拉,标签页2、3、4、5 的 index 依次往前 +1;标签页1 排在数组末尾处。依次类推,直到第5行的下一次,才跳回到第1行继续循环上面的规律.
第1行变成第2行的样子,要经历 5 次排序,每一次排序都会破坏原有的数组结构,因此我在写的时候,定义了两个空数组,一个用来存储之前的顺序,且不改变这个数组的结构和顺序,排序完成之后的元素依次插入到第二个数组中.
let tempTabPageBox = [];
let movedTabPageBox = [];
这里还考察到了一个知识点,JS 中对象通过等号赋值是地址引用,而不是拷贝。所以,我这里用的 new Array(...arr) 来拷贝了一份新的数组对象给第二个数组。我推荐看 对象引用和复制 来理解对象的拷贝知识.
原本我用的是 JSON.parse(JSON.stringfy(arr)) 拷贝一个数组,但是这种方式会丢失很多 DOM 原本的字段。因为,数组里面存储的是一个个 DOM 对象,所以这种方式拷贝不适用于现在的情况。所以,我就改用了 new Array(...arr) 来 new 一个新数组,可能会导致性能降低,因为一直都在 new 数组,不过 JS 应该会给我回收垃圾吧?
tempTabPageBox 存储上一次的数组顺序和结构,movedTabPageBox 保存排序之后的顺序和结构.
function movePageToRight() {
for (let i = 0; i < tempTabPageBox.length; i++) {
if (i > 0) movedTabPageBox[i - 1] = tempTabPageBox[i];
else movedTabPageBox[tempTabPageBox.length - 1] = tempTabPageBox[i];
}
for (let i = 0; i < movedTabPageBox.length; i++) {
$(movedTabPageBox[i]).css({ transform: `translate(${tabPageTranslateX[i]}%, 0px) translateZ(0px)`, "z-index": 999 });
}
tempTabPageBox = new Array(...movedTabPageBox);
}
$(".tab-page")
.find(".page-item")
.each((index, elem) => {
// 初始化每一个 page 到暂存容器中
tempTabPageBox.push(elem);
// 初始化 page-item
if (index == 0) {
$(elem).css({ transform: `translate(${tabPageTranslateX[0]}%, 0px) translateZ(0px)`, "z-index": 999 });
} else {
$(elem).css({ transform: `translate(${tabPageTranslateX[index]}%, 0px) translateZ(0px)`, "z-index": 999 });
}
$(elem).on("mousedown", e => {
e.preventDefault();
$(elem).on("mouseup", e => {
if (/* 往右拉 */) {
movePageToRight();
} else if (/* 往左拉 */) {
movePageToLeft();
}
$(elem).unbind("mousemove");
});
});
});
这里贴上的代码省略了很多细节啊!但主要还是看 movePageToRight() 函数。结合上面说的和图片,每一次都是第一个元素被直接放在了末尾处,其余的元素依次往前移动。函数中第二个 for 是根据排序好的 movedTabPageBox 依次设置页面的 translate,实现平移。最后再把这一次的排序结果拷贝给 tempTabPageBox,然后等待下一次的循环.
如上图,往后滑动(也就是往左拉)每一行的数组变化情况。只有最后一个元素排在了第一位,其余的元素依次往后 +1.
function movePageToLeft() {
for (let i = 0; i < tempTabPageBox.length; i++) {
if (i >= 0 && i < tempTabPageBox.length - 1) {
movedTabPageBox[i + 1] = tempTabPageBox[i];
} else if (i === tempTabPageBox.length - 1) {
movedTabPageBox[0] = tempTabPageBox[i];
}
}
for (let i = 0; i < movedTabPageBox.length; i++) {
$(movedTabPageBox[i]).css({ transform: `translate(${tabPageTranslateX[i]}%, 0px) translateZ(0px)`, "z-index": 999 });
}
tempTabPageBox = new Array(...movedTabPageBox);
}
其余的代码和 movePageToRight() 函数是一样的,没有什么变化.
到目前为止,滑块的移动和标签页的移动都是独立的,现在要做的就是把他们连接起来。后面我也不想多写了,滑块移动的时候要把这个 index 赋值给一个全局的 index,标签页移动也是一样,而且还要记录上一次的 index.
通过一顿骚操作,把代码写出来,就实现了这个小案例了。具体还是看我仓库的代码吧👉 Gitee 和 GitHub 地址.
最后此篇关于06#Web实战:实现可滑动的标签页的文章就讲到这里了,如果你想了解更多关于06#Web实战:实现可滑动的标签页的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一个几乎可以构建的Maven / Grails应用,但在web.xml上找不到[my-app]\webapp\WEB-INF\web.xml。但是目录结构像往常一样包含web-app文件夹,而不是
正如我在标题中提到的:我想知道 web-service 和 web-socket 之间的区别?我们什么时候使用每一个? 谢谢! 最佳答案 一个web service是一个响应客户端 SOAP/REST
让我们看一个示例场景: 客户端打开一个网站并找到他从文本框中输入的两个数字的总和。然后单击“添加”按钮。两个参数通过 HTTP GET 发送到服务器,在服务器上写入 PHP 代码以添加数字,结果为回声
我知道这是一个老问题,肯定已经被回答了数百次,但我还无法找到令人满意的答案。 我正在创建一个应用程序,其他应用程序(移动/网络)将使用该应用程序来获取数据。现在我有两个选择: 将我的应用程序创建为简单
通过 Web 作业部署新功能有 3 种方法: 创建一个新的 Web 应用,并部署一个包含该函数的 Web 作业。 向现有 Web 作业添加一项新函数(这样您现在在一个 Web 作业中就拥有了多个函数)
我收到来自网络场景的通知,上面写着“问题”和“确定”。我想在问题发生时包含网络响应的内容。我不担心标题值,只担心网页的内容. 这是我可以在通知设置中引用的变量吗? 最佳答案 不幸的是 zabbix 不
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
嗨,这是一个理论问题,但我真的无法弄清楚 Web 应用程序、基于 Web 的应用程序和基于云的应用程序之间的区别。这个你能帮我吗。 最佳答案 @Matt 是对的 - 这真的无关紧要,但是,为了清楚起见
我正在尝试使用多个 Web 服务,这些服务在它们的 wsdl 中重新定义了一些相同的公共(public)类。我目前在网站中引用了它们,但我想转换为 Web 应用程序。 由于一些相同的类是从多个 Web
一个。我必须考虑哪些事项?b.当前应用程序正在执行多个存储过程。如果我创建等效的方法来执行这些过程,会有什么风险或挑战。 最佳答案 在架构上,将网络应用程序转换为网络服务时必须考虑的一件事是,对方法和
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 5年前关闭。 Improve thi
网络 API 和网络服务之间有什么区别吗?或者它们是同一个吗? 最佳答案 网络服务通常提供 WSDL您可以从中自动创建客户端 stub 。 Web 服务基于 SOAP protocol 。ASP.NE
我已经获得了我需要的所有资源。我将 Web 服务放入应用程序服务环境中,然后将 NSG 连接到应用程序服务环境使用的子网。然后,我允许 VNET 内的应用程序与 Web 服务进行通信,但它无法正常工作
我已经获得了我需要的所有资源。我将 Web 服务放入应用程序服务环境中,然后将 NSG 连接到应用程序服务环境使用的子网。然后,我允许 VNET 内的应用程序与 Web 服务进行通信,但它无法正常工作
我正在使用 stub 将我的网络服务相关测试与实际网络服务隔离开来。 你/我应该如何合并测试以确保我制作的响应与实际的网络服务匹配(我无法控制它)? 我不想知道怎么做,而是何时何地? 我应该为测试数据
我在互联网上搜索了很多,但我仍然没有得到网络服务和网络 API 之间的明显区别?我在某处读到所有 Web 服务都是 API,但所有 API 都不是 Web 服务。如何? 我所知道的是两者都允许利用其他
假设我已经完成了使用 JavaEE 制作的 Web 应用程序。这个 Web 应用程序包含登录系统,但最后它是非常基本的 Web 应用程序。我使用的是 GlassFish 3.1.2.2。 我想知道一旦
我希望设计者能够打开与我相同的解决方案文件。这可以通过 Expressions Web 实现吗? 最佳答案 简短的回答是“不”;但这是一个非常常见的请求,我知道很多人都希望下一个版本(无论何时)对此有
我正在尝试在 CF10 中创建一个 Web 服务对象。我已验证它在 SoapUI 中按预期工作。但是,当我在 CF 中运行它时,我得到一个错误,它无法找到在 WSDL 的导入语句中导入的 XSD。这是
我的要求是开发一个 Web 服务,充当外部 Web 服务和客户端之间的中间人。 我知道,我可以为我的服务设计一个wsdl,然后将外部wsdl映射到代码中我的wsdl。我的问题是有一个开源 api/工具
我是一名优秀的程序员,十分优秀!