目录

写在前面

Tabs页面完成的基本操作完成,但是功能还不够完备:

  • Tab页打开过多超出的如何处理?
  • Tab页关闭所有、关闭其它操作
  • Tab页刷新操作

设计

这里参考LayUIAdmin的设计方式:

  1. Tab栏左右未知可以动态调整
  2. 打开的标签页面超出时,调整位置到指定标签页显示
  3. 左右滑动不同范围的标签页

布局

  • Tab栏左右位置可以调整,那么Tab栏的定位是绝对定位
  • 左右调整动画 transaction

代码

HTML

···
<div class="ls-tab-container">
<div class="header flex">
<!--left-->
<div class="tab-operate tab-operate-left">
<a class="fa fa-2x fa-angle-double-left opt-left"></a>
</div>
<!--titles-->
<div class="ls-tab-titles flex">
<div class="tab-title active" data-id="0">
<span class="title">
<i class="ls-icon ls-icon-home"></i>
</span>
</div>
</div>
<!--right-->
<div class="tab-operate tab-operate-right">
<a class="fa fa-2x fa-angle-double-right opt-right"></a>
<a class="fa fa-2x fa-angle-double-down">
<div class="dropdown-panel">
<ul>
<li class="opt" data-opt="refresh">刷新</li>
<li class="opt" data-opt="closeOthers">关闭其它</li>
<li class="opt" data-opt="closeAll">全部关闭</li>
</ul>
</div>
</a>
</div>
</div>
···
</div>
···

CSS

<!--Tabs栏-->
.ls-tab-container .ls-tab-titles {
position: absolute;
left: 39px;
right: 78px;
overflow: hidden;
transition: all 300ms ease-in;
-webkit-transition: all 300ms ease-in;
}
<!--操作--> .tab-operate {
position: absolute;
display: flex;
text-align: center;
border-bottom: 1px solid #e6e6e6;
background: rgba(255, 255, 255, 1);
box-shadow: 0 0 6px rgba(196, 199, 202, 0.35);
z-index: 8;
} .tab-operate .fa:hover {
background: rgba(238, 238, 238, .6);
cursor: pointer;
} .tab-operate.tab-operate-left {
left: 0;
} .tab-operate.tab-operate-right {
right: 0;
} .tab-operate .fa {
color: #666;
font-size: 22px;
line-height: 36px;
width: 38px;
display: inline-block;
} .tab-operate-left .fa {
border-right: 1px solid rgb(230, 230, 230, .8);
} .tab-operate-right .fa {
border-left: 1px solid rgb(230, 230, 230, .8);
position: relative;
}

效果

下拉菜单

鼠标经过最右侧操作按钮时展示下拉菜单,思路很简单就算用伪类 hover 实现,但是在利用transaction做动画的过程中发现,display 属性与 transaction 属性冲突,解决方式是通过 height:0;overflow:hidden; 来实现动画:

.dropdown-panel {
background: #fff;
position: absolute;
width: 120px;
right: 0;
font-size: 13px;
transition: top 200ms ease-in, opacity 200ms ease-in;
-webkit-transition: top 200ms ease-in, opacity 200ms ease-in;
border-radius: 4px;
top: 46px;
height: 0;
opacity: 0;
overflow: hidden;
box-shadow: 0 0 6px rgba(196, 199, 202, .35);
} .tab-operate-right .fa:hover .dropdown-panel {
top: 37px;
opacity: 1;
height: auto;
border: 1px solid rgb(230, 230, 230, .8);
}

效果预览

操作

思路



如图所示 打开多个标签页时只要把超出的部分利用 Tab栏margin-left 属性补回来就可以实现:

margin-left: (Tab栏.Offset().Left+Tabs栏.Width() - TabItem.Offset().Left-TabItem.Width()) + 'px'

关键代码实现

// 激活Tab时触发
···
// 位置调整
var pleft = $tab.offset().left + 39;
var pright = $tab.offset().left + $tab.width() - 80;
var cleft = $tabTitle.offset().left;
var cright = cleft + $tabTitle.width() + 30;
var cmgLeft = parseFloat($tabTitle.parent().css("margin-left").replace("px", "")); if (cleft < pleft) {
cmgLeft = (cmgLeft + pleft - cleft);
$tabTitle.parent().css("margin-left", cmgLeft + "px");
} else if (cright > pright) {
cmgLeft = (cmgLeft + pright - cright);
$tabTitle.parent().css("margin-left", cmgLeft + "px");
}
···

左右滑动

思路

分页的思想:把Tabs栏的宽度类比为 PageSize[分页大小] , 打开标签页占用的总长度类比为 TotalCount[总数]

关键代码实现


/**
* 翻页
* @param {页码}} pageIndex
*/
var changePage = function(diff) {
// 容器宽度
var cWidth = $('.ls-tab-container').width() - 119;
var $firstTitle = $('.ls-tab-titles .tab-title:first'),
$lastTitle = $('.ls-tab-titles .tab-title:last');
// 内容宽度
var tsWidth = $lastTitle.offset().left -
$firstTitle.offset().left +
$lastTitle.width() + 30;
var curPage = $title_container.attr("cur-p"); // 容器 margin-left 用于计算当前页码
var cmgLeft = parseFloat($title_container.css("margin-left").replace("px", ""));
curPage = Math.floor(Math.abs(cmgLeft) / cWidth) + 1; var totalPage = Math.floor(tsWidth / cWidth) + (tsWidth % cWidth > 0 ? 1 : 0);
curPage = curPage + diff;
if (curPage >= totalPage) {
curPage = totalPage;
$title_container
.css("margin-left", (1 - totalPage) * cWidth + "px")
.attr("cur-p", totalPage);
} else if (curPage <= 1) {
curPage = 1;
$title_container
.css("margin-left", "0px")
.attr("cur-p", "1");
} else {
$title_container
.css("margin-left", (1 - curPage) * cWidth + "px")
.attr("cur-p", curPage);
}
}

效果预览

欢迎批评指正

源码地址

https://github.com/LaosanShang/ls-admin-frontend

东拼西凑完成一个“前端框架”(5) - Tabs操作的更多相关文章

  1. 东拼西凑完成一个“前端框架”(4) - Tabs页

    目录 东拼西凑完成一个后台 "前端框架" (1) - 布局  东拼西凑完成一个后台 "前端框架" (2) - 字体图标 东拼西凑完成一个"前端框架&q ...

  2. 最接近原生APP体验的高性能前端框架——MUI

      前  言 MUI有三大特点: 轻量 追求性能体验,是我们开始启动MUI项目的首要目标,轻量必然是重要特征: MUI不依赖任何第三方JS库,压缩后的JS和CSS文件仅有100+K和60+K 原生UI ...

  3. vue 前端框架

    什么是vue.js 1.vue是目前最火的一个前端框架,react 是最流行的前端框架(react除了开发网站,还可以开发手机APP,vue语法也是可以进行手机app开发的,需要借助于weex) 2. ...

  4. 推荐web前端框架bootstrap

    bootstrap是基于Jquery而开发的一个前端框架. 全中文的学习网站:http://www.runoob.com/bootstrap/bootstrap-tutorial.html 实际上就是 ...

  5. day97:MoFang:移动端APP开发准备&移动端项目搭建&APICloud前端框架

    目录 1.移动端开发相关概念 1.APP类型 2.移动端屏幕介绍 3.移动端自适配方案 4.元信息(meta) 2.APP开发准备 1.注册APPCLoud账号 2.下载APP开发编辑器 3.下载AP ...

  6. Vue.js教程 1.前端框架学习介绍

    Vue.js教程 1.前端框架学习介绍 什么是Vue.js 为什么要学习流行框架 什么是Vue.js Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站, ...

  7. 前端框架easyui layout, Tabs,tree

    一.三大前端框架的 1.easyui=jquery+html4(用来做后台的管理界面) 不要钱,开发速度快,不好看,不支持响应式 2.bootstrap=jquery+html5 好看,开发速度快,部 ...

  8. jQuery操作标签,jQuery事件操作,jQuery动画效果,前端框架

    jQuery操作标签 jQuery代码查找标签绑定的变量名推荐使用 $xxxEle 样式类操作 addClass();// 添加指定的CSS类名. removeClass();// 移除指定的CSS类 ...

  9. DHTMLX 前端框架 建立你的一个应用程序 教程(十一)--添加/删除表格中的记录

    添加/删除表格中的记录 我们的最终功能是在表格中添加删除 我们通过单机工具栏上的按钮来实现添加删除 当我们单击添加按钮的时候, 表单中 第一行默认填写New contact 光标自动聚焦 当用户点击删 ...

随机推荐

  1. 设置 Tomcat 的JVM运行内存

    win7,64位: Tomcat7.0.5:jdk1.7: 情况一:Tomcat注册成系统服务,如何修改JVM运行内存? WINDOW 64位 , cmd打开注册表(regedit) HKEY_LOC ...

  2. PHP实现图片的等比缩放和Logo水印功能示例

    文章来自于:脚本之家 文章链接:https://www.jb51.net/article/112909.htm 这篇文章主要介绍了PHP实现图片的等比缩放和Logo水印功能,结合实例形式分析了php图 ...

  3. es6新增语法之`${}`

    这是es6中新增的字符串方法 可以配合反单引号完成拼接字符串的功能 1.反单引号怎么打出来?将输入法调整为英文输入法,单击键盘上数字键1左边的按键. 2.用法step1: 定义需要拼接进去的字符串变量 ...

  4. Ext.FormPanel-----FieldSet的用法

    Ext.form.FieldSet的常用配置项: 1.checkboxToggle : Mixed True表示在lengend标签之前fieldset的范围内渲染一个checkbox,或者送入一个D ...

  5. supersockets和 AppSession,AppServer 配合工作

    现在, 你已经有了 RequestInfo, ReceiveFilter 和 ReceiveFilterFactory, 但是你还没有正式使用它们. 如果你想让他们在你的程序里面可用, 你需要定义你们 ...

  6. Spring Boot 动态数据源(多数据源自动切换)

    本文实现案例场景: 某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库. 为了在开发中以最简单的方法使用,本文基 ...

  7. php Restful设计

    1.restful是基于资源的,面向资源架构风格(一个链接,一张图.一个文本等等) 2.restful的http协议 2.1 url: 2.1.1 port 服务端口,默认为80 2.1.2 path ...

  8. uni-app学习记录03-路由跳转

    <template> <view class="content"> <!-- v-show是相对于display: none --> <v ...

  9. POJ 2763"Housewife Wind"(DFS序+树状数组+LCA)

    传送门 •题意 一对夫妇居住在 xx村庄,给村庄有 $n$ 个小屋: 这 $n$ 个小屋之间有双向可达的道路,不会出现环,即所构成的图是个树: 从 $a_i$ 小屋到 $b_i$ 小屋需要花费 $w_ ...

  10. H3C 基于ACL的包过滤技术