如下是响应式下的界面:
开门见山的说,为什么要把网页做成这种样式呢?
实话说:你们不觉得这样的一个界面去做为我们后台操作系统的界面。不仅美观还很让人易操作、易上手吧。
作者在借鉴win10UI官网的同时用我的思路进行开发。如果有什么疑问和问题,可以随时联系我....
构建底部
底部导航栏布局
<!-- 底部-->
<footer>
<!-- 开始按钮 -->
<div class="win-start">
<i class="icon start-icon"></i>
</div>
<!-- 搜索 -->
<div class="search">
<div class="search-bar">
<i class="fa fa-search"></i>
<input type="text" name="search_input" placeholder="Win10搜索此系统"/>
</div>
<div class="search-icon">
<i class="fa fa-genderless"></i>
</div>
</div>
<!-- 最小化窗口栏 -->
<div class="task-bar">
</div>
<!-- 日历 -->
<div class="calendar">
<span id="hour">21:13</span>
<span id="date">2018/02/08</span>
<div class="time-piece">
<p><span id="time"></span></p>
<p><span id="days"></span><span></span></p>
</div>
</div>
<!-- 任务管理器 -->
<div class="taskmgr">
<i class="fa fa-angle-up"></i>
</div>
</footer>
//底部导航栏的样式
footer{
position: fixed;//固定 定位
bottom: 0;
left: 0;
width: 100%;//在此前设置了 html,body的宽高为100%
height: 50px;
background: rgb(38, 38, 38);
/*设置文本不可被选中*/
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/*设置z-index 必须先设置position*/
z-index: 9999;
}
开始菜单栏
<!-- 菜单 -->
<div class="start-menu">
<ul class="menu">
<li id="user_info">
<i class="fa fa-user-circle"></i>
<span>Administrator</span>
</li>
<li id="lock_window">
<i class="fa fa-unlock-alt"></i>
<span>锁屏</span>
</li>
<li id="cancel_window">
<i class="fa fa-sign-out"></i>
<span>注销</span>
</li>
<li id="close_window">
<i class="fa fa-power-off"></i>
<span>关闭</span>
</li>
</ul>
</div>
点击window图标上滑显示开始菜单栏。JS如下:
//开始菜单弹出
var start_icon = $(".start-icon");
var start_menu = $(".start-menu");
start_icon.click(function(event){
start_menu.css("display") == "none" ?//三目运算
(start_menu.show(),
start_menu.animate({
"bottom": "50px"//start_menu设置为position定位,动态设置left和bottom即可
})) :
(start_menu.animate({
"bottom": "-200px"
},function(){
start_menu.hide()
}));
event=event||window.event;
event.stopPropagation();//阻止事件冒泡到父元素
});
搜索栏
点击小圆圈,搜索框缓缓展开:JS如下
//搜索框弹出
var search_icon = $(".search-icon");
var search_bar = $(".search-bar");
var search = $(".search");
search_icon.click(function(event){
search_bar.width() <= 0 ?//如果隐藏,宽度等于0
//此处一定要先show();否则看不到展开的效果
(search_bar.show(),search.width(300),task_bar.css({left: "350px"}),
search_bar.animate({
"width": "220px"
})) : (search_bar.animate({
"width": "0px"
},function(){
search_bar.hide();
search.width(50);
task_bar.css({left: "110px"});
}));
});
日历
// 时钟 定义一个函数用以显示当前时间
var nowHour = $("#hour");
var nowDate = $("#date");
var nowTime = $("#time");
var nowDays = $("#days");
var now = null,Days = null;
displayTime();
function displayTime() {
now = new Date(); // 得到当前时间
var D = now.getDay();
var H = now.getHours();
var M = cehckTime(now.getMinutes());
var S = cehckTime(now.getSeconds());
//这里做日期判断,如果相等则不去重新设置html,避免重复设置,降低系统性能
Days = (Days == D ? D : showLunarCalendarTime(now));
nowHour.html(H + ":" + M);
nowTime.html(H + ":" + M + ":" + S);
setTimeout(displayTime,1000); //在1秒后再次执行
}
//检验时间格式 1→01
function cehckTime(i){
return i < 10 ? i = "0" + i : i;
}
// 显示时间(这里需要对月份+1,因为JS获取到的月份为0-12)
function showLunarCalendarTime(now){
var Y = 1990 + now.getYear();
var O = cehckTime(now.getMonth() + 1);
var D = cehckTime(now.getDate());
nowDate.html(Y + "/" + O + "/" + D);
nowDays.html(Y + "年" + O + "月" + D + "日");
return now.getDay();
}
//日历 渐显
$(".calendar").hover(function(){
$(".time-piece").stop();//停止动画,避免用户重复hover过快
$(".time-piece").fadeToggle();
});
点击其他元素关闭开始菜单,搜索框展开
$(document).on("click", function (event) {
//点击空白,关闭开始菜单
if(start_menu.css("display") != "none"){
start_menu.hide()
}
});
桌面元素
<!-- 桌面元素 -->
<div id="desktop">
<ul class="window">
<li data-url="init.html">
<img src="../img/icon/win10.png" />
<span>Win10UI</span>
</li>
<li data-url="init.html">
<img src="../img/icon/baidu.png" />
<span>百度首页</span>
</li>
<li data-url="init.html">
<img src="../img/icon/blogger.png" />
<span>Blog</span>
</li>
<li data-url="init.html">
<img src="../img/icon/demo.png" />
<span>媒体视频</span>
</li>
<li data-url="init.html">
<img src="../img/icon/download.png" />
<span>下载资源</span>
</li>
<li data-url="init.html">
<img src="../img/icon/doc.png" />
<span>在线文档</span>
</li>
<li data-url="init.html">
<img src="../img/icon/github.png" />
<span>Github</span>
</li>
<li data-url="init.html">
<img src="../img/icon/kyzg.png" />
<span>开源中国</span>
</li>
<li data-url="init.html">
<img src="../img/icon/website.png" />
<span>设置中心</span>
</li>
</ul>
</div>
/*桌面 start*/
#desktop{
position: fixed;
top: 0;
bottom: 50px;
width: 100%;
/*设置文本不可被选中*/
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 9;
}
.window li{
position: absolute;//设置绝对定位,通过JS设置位置
display: block;
width: 70px;
height: 70px;
padding: 7px 15px;
/*设置border-box 避免padding的像素扩张*/
box-sizing: border-box;
border-radius: 5px;
cursor: pointer;
}桌面
元素定位(实现自适应,高度变化,每列元素个数也随之变化)
这个函数比较难以理解。大家如果有什么不懂或是更好的建议的地方,可以评论,我会一一回复。
/*元素的定位函数*/
//第一个元素的位置,之后的元素的位置 都需要加上这个初始值
var heightTop = 10;
var widthLeft = 10;
//每列元素的个数
var LisCount = 0;
var Lis = $(".window > li");
LisPosition(Lis);
$(window).resize(function () {
LisPosition(Lis);
});
//元素定位函数实现
function LisPosition(obj){
//获取窗体的高度
var windowHeight = $(window).height() - 50;
//每列元素的最大个数, floor向下取整
var LisMaxCount = Math.floor(windowHeight / 90);
$(obj).each(function(index,item){
var topHeight = heightTop + LisCount * 80;
//如果元素的top值 大于窗口的最大高度 而且这一列元素的个数 大于每列最大的元素个数
//则执行重置操作
if(LisMaxCount < LisCount){
LisCount = 0;
widthLeft = widthLeft + 80;
topHeight = heightTop + LisCount * 80;
}
$(item).css({
top: topHeight,
left: widthLeft
});
//绑定点击事件
$(item).bind("click",function(){
openNewWindow(this);
});
LisCount ++;
})
heightTop = 10;
widthLeft = 10;
LisCount = 0;
/*弹窗定位*/
$(".pop-ups").css({
left: ($(window).width() - $(this).outerWidth()) / 2,
top: ($(window).height() - $(this).outerHeight()) / 2
});
}
点击桌面元素弹窗
在上一步我们在元素排序的时候,已经给没个元素绑定上点击事件openNewWindow(this);
了。
- 第一步:判断是否已经打开同一窗口
- 第二步:判断task_bar(底部显示图标的部位)的宽度够不够显示
- 第三步:task_bar 增加桌面元素的图标 + 添加弹窗
- 第四步:弹窗内容区域加载指定页面
- 第五步:绑定底部的图标点击事件(弹窗置顶:比如打开了多个页面,点击第一个窗口对应的底部图标,打开这个弹窗)
- 第六步:绑定最小化弹窗事件
- 第七步:绑定关闭弹窗事件
- 第八步:绑定最大化弹窗事件
//打开窗口函数
function openNewWindow(obj){
//判断是否已经打开同一窗口
var pop_name = $(obj).find("span").text();
if(pop_names.indexOf(pop_name) == -1){
pop_names += (pop_name + ",");
}else{
layer.msg(pop_name +"窗口已经打开了~");
return null;
}
//首先应该判断task_bar的宽度够不够显示
//footer增加标题
//取消active的状态
task_bar.find("div").removeClass("task-active");
var task = $("<div class='task task-active'></div>");
task.append($(obj).find("img").clone()).append("<span></span>");
if(task_width > task_bar.width()){
layer.msg("您当前打开的窗口太多了,休息一下吧~");
return ;
}else{
task_bar.append(task);
task_width += (task.width() + 3);
}
var pop_ups = $("<div class='pop-ups'></div>");
var pop_menu = $("<div class='pop-menu'></div>");
var pop_title = $("<div class='pop-title'></div>");
var pop_func = $("<div class='pop-func'></div>");
var pop_container = $("<div class='pop-container'></div>");
var fa_refresh = $("<span><i class='fa fa-refresh'></i></span>");
var fa_minus = $("<span><i class='fa fa-minus'></i></span>");
var fa_window_maximize = $("<span><i class='fa fa-window-maximize'></i></span>");
var fa_remove = $("<span><i class='fa fa-remove'></i></span>");
pop_func.append(fa_refresh).append(fa_minus).append(fa_window_maximize).append(fa_remove);
pop_ups.append(pop_menu.append(pop_title).append(pop_func)).append(pop_container);
pop_title.html($(obj).find("*").clone());
//添加弹窗
$("body").append(pop_ups);
//居中
pop_left = ($(window).width() - pop_ups.outerWidth()) / 2 + pop_windows_count * 15;
pop_top = ($(window).height() - pop_ups.outerHeight()) / 2 + pop_windows_count * 10;
if(pop_left + pop_ups.outerWidth() > $(window).width() ||
pop_top + pop_ups.outerHeight() > $(window).height()){
pop_windows_count = 0;
pop_left = ($(window).width() - pop_ups.outerWidth()) / 2 + pop_windows_count * 15;
pop_top = ($(window).height() - pop_ups.outerHeight()) / 2 + pop_windows_count * 10;
}
pop_windows_count ++;
pop_ups.css({
left: pop_left,
top: pop_top,
"z-index": z_index++
});
//加载页面
pop_container.load($(obj).attr("data-url"));
//底部的图标 绑定事件
task.bind("click",function(){
pop_ups.css({"z-index": z_index++});
task_bar.find("div").removeClass("task-active");
$(this).addClass("task-active");
});
//最小化弹窗
fa_minus.bind("click", function(){
pop_ups.hide();
});
//关闭弹窗
fa_remove.bind("click", function(){
pop_ups.remove();
task_width -= (task.width() + 3);
if(-- pop_windows_count< 0){
pop_windows_count = Math.floor(task_width /(task.width() + 3));
}
task.remove();
z_index --;
pop_names = pop_names.replace(pop_name + ",",",");
});
//最大化弹窗
fa_window_maximize.bind("click", function(){
if($(this).html() != '<i class="fa fa-window-restore"></i>'){
pop_ups.css({
left: 0,
top: 0,
width: "100%",
height: "100%"
});
$(this).html("<i class='fa fa-window-restore'></i>");
}else{
var width = $(window).width() * 0.8 > 400 ? $(window).width() * 0.8 : 400;
var height = $(window).height() * 0.8 > 400 ? $(window).height() * 0.8 : 400;
pop_ups.css({
left: ($(window).width() - width) / 2,
top: ($(window).height() - height) / 2,
width: width,
height: height
});
$(this).html("<i class='fa fa-window-maximize'></i>");
}
});
}
重置右键
模拟PC,所以要重置右键。因为有可能应用后台系统(表格),所以保留打印选项
<!-- 桌面 右键菜单 -->
<div class="desktop-menu">
<ul class="context">
<li id="desktop_fullscreen">
<i class="fa fa-window-maximize"></i>
<span>进入全屏</span>
</li>
<li id="desktop_refresh">
<i class="fa fa-refresh"></i>
<span>刷新本页</span>
</li>
<li id="desktop_print">
<i class="fa fa-print"></i>
<span>打印本页</span>
</li>
<hr class="layui-bg-gray" style="margin: 0;" />
<li id="desktop_about">
<i class="fa fa-star-half-o"></i>
<span>关于</span>
</li>
</ul>
</div>
桌面 右键JS事件
//桌面重置右键
$("#desktop").bind("contextmenu",function(e){
context_menu.hide();
var key = e.which; //获取鼠标键位
if(key == 3) //(1:代表左键; 2:代表中键; 3:代表右键)
{
//获取右键点击坐标
var x = ($(window).width() - e.clientX) < desktop_menu.width() ?
e.clientX - desktop_menu.width() - 4 : e.clientX;
var y = ($(window).height() - e.clientY) < desktop_menu.height() ?
e.clientY - desktop_menu.height() - 4 : e.clientY;
desktop_menu.show().css({left:x,top:y});
}
return false;
});
//全屏
$("#desktop_fullscreen").click(function (){
if($(this).find("i").attr("class") == "fa fa-window-maximize"){
$(this).html("<i class='fa fa-window-restore'></i><span>退出全屏</span>");
var elem = document.body;
if(elem.webkitRequestFullScreen){
elem.webkitRequestFullScreen();
}else if(elem.mozRequestFullScreen){
elem.mozRequestFullScreen();
}else if(elem.requestFullScreen){
elem.requestFullscreen();
}else{
layer.msg("浏览器不支持全屏API或已被禁用");
}
}else{
$(this).html("<i class='fa fa-window-maximize'></i><span>进入全屏</span>");
var elem = document;
if(elem.webkitCancelFullScreen){
elem.webkitCancelFullScreen();
}else if(elem.mozCancelFullScreen){
elem.mozCancelFullScreen();
}else if(elem.cancelFullScreen){
elem.cancelFullScreen();
}else if(elem.exitFullscreen){
elem.exitFullscreen();
}else{
layer.msg("浏览器不支持全屏API或已被禁用");
}
}
});
//打印
$("#desktop_print").click(function (){
window.print();
});
//自刷新
$("#desktop_refresh").click(function (){
location.reload();
});
底部导航栏右键
<!-- footer右键菜单 -->
<div class="context-menu">
<ul class="context">
<li id="context_all_show">
<i class="fa fa-window-maximize"></i>
<span>全部显示</span>
</li>
<li id="context_all_hide">
<i class="fa fa-minus"></i>
<span>全部隐藏</span>
</li>
<li id="context_all_close">
<i class="fa fa-remove"></i>
<span>全部关闭</span>
</li>
</ul>
</div>
JS事件
//底部导航条重置右键
$("footer").bind("contextmenu",function(e){
desktop_menu.hide()
var key = e.which; //获取鼠标键位
if(key == 3) //(1:代表左键; 2:代表中键; 3:代表右键)
{
//获取右键点击坐标
var x = ($(window).width() - e.clientX) < context_menu.width() ?
e.clientX - context_menu.width() - 4 : e.clientX;
var y = e.clientY - context_menu.height() - 4;
context_menu.show().css({left:x,top:y});
}
return false;
});
//全部关闭
$("#context_all_close").click(function(){
task_bar.empty();
$("body .pop-ups").remove();
//重置弹窗参数
pop_windows_count = 0;
task_width = 53;
z_index = 99;
});
//全部隐藏
$("#context_all_hide").click(function(){
$("body .pop-ups").hide();
});
//全部显示
$("#context_all_show").click(function(){
$("body .pop-ups").show();
});
分析大多都写在注释里了。辛苦大家仔细看一下~了。。。
如果有更好的思路和或者有不理解的地方,欢迎共同讨论。
不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。 ——文森特・梵高