在webstorm中,开发vue项目(模块化开发),在登录界面右上角显示时钟(含有日期):
1.先在login.vue中template中相应位置,添加如下代码:
<el-col :span="8">
<div id="clock">
<p class="date">{{ date }}</p>
<p class="time">{{ time }}</p>
</div>
</el-col>
2.在vue组件的script中编写下面的代码:
<script>
export default{
data(){
return {
date:'',
time:'',
week : ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
...//与时钟的实现无关的代码都省略了
},
mounted:function(){//定时执行更新时间的方法
let _this = this ;
_this.$nextTick(function () {
setInterval(_this.updateTime, 1000);
})
},
methods: {
//更新时间的方法
updateTime:function () {
let _this = this ;
let cd = new Date();
//this.date;
_this.time = _this.zeroPadding(cd.getHours(), 2) + ':'
+ _this.zeroPadding(cd.getMinutes(), 2) + ':'
+ _this.zeroPadding(cd.getSeconds(), 2);
_this.date = _this.zeroPadding(cd.getFullYear(), 4) + '-'
+ _this.zeroPadding(cd.getMonth()+1, 2) + '-'
+ _this.zeroPadding(cd.getDate(), 2) + ' '
+ _this.week[cd.getDay()];
},
//更新时间的辅助方法
zeroPadding:function(num, digit) {
let zero = '';
for(let i = 0; i < digit; i++) {
zero += '0';
}
return (zero + num).slice(-digit);
}
...//与时钟无关的代码都省略掉了
}
</script>
其中slice方法说明如下: arrayObject.slice(start,end)
参数 | 描述 |
---|---|
start | 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。 |
end | 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。 |
3.在vue组件的style(样式)标签中,添加如下样式:
<style>
p {
margin: 0;
padding: 0;
}
#clock {
font-family: 'Microsoft YaHei','Lantinghei SC','Open Sans',Arial,'Hiragino Sans GB','STHeiti','WenQuanYi Micro Hei','SimSun',sans-serif;
color: #daf6ff;
}
#clock .time {
letter-spacing: 0.05em;
font-size: 24px;
padding: 5px 0;
text-align: center;
}
#clock .date {
text-align: center;
letter-spacing: 0.1em;
font-size: 24px;
}
</style>
4.效果如下:
现在我想,能不能实现一个浮动的时钟?element-ui中有没有浮动的组件?然后我将时钟放在浮动的组件里?
浮动的组件可能没有,但是浮动广告倒是不少。虽然大多是基于jquery或原生javascript的,但是改造一下就是基于vue了。
原理是一样的,只是实现的方式不同罢了。
先看两个jquery实现的浮动广告的例子
例子1:
可以利用菜鸟教程的“尝试一下”,查看运行效果。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<!--样式的定义-->
<style>
.floadAd { position: absolute;z-index: 999900; display: none; }
.floadAd .item { display: block; }
.floadAd .item img { vertical-align: bottom; }
/* a img 的组合浏览器默认下边会有几个像素的空白,这里可以消除空白*/
</style>
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<!--html标记,也就是内容,改造为浮动时钟时,就是在这里添加时钟的内容。-->
<div id="floadAD" class="floadAd">
<a class="close" href="javascript:void();" style="color: red">×关闭</a>
<a class="item" title='首届党建文化节' href="http://unsun.net" target="_blank">
<img src="App_UpLoad/image/20160405/20160405172215_2907.png" alt="首届党建文化节" /></a>
</div>
<script>
//js代码,让广告动起来。原理就是定时改变样式(此处为位置)。
//调用
FloatAd("#floadAD");
//广告漂浮窗口
function FloatAd(selector) {
var obj = $(selector);
if (obj.find(".item").length == 0) return;//如果没有内容,不执行
var windowHeight = $(window).height();//浏览器高度
var windowWidth = $(window).width();//浏览器宽度
var dirX = -1.5;//每次水平漂浮方向及距离(单位:px),正数向右,负数向左,如果越大的话就会看起来越不流畅,但在某些需求下你可能会需要这种效果
var dirY = -1;//每次垂直漂浮方向及距离(单位:px),正数向下,负数向上,如果越大的话就会看起来越不流畅,但在某些需求下你可能会需要这种效果
var delay = 30;//定期执行的时间间隔,单位毫秒
obj.css({ left: windowWidth / 2 - obj.width() / 2 + "px", top: windowHeight / 2 - obj.height() / 2 + "px" });//把元素设置成在页面中间
obj.show();//元素默认是隐藏的,避免上一句代码改变位置视觉突兀,改变位置后再显示出来
var handler = setInterval(move, delay);//定期执行,返回一个值,这个值可以用来取消定期执行
obj.hover(function() {//鼠标经过时暂停,离开时继续
clearInterval(handler);//取消定期执行
}, function() {
handler = setInterval(move, delay);
});
obj.find(".close").click(function() {//绑定关闭按钮事件
close();
});
$(window).resize(function() {//当改变窗口大小时,重新获取浏览器大小,以保证不会过界(飘出浏览器可视范围)或漂的范围小于新的大小
windowHeight = $(window).height();//浏览器高度
windowWidth = $(window).width();//浏览器宽度
});
function move() {//定期执行的函数,使元素移动
var currentPos = obj.position();//获取当前位置,这是JQuery的函数,具体见:http://hemin.cn/jq/position.html
var nextPosX = currentPos.left + dirX;//下一个水平位置
var nextPosY = currentPos.top + dirY;//下一个垂直位置
if (nextPosX >= windowWidth - obj.width()) {//这一段是本站特有的需求,当漂浮到右边时关闭漂浮窗口,如不需要可删除
close();
}
if (nextPosX <= 0 || nextPosX >= windowWidth - obj.width()) {//如果达到左边,或者达到右边,则改变为相反方向
dirX = dirX * -1;//改变方向
nextPosX = currentPos.left + dirX;//为了不过界,重新获取下一个位置
}
if (nextPosY <= 0 || nextPosY >= windowHeight - obj.height() - 5) {//如果达到上边,或者达到下边,则改变为相反方向。
dirY = dirY * -1;//改变方向
nextPosY = currentPos.top + dirY;//为了不过界,重新获取下一个位置
}
obj.css({ left: nextPosX + "px", top: nextPosY + "px" });//移动到下一个位置
}
function close() {//停止漂浮,并销毁漂浮窗口
clearInterval(handler);
obj.remove();
}
}
</script>
</body>
</html>
另一个基于JQuery的浮动广告的例子:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jquery漂浮广告代码</title>
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<style>
</style>
</head>
<body>
<div id="imgDiv" style="position:absolute;left:50px;top:60px;">
<div id="a" style="width:20px;height:20px;position:absolute;left:160px;background:salmon;text-align: center;">×</div>
<!-- <img src="01.jpg" border="0" /> -->
<div style="width:180px;height:180px;background:red;"></div>
</div>
<script>
var xin = true,
yin = true;
var step = 1;
var delay = 10;
var $obj;
$(function() {
$obj = $("#imgDiv");
var time = window.setInterval("move()", delay);
$obj.mouseover(function() {
clearInterval(time)
});
$obj.mouseout(function() {
time = window.setInterval("move()", delay)
});
});
function move() {
var left = $obj.offset().left;
var top = $obj.offset().top;
var L = T = 0; //左边界和顶部边界
var R = $(window).width() - $obj.width(); // 右边界
var B = $(window).height() - $obj.height(); //下边界
//难点:怎样判断广告的4个边框有没有超出可视化范围!
if (left < L) {
xin = true; // 水平向右移动
}
if (left > R) {
xin = false;
}
if (top < T) {
yin = true;
}
if (top > B) {
yin = false;
}
//根据有没有超出范围来确定广告的移动方向
left += step * (xin == true ? 1 : -1);
top += step * (yin == true ? 1 : -1);
// 给div 元素重新定位
$obj.offset({
top: top,
left: left
})
}
//关闭
$(function() {
$("#a").click(function() {
var b = $("#a").parent();
$(b).remove();
})
})
</script>
</body>
</html>
再看一个基于原生javascript实现的浮动广告:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<!-- 浮动窗口样式css begin -->
<style type="text/css">
#msg_win{border:1px solid #A67901;background:#EAEAEA;width:240px;position:absolute;right:0;font-size:12px;font-family:Arial;margin:0px;display:none;overflow:hidden;z-index:99;}
#msg_win .icos{position:absolute;top:2px;*top:0px;right:2px;z-index:9;}
.icos a{float:left;color:#833B02;margin:1px;text-align:center;font-weight:bold;width:14px;height:22px;line-height:22px;padding:1px;text-decoration:none;font-family:webdings;}
.icos a:hover{color:#fff;}
#msg_title{background:#BBDEF6;border-bottom:1px solid #A67901;border-top:1px solid #FFF;border-left:1px solid #FFF;color:#000;height:25px;line-height:25px;text-indent:5px;}
#msg_content{margin:5px;margin-right:0;width:230px;height:126px;overflow:hidden;}
</style>
<!-- 浮动窗口样式css end -->
<script language="javascript">
/**可加入定时器,10分钟后自动刷新页面,显示运行的实时性*/
window.onload=function(){
setTimeout('refresh10()',1000*60*10) ;
}
function refresh10(){
window.location.reload();
}
</script>
<!-- 浮动窗口html代码 begin -->
<hr>
<div id="msg_win" style="display:block;top:490px;visibility:visible;opacity:1;">
<div class="icos">
<a id="msg_min" title="最小化" href="javascript:void 0">_</a><a id="msg_close" title="关闭" href="javascript:void 0">×
</a>
</div>
<div id="msg_title">
标题-->
</div>
<div id="msg_content" style="overflow:auto;height:150px;width:100%;white-space:nowrap">
<s:property value="devRun" escape="false"/>
</div>
</div>
<!-- 浮动窗口html代码 end -->
<!-- 浮动窗口js,必须要放置到最后 begin-->
<script language="javascript">
var Message={
set: function() {//最小化与恢复状态切换
var set=this.minbtn.status == 1?[0,1,'block',this.char[0],'最小化']:[1,0,'none',this.char[1],'展开'];
this.minbtn.status=set[0];
this.win.style.borderBottomWidth=set[1];
this.content.style.display =set[2];
this.minbtn.innerHTML =set[3]
this.minbtn.title = set[4];
this.win.style.top = this.getY().top;
},
close: function() {//关闭
this.win.style.display = 'none';
window.onscroll = null;
},
setOpacity: function(x) {//设置透明度
var v = x >= 100 ? '': 'Alpha(opacity=' + x + ')';
this.win.style.visibility = x<=0?'hidden':'visible';//IE有绝对或相对定位内容不随父透明度变化的bug
this.win.style.filter = v;
this.win.style.opacity = x / 100;
},
show: function() {//渐显
clearInterval(this.timer2);
var me = this,fx = this.fx(0, 100, 0.1),t = 0;
this.timer2 = setInterval(function() {
t = fx();
me.setOpacity(t[0]);
if (t[1] == 0) {clearInterval(me.timer2) }
},10);
},
fx: function(a, b, c) {//缓冲计算
var cMath = Math[(a - b) > 0 ? "floor": "ceil"],c = c || 0.1;
return function() {return [a += cMath((b - a) * c), a - b]}
},
getY: function() {//计算移动坐标
var d = document,b = document.body, e = document.documentElement;
var s = Math.max(b.scrollTop, e.scrollTop);
var h = /BackCompat/i.test(document.compatMode)?b.clientHeight:e.clientHeight;
var h2 = this.win.offsetHeight;
return {foot: s + h + h2 + 2+'px',top: s + h - h2 - 2+'px'}
},
moveTo: function(y) {//移动动画
clearInterval(this.timer);
var me = this,a = parseInt(this.win.style.top)||0;
var fx = this.fx(a, parseInt(y));
var t = 0 ;
this.timer = setInterval(function() {
t = fx();
me.win.style.top = t[0]+'px';
if (t[1] == 0) {
clearInterval(me.timer);
me.bind();
}
},10);
},
bind:function (){//绑定窗口滚动条与大小变化事件
var me=this,st,rt;
window.onscroll = function() {
clearTimeout(st);
clearTimeout(me.timer2);
me.setOpacity(0);
st = setTimeout(function() {
me.win.style.top = me.getY().top;
me.show();
},600);
};
window.onresize = function (){
clearTimeout(rt);
rt = setTimeout(function() {me.win.style.top = me.getY().top},100);
}
},
init: function() {//创建HTML
function $(id) {return document.getElementById(id)};
this.win=$('msg_win');
var set={minbtn: 'msg_min',closebtn: 'msg_close',title: 'msg_title',content: 'msg_content'};
for (var Id in set) {this[Id] = $(set[Id])};
var me = this;
this.minbtn.onclick = function() {me.set();this.blur()};
this.closebtn.onclick = function() {me.close()};
this.char=navigator.userAgent.toLowerCase().indexOf('firefox')+1?['_','::','×']:['0','2','r'];//FF不支持webdings字体
this.minbtn.innerHTML=this.char[0];
this.closebtn.innerHTML=this.char[2];
setTimeout(function() {//初始化最先位置
me.win.style.display = 'block';
me.win.style.top = me.getY().foot;
me.moveTo(me.getY().top);
},0);
return this;
}
};
Message.init();
</script>
<!-- 浮动窗口js end-->
</body>
</html>
经验证,上述三个例子都未能实现浮动广告的效果(应该是因为各种小毛病吧,不过思路是正确的)。
基于上述三个实例,还是可以实现vue版的浮动时钟,代码如下:
(在webstorm中模块化开发vue项目,以下代码全在一个组件里,我是放在了登录的组件里了)
<template>
<div class="mywebpage">
...
<!--核心html代码-->
<!--v-bind:style绑定属性,这样可以动态改变绑定的变量即可,这也是vue相对于原生
javascript和JQuery的优势,px在这里加上,不要包含在相应的变量内-->
<div @mouseover="mouse_over_fun" @mouseout="mouse_out_fun"
v-show="{objVisible}" v-bind:style="{left:position.left + 'px',top:position.top+'px',
height:position.height + 'px',width:position.width + 'px',
position:position.position}">
<a>
<p class="date">{{ date }}</p>
<p class="time">{{ time }}</p>
</a>
</div>
</div>
</template>
<script>
//核心vue.js代码
export default {
data() {
return {
...
//每次水平漂浮方向及距离(单位:px),正数向右,负数向左,
// 如果越大的话就会看起来越不流畅
dirX:1.5,
//每次垂直漂浮方向及距离(单位:px),正数向下,负数向上,
// 如果越大的话就会看起来越不流畅
dirY:1,
delay:'',
objVisible:false ,
handler:'',
position:{
//下面四个属性不要声明字符串(不要带px),否则,后面不容易处理,且易出错
left: 0 ,
top: 0,
height: 50 ,
width: 200 ,
position:'absolute',
z_index: 999900
},
windowHeight:'',
windowWidth:'',
...
},
mounted: function () {
let _this = this;
...
_this.FloatAd();//调用
window.onresize=function(){
window.alert("窗口大小改变");
//当改变窗口大小时,重新获取浏览器大小,以保证不会过界(飘出浏览器可视范围)或漂的范围小于新的大小
_this.windowHeight = $(window).height();//浏览器高度
_this.windowWidth = $(window).width();//浏览器宽度
};
},
methods: {
//广告漂浮窗口
FloatAd: function () {
let _this = this;
_this.windowHeight = $(window).height();//浏览器高度
_this.windowWidth = $(window).width();//浏览器宽度
_this.delay = 30;//定期执行的时间间隔,单位毫秒
_this.position.left = _this.windowWidth / 2 - _this.position.width / 2 ;
_this.position.top = _this.windowHeight / 2 - _this.position.height / 2 ;//把元素设置成在页面中间
_this.objVisible = true ;//元素默认是隐藏的,避免上一句代码改变位置视觉突兀,改变位置后再显示出来
_this.handler = setInterval(_this.move, _this.delay);//定期执行,返回一个值,这个值可以用来取消定期执行
},
mouse_over_fun:function(){
let _this = this ;
clearInterval(_this.handler);//鼠标移入,取消定期执行
},
mouse_out_fun:function(){//鼠标移出,继续定期执行
let _this = this ;
this.handler = setInterval(_this.move, _this.delay);
},
move: function () {//定期执行的函数,使元素移动
let _this = this ;
let nextPosX = _this.position.left + _this.dirX;//下一个水平位置
let nextPosY = _this.position.top + _this.dirY;//下一个垂直位置
if (nextPosX <= 0 || nextPosX >= _this.windowWidth - _this.position.width) {//如果达到左边,或者达到右边,则改变为相反方向
_this.dirX = _this.dirX * -1;//改变方向
nextPosX =_this.position.left + _this.dirX;//为了不过界,重新获取下一个位置
}
if (nextPosY <= 0 || nextPosY >= _this.windowHeight - _this.position.height - 5) {//如果达到上边,或者达到下边,则改变为相反方向。
_this.dirY = _this.dirY * -1;//改变方向
nextPosY = _this.position.top + _this.dirY;//为了不过界,重新获取下一个位置
}
_this.position.left = nextPosX ;
_this.position.top = nextPosY ;//移动到下一个位置
},
}
}
</script>
<style>
...
</style>