前端及开发文章及欣赏

Vue.js 学习日志(一)

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="../static/vue.min.js"></script>
</head>
<body>
<div id="vue_data">
<h1>title : {{title}}</h1>
<h1>url : {{url}}</h1>
<h1>{{info()}}</h1>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_data',
data: {
title: "Vue.js",
url: "https://cn.vuejs.org"
},
methods: {
info: function() {
return  this.title + " - 坚持学习!";
}
}
})
</script>
</body>
</html>
1、每个Vue应用都需要实例化Vue来实现

var vm = new Vue({
    //*******
})
2、el参数

在上面实例中的id为vue_data,在div元素中:

<div id="vue_data"></div>
意味着所有的改动均在这个id为vau_data的div中,外部不受影响。

3、定义数据对象

data用于定义属性,在上述实例中有2个属性,分别为:title、url。

methods用于定义函数,可以通过return来返回函数值。

{{ }}用于输出对象属性和函数返回值。

当一个Vue实例创建时,Vue的响应系统加入了data对象中能找到的所有属性。当这些属性的值发生改变时,html视图也会产生相应的变化。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="../static/vue.min.js"></script>
</head>
<body>
<div id="vue_data">
<h1>title : {{title}}</h1>
<h1>url : {{url}}</h1>
</div>
<script type="text/javascript">
//数据对象
var data = {title: "Vue.js",url: "https://cn.vuejs.org"}
var vm = new Vue({
el: '#vue_data',
data: data
})

//设置属性会影响到原始数据
vm.title = "spring";
document.write(data.title + "<br>");

//同样
data.url = "https://spring.io";
document.write(vm.url);
</script>
</body>
</html>
Vue还提供了实例属性与方法,以前缀$与用户定义的属性区分开来。

document.write(vm.$data === data) // true

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务

CSS-弹性伸缩布局(新版本)

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

使用新版本的弹性伸缩布局
display使用弹性伸缩盒

direction容器盒内元素的排列顺序

flex-wrap设置无法容纳时,自动换行

justify-content 伸缩项目的排列方式

align-items 处理额外空间

align-self 单独处理一个伸缩项目的额外空间

flex 控制伸缩容器的比例分配

order 设置伸缩项目出现的位置

dislpay
值:
flex 将容器盒作为块级弹性伸缩盒显示。
inline-flex:将容器盒作为内联级弹性伸缩盒显示。
实际现实中 这两个值没区别。

direction
容器盒内元素的排列顺序

值:
row:从左到右排列
row-reverse:从右到左排列
column:从上倒下排列
column-reverse从下到上排列

flex-wrap
设置无法容纳时,自动换行

值:
nowrap:不换行
wrap:自动换行
wrap-reverse:自动换行,方向和wrap相反

下图为正常排序

使用wrap-reverse后缩小浏览器时:


justify-content
伸缩项目的排列方式

值:
flex-start:伸缩项目以起始点靠齐

flex-end:伸缩项目以结尾靠齐
center:以中心点靠齐
space-between:伸缩项目平均分布
space-around:同上但两段保留一般的空间

实例:使用space-around的排列效果


align-items
处理额外空间

值:
flex-start:以顶部为基准,清理底部的额外空间
flex-end:以底部为基准,清理顶部的额外空间
center:以中间为基准,清理上下部分的额外空间
baseline:以基线为基准,清理额外的空间
stretch:伸缩项目填充整个容器,默认值

align-self
处理额外空间

值:与align-items的值一样,需要用nth-child()设置某一个需要处理的伸缩项目
flex
设置伸缩项目分配比例

p:nth-child(1)
{
   flex: 1;
}

p:nth-child(2)
{
flex: 2;
}
 p:nth-child(3)
{

flex: 2;
}
p:nth-child(4)
{
flex: 1;
}

order
设置伸缩项目出现的位置

p:nth-child(1)
{
   order:2;
}

p:nth-child(2)
{
 order:3;
}
 p:nth-child(3)
{

 order:4;
}
p:nth-child(4)
{
 order:1;
}
--------------------- 
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务

vue项目 微信支付 和 支付宝支付

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

做了一个项目,有充值功能,充值方式为 微信和支付宝,效果如下:



代码:

<template>
<el-card class="box-card">
<ul class="msg-box">
<li>
<h4>我要充值</h4>
</li>
<li>
<h4 style="margin-bottom: 15px;">充值金额</h4>
<el-radio-group v-model="amountVal" @change="amountChange">
<el-radio border :label="''+ 100">充值100</el-radio>
<el-radio border :label="''+ 500">充值500</el-radio>
<el-radio border :label="''+ 1000">充值1000</el-radio>
<el-radio border :label="''+ 2000">充值2000</el-radio>
<el-radio border :label="''+ 5000">充值5000</el-radio>
<el-radio border :label="''">自定义</el-radio>
</el-radio-group>
</li>
<li>
<h4 style="margin-bottom: 15px;">充值方式</h4>
<el-radio-group v-model="rechargeParams.paymentType" @change="paymentTypeChange">
<el-radio border :label="''+ 0">微信</el-radio>
<el-radio border :label="''+ 1">支付宝</el-radio>
</el-radio-group>
</li>
<li>
<h4 style="margin-bottom: 15px;">充值金额</h4>
<el-input :disabled="disabled" clearable v-model="rechargeParams.totalAmt" placeholder="请输入金额" style="width: 150px;"></el-input>
</li>
</ul>
<div style="text-align: center; margin-top: 30px;">
<el-button type="primary" @click="surePay">确认支付</el-button>
</div>
</el-card>
</template>
 
<script>
export default {
data() {
return {
amountVal: '',
disabled: false,
//充值参数
rechargeParams: {
"totalAmt": '', //金额
"paymentType": "0", //支付方式[0:微信,1:支付宝,2:余额,3:活动]
"transType": "0" //交易类型[0:充值,1:消费]
}
}
},
methods: {
//充值金额
amountChange(val) {
this.rechargeParams.totalAmt = val;
if (val == '') {
this.disabled = false
} else {
this.disabled = true
}
},
//支付方式
paymentTypeChange(val) {
this.rechargeParams.paymentType = val
},
//确认支付
async surePay() {
if (this.rechargeParams.totalAmt == '') {
this.$message.warning('请输入金额');
return;
}
const res = await this.$http.post('orderInfo/createOrderInfo', this.rechargeParams)
const {
code,
msg,
result
} = res.data
if (code === '200') {
//支付方式跳转
if (this.rechargeParams.paymentType == '0') {
this.$message.success('微信支付');
this.wechatPay(result);
} else if (this.rechargeParams.paymentType == '1') {
this.$message.success('支付宝支付')
const payDiv = document.getElementById('payDiv');
if (payDiv) {
document.body.removeChild(payDiv);
}
const div = document.createElement('div');
div.id = 'payDiv';
div.innerHTML = result;
document.body.appendChild(div);
document.getElementById('payDiv').getElementsByTagName('form')[0].submit();
} else if (this.rechargeParams.paymentType == '2') {
this.$message.success('余额支付成功');
this.$router.push({
name: 'order'
})
} else {
this.$message.success('活动支付')
}
} else if (code === 401) {
this.$message.error(msg)
this.$router.push({
name: 'login'
})
} else {
this.$message.error(msg)
}
},
//微信支付
wechatPay(result) {
if (result) {
const orderParams = JSON.parse(result);
sessionStorage.qrurl = orderParams.qrurl;
sessionStorage.amt = orderParams.amt;
sessionStorage.returnUrl = orderParams.returnUrl;
sessionStorage.order_id = orderParams.order_id;
this.$router.push({
name: 'wechatPay'
})
}
}
}
}
</script>
 
<style scoped>
/* 信息列表样式 */
.msg-box > li {
list-style: none;
border-bottom: 1px solid #c5c5c5;
padding: 20px 10px;
}
</style>
支付宝方式:后台会返回来一个form,然后提交form自动跳转到支付宝支付页面。

微信方式:需要自己根据后台返回的url生成二维码页面,如图所示:



代码:

<template>
<div class="payBox">
<div class="img-logo">
<img src="http://img.huoxingbeidiao.com/public/WePayLogo.png" alt="">
</div>
<div class="info-box">
<div style="padding-bottom: 20px;">
<qrcode-vue :value="qrurl" :size="200" level="H"></qrcode-vue>
</div>
<img src="http://img.huoxingbeidiao.com/public/WePayInfo.png" alt="">
<p class="price">¥&nbsp;{{amt}}</p>
</div>
</div>
</template>
 
<script>
import QrcodeVue from 'qrcode.vue'
export default {
data() {
return {
amt: 0,
qrurl: '',
timer: null
}
},
components: {
QrcodeVue
},
methods: {
getOrderInfo() {
if (sessionStorage.qrurl && sessionStorage.amt) {
this.qrurl = sessionStorage.qrurl;
this.amt = sessionStorage.amt;
}
},
startLoop() {
this.timer = setInterval(() => {
this.isPaySuccess()
}, 3000)
},
async isPaySuccess() {
const orderId = sessionStorage.order_id;
const res = await this.$http.get('orderInfo/queryOrder?orderId=' + orderId)
const {
code,
msg,
resultList
} = res.data
if (code === '200') {
clearInterval(this.timer);
this.timer = null;
sessionStorage.removeItem('qrurl');
sessionStorage.removeItem('amt');
sessionStorage.removeItem('order_id');
sessionStorage.removeItem('returnUrl');
setTimeout(() => {
this.$router.push({
name: 'order'
})
}, 3000)
} else if (code === 401) {
clearInterval(this.timer);
this.timer = null;
sessionStorage.removeItem('qrurl');
sessionStorage.removeItem('amt');
sessionStorage.removeItem('order_id');
sessionStorage.removeItem('returnUrl');
this.$message.error(msg)
this.$router.push({
name: 'login'
})
} else {
 
}
}
},
created() {
this.getOrderInfo()
this.startLoop()
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
}
}
</script>
 
<style scoped>
.payBox {
width: 1000px;
margin: 0 auto;
}
 
.payBox .img-logo {
padding: 20px 0;
text-align: center;
}
 
.payBox .img-logo img {
width: 180px;
}
 
.info-box {
padding: 60px 0;
border-top: 3px solid #F43B66;
-webkit-box-shadow: 0 0 32px 0 rgba(0, 0, 0, .18);
box-shadow: 0 0 32px 0 rgba(0, 0, 0, .18);
text-align: center;
}
 
.info-box .price {
color: #F43B66;
font-size: 40px;
padding-top: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #f1f1f1;
}
</style>
需要安装qrcode.vue

npm install --save qrcode.vue  或  yarn add qrcode.vue
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务

css高级选择器和基本选择器

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

ID选择器>类选择器>标签选择器
行内样式>内部样式>外部样式
*结构伪类选择器 一旦设置 不管在行内还是在后面重新设置,都没办法改变
*结构伪类选择器设置奇偶行以及从第三行开始变色如何实现
nth-cild(2N+3)表示从第三行开始的奇数行
同理 nth-child(2N+4)表示从第四行开始的偶数行
nth-cild(2N+5)表示从第五行开始的奇数行
*设置前三个:
p:nth-child(-n+3){
background-color: #b3d4fc;
}
*使用E F:nth-child(n)和E F:nth-of-type(n)的 关键点
E F:nth-child(n)在父级里从一个元素开始查找,不分类型
E F:nth-of-type(n)在父级里先看类型,再看位置

注意
child 跟子选择器没有关系,可以是子选择,也可以是后代选择 由层次选择器 (如table tr)来控制

1.层次选择器
table td 后代选择器 td包含在table里
div>p子选择器 p是div的子元素
p1+p p1后面一个兄弟p变化 是对p进行处理 p1不变 而且只是下面相邻的变化 上面相邻不变化
p1~p p1后面所有兄弟p变化 p1不变
2.结构伪类选择器
P:first-child 作为父元素的第一个子元素得元素 p
P:last-child 作为父元素的最后一个子元素得元素 p
P a :nth-child(n) p中第n个a元素 (even)(odd)
p:first-of-type 必须是p元素 不是子元素也行
p a:nth-of-type(n)
必须是a元素 不是a的子元素也行
3.属性选择器
a[id] a标签中含有id的
a[id=111] a标签中的id=111的
a[href*=http] a标签中包含href属性 且都包含http
a[href&=png] a标签中包含href属性 且最后以png结尾
a[href^=http://] a标签中包含href属性且以http://开头
1.层次选择器

*相邻兄弟选择器,只对后面的兄弟有作用,对前面的兄弟没效果。
*相邻兄弟选择器,E+F E不会产生效果效果

2.结构伪类选择器


使用E F:nth-child(n)和E F:nth-of-type(n)的 关键点
E F:nth-child(n)在父级里从一个元素开始查找,不分类型
E F:nth-of-type(n)在父级里先看类型,再看位置

注意
child 跟子选择器没有关系,可以是子选择,也可以是后代选择 由层次选择器 (如table tr)来控制
设置前三个:
p:nth-child(-n+3){
background-color: #b3d4fc;
}
3.属性选择器

举例:
a[href=^http]{backgroud-color:red}

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务

微信小程序动画之点击效果

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

微信小程序动画之点击效果

代码:
js:

// pages/test/test.js
Page({
  containerTap: function (res) {
    var that = this
    var x = res.touches[0].pageX;
    var y = res.touches[0].pageY + 85;
    this.setData({
      rippleStyle: ''
    });
    setTimeout(function () {
      that.setData({
        rippleStyle: 'top:' + y + 'px;left:' + x + 'px;-webkit-animation: ripple 0.4s linear;animation:ripple 0.4s linear;'
      });
    }, 200)
  },
})


wxml:

<view class="ripple" style="{{rippleStyle}}"></view>
<view class="container" bindtouchstart="containerTap"></view>

wxss:

page{height:100%}
.container{
    width:100%;
    height:100%;
    overflow: hidden
}
.ripple {
    background-color:aquamarine;
    border-radius: 100%;
    height:10px;
    width:10px;
    margin-top: -90px;
    position: absolute;
    
    overflow: hidden
}
@-webkit-keyframes ripple {
    100% {
    webkit-transform: scale(12);
    transform: scale(12);
    background-color: transparent;
    }
}

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

ECMAScript6学习笔记

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

这周萌芽决定好好学习一下ES6,感兴趣的小伙伴们来一起学习吧~
ES6(ES2015)——IE10+、Chrome、FireFox、移动端、Node.js

编译转换

1.在线转换(browser.js)
2.提前编译

ES6新特性
1.变量
2.函数
3.数组
4.字符串
5.面向对象
6.promise(串行化异步交互)
7.generator(把同步拆分为异步)
8.模块化(ES6自带模块化)

变量
var
1.可以重复声明
2.无法限制修改
3.没有块级作用域(没有语法块!)

let 不能重复声明(变量,可以修改)
const 不能重复声明(常量,不能修改)

块级作用域,let在外部无法调用

函数
箭头函数 =>

function show(){
//这是我们平常的函数
}
let show=()=>{
//箭头函数
}
//区别不大,把function省略掉换成箭头,主要就是为了方便,可传参

1.如果只有一个参数,()可以省去。

 let show=a=>{
        return a*2
    }

2.如果只有一个return,{}可以省略

   let show=a=>a*2;
   let arr = [15,2,37,11,67,4,6]; //排序
  
   arr.sort((n1,n2)=>{
        return n1-n2;
    })
    
    arr.sort((n1,n2)=> n1-n2 );
    console.log(arr)


函数的参数
1.参数扩展/展开
2.默认参数

参数的扩展
1.收集参数

 function arrData(a,b,...args) {
        alert(a);
        alert(b);
        alert(args);
    }
    *注意:Rest Parameter必须是最后一个(除其他语言)
1

2.展开数组

    arrData(...arr);       //等价于 arrData(1,2,3);
1
这仨点儿【…】代表把数组内容掏出来放这。

默认参数

//jQuery中的默认参数
$('#div1').animate({width:'200px'});
$('#div1').animate({width:'200px'},1000);

//ES6默认传参
   function showOne(a,b=10,c=5) {
        console.log(a,b,c)
    }

解构赋值
1.左右两边解构必须一样
2.右边必须是个合法的东西
3.声明和赋值不能分开(必须在一句话里完成)

    let  [one,two,three] = [10,20,30];
    let  {one1,two2,three3} = {a:10,b:20,c:30};

数组
map 映射(一个对一个。传几个返回几个)

let result = arr.map(function (item) {
    return item*2;
});//简写一下
let result = arr.map(item=>item*2 );

//判断考试成绩
let score = [19,18,78,65,100];
let result = score.map(item=>item>=60?'及格':'不及格');

reduce 汇总(算个总数,算个平均数)

//tmp:上次求和总和,为两两相加,如果之前没有结果则为传进来的数组的第一个数。
//itme:当前的数。
//index:执行的次数。

   let result = arr.reduce(function (tmp, item, index) {
       return tmp + item;
    });
    //简写
    arr.reduce((tmp, item, index)=>tmp + item);

filter 过滤器(筛选掉不需要的)

 let result = arr.filter(item=>{
        if (item%2 == 0){
            return true;
        } else {
            return false;
        }
    });
    
 //简写
let result = arr.filter(item=>item%2 == 0);
       
//***萌芽在这里提一下!json和之前的item都不是固定的,可以随便命名。意思都是当前的值!

 let arrProce = [
        {title:'男士衬衫',price:75},
        {title:'女士包包',price:5000},
        {title:'男士包包',price:20},
        {title:'女士鞋',price:2500}
    ];
    let result = arrProce.filter(jsom=>json.price >= 2000);
    console.log(result);

forEach循环(迭代)

   arr.forEach((item,index)=>{
        alert(index+":"+item)
    })

字符串
1.多了俩新方法
startsWith(); //判断开头,返回布尔类型
endWith(); //判断结尾,返回布尔类型

let str='hello,world!'
str.startsWith('h')
str.endWith('!')      //返回true

2.字符串模板
字符串连接
2.1直接把东西塞进字符串里面 ${东西}
2.2可以折行

<h1>${title}</h1>
<p>${content}</p>

ES6的面向对象
1.class关键字,构造器和类分开啦。
2.class里面直接加方法。

    class User{
        constructor(name,password){   //构造器
            this.name = name;
            this.password = password;
        }

        showName(){
            alert(this.name);
        }
        showPass(){
           alert(this.password);
        }
    }

    var user = new User('萌芽子','123456');
    user.showName();
    user.showPass();

继承

    class VipUser extends User{
        constructor(name,password,age){
        super(name,password);          //super 超类
        this.age = age;
        }
        showAge(){
            alert(this.age)
        }
    }
    var user = new VipUser('萌芽子','123456','18岁');
    user.showName();
    user.showPass();
    user.showAge();

不得不说作为一只JAVA汪,这种写法真得劲!

面向对象的应用
React
1.组件化(class)
2.JSX(JSXbabelbrowser.js)
JSX属于JS的扩展版

class Test extends React.Component{
 constructor(...args){
 super(...args);
 }
render(){
return <li>{this.props.str}</li>         //props:属性
}
}

window.onload = function(){
let oDiv = document.getElementById('div1');

ReactDOM.render(
<ul>
<Item str="你好"></Item>
<Item str="世界!"></Item>
</ul>
oDiv
);
};


打卡,下次就学这个了!===============

json
1.JSON对象

JSON.stringify() json转字符串

 let json = {a:10, b:20};//JSON.stringify   字符串化
    let str = 'http://www.baidu.com/path/user?data='+JSON.stringify(json);
    str = 'http://www.baidu.com/path/user?data='+encodeURIComponent(JSON.stringify(json));
    alert(str)
1
2
3
4
JSON.parse() 字符串转json

    let str = '{"a":12,"b":20,"c":"可乐"}';
    let json = JSON.parse(str);
    console.log(json);

2.简写
在新版的ES6当中名字一样的键(key)和值(value)可以只写一个。

    let a = 12;
    let b = 5;
    let json = {a,b,c:21};

简化了JSON中的方法。

 let json ={
        a:12,
        showJson(){
            alert(this.a);
        }
    };
    json.showJson();

json的标准写法:
1.只能用双引号
2.所有的名字都必须用引号包起来(所有的key都必须是双引号)

{a:12,b:5}     × 错误的写法
{"a":"萌萌萌","b":"芽子"}     √ 正确的写法
1
2
Promise(承诺)
异步:操作之间没啥关系,同时进行多个操作
同步:同时只能做一件事
优缺点:
异步:代码更复杂
同步:代码简单
Promise——消除异步操作
*用同步一样的方式来书写异步代码;

    let p = new Promise(function (resolve,reject) {
        //异步代码
        //resolve——成功
        //reject——失败
    })

-----------------------------------------访问我们的arr.txt文件,这里用到了jQuery的ajax就不详细介绍了。
  let p = new Promise(function (resolve, reject) {
        //异步代码
        //resolve——成功
        //reject——失败
        $.ajax({
            url: 'arr.txt',
            dataType: 'json',
            success(arr) {
                resolve(arr);
            }, error(err) {
                reject(err);
            }
        })
    });
    //结果
    p.then(function (arr) {
        alert('成功啦' + arr)
    }, function (err) {
        alert('失败了' + err)
        console.log(err)
    });
-----------------------------------------------多个请求地址
  Promise.all([p1,p2]).then(function (arr){
        let [res1,res2] = arr;
        alert('全部成功啦');
        console.log(res1);
        console.log(res2);
    },function (){
        alert('至少有一个失败了');
    });
    ----------------------------再简化
    function createPromise(url){
    return new Promise(function (resolve, reject) {
            $.ajax({
                url,
                dataType: 'json',
                success(arr) {
                    resolve(arr);
                }, error(err) {
                    reject(err);
                }
            })
        });
    }
  Promise.all([
        createPromise('arr.txt'),
        createPromise('json.txt')
    ]).then(function (arr){
        let [res1,res2] = arr;
        alert('全部成功啦');
        console.log(res1);
        console.log(res2);
    },function (){
        alert('至少有一个失败了');
    });
----------------------完美写法
 Promise.all([
        $.ajax({url:'arr.txt',dataType:'json'}),
        $.ajax({url:'json.txt',dataType:'json'})
    ]).then(function (results) {
        let [arr,json] = results;
        alert("成功了");
        console.log(arr,json)
    },function () {
        alert("失败了")
    })

我们有了promise之后的异步:

 Promise.all([ $.ajax(),$.ajax() ]).then( results=>{
   //对了
    },err=> {
   //错了
    })

Promise.all (必须全部成功)
Promise.race(同事读多个数据,即使失败也没关系)

generator(生成器)
普通函数 - 一路到底执行不可中断
generator函数 - 可中断

 function * show() {
        alert('a');
        yield;//暂时放弃执行
        alert('b');
    }
    let genObj = show();
    genObj.next();
    genObj.next();

yield
yield传参

  function * show(num1,num2) {
        alert(`${num1},${num2}`);//es6
        alert('a');
       let a = yield;//暂时放弃执行
        console.log(a);
        alert('b');
    }
    let genObj = show(99,88);
    genObj.next(12);//第一个next无法给yield传参的,废的
    genObj.next(5);

yield返回

  function *show() {
        alert('a');
        yield 12;
        alert('b');
        return 55;
    }

    let gen = show();
    let res1 = gen.next();
    console.log(res1);      //{value: 12, done: false}
    let res2 = gen.next();
    console.log(res2);//{value: undefined, done: true}  加了return  {value: 55, done: true}



还没做的菜叫函数参数,过程是yield之前函数里面的东西,干净的菜,切好的菜是中间过程也就是yield,最终我们将它返回出去!不得不说这图很生动。
异步操作
1.回调

$.ajax({
    url:'url',
    dataType:'json',
    success(data){
        $.ajax({
            url:'xxx',
            dataType: 'json',
            success(data) {
                //完事儿了
            },error(err) {
                alert('错了')
            }
        })
    },error(){
        alert('失败')
    }
})

2.Promise

Promise.all([
        $.ajax({url:xxx,dataType:'json'}),
        $.ajax({url:xxx,dataType:'json'}),
        $.ajax({url:xxx,dataType:'json'})
    ]).then(results=>{
        //完事儿
    },err=>{
        //错误的
    })

3.generator

runner(function  *(){
let data1 = yield $.ajax({ulr:xxx,dataType:'json'});
let data2 = yield $.ajax({ulr:xxx,dataType:'json'});
let data3 = yield $.ajax({ulr:xxx,dataType:'json'});
})
1
2
3
4
5
generator(不能用=>函数)
逻辑判断下非常好用。
Promise:一次读一堆。
generator:逻辑性。

runner(function *(){
let userData = yield $.ajax({url:'getUserData',dataType:'json'});
if(userData.type == 'VIP'){
let items = yield $.ajax({url:'getVIPItems',dataTyoe:'jsom'});
}else{
let items = yield $.ajax({url:'getItems',dataTyoe:'jsom'});
      }
//生成...
}
})

总结
1.变量:
var:能重复声明、函数级
let: 严格的,不能重复声明,块级,变量
const:严格的,不能重复声明,块级,常量

2.箭头函数
2.1方便
i.如果只有一个参数,()可以省
ii.如果只有一个return,{}可以省
2.2修正了this
this相对正常点

3.参数扩展
…能收集
…能扩展
默认参数

4.数组方法
map 映射
reduce 汇总
filter 过滤
forEach 循环

5.字符串
starsWith/endWith
字符串模板:${a}xxx{b}

6.Promise
封装异步操作
Promise.all([]);

7.generator
function *show(){
yield
}

8.JSON
JSON.stringify({ a :12,b :5}) => {“a”:12,“b”:5}
JSON.parse(’{“a”:12,“b”:5}’) =>{a:12,b:5}//字符串

9.解构赋值
let [a,b,c] = [12,5,8];
左右结构一样,右边是个合法的东西,连生命带赋值一次完成。

10.面向对象
class Test(){
constructor(xxx){
this = xxx
}
方法1(){
}
方法2(){
}
}
继承
class Test2 extends Test(){
constructor(){
super();
}
}

谈谈ES7和ES8
1.数组includes
数组是否包含某个东西

2.数组 keys/values/entries
for…in(循环数组)
对于数组来讲循环的是下标
对于json循环的是key

for…of(循环迭代器)
对于数组循环的是值
不能用于JSON,json并不是迭代器

keys = >所有的key拿出来 0,1,2,3…
values =>所有的values拿出来 23,5,8,1…
entries =>所有的键值对拿出来 {key:0,value:a}

let arr = [12,5,8,99];
for(let [key,value] of arr.entries()){
alert(`${key} = ${value}`);

预览版,目前极大多数浏览器都不支持,以后可能会支持,了解一下就好。
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

微信小程序之卡片层叠滑动效果

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

微信小程序之卡片层叠滑动效果

代码:
js:

// index/gun/jsSwiper2/jsSwiper2.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    startX: 0,
    endX: 0,
    iCenter: 3,
    datas: [{
      id: 1,
      zIndex: 2,
      opacity: 0.2,
      left: 40,
      iamge: "../../images/1.jpg",
      animation: null
    },
    {
      id: 2,
      zIndex: 4,
      opacity: 0.4,
      left: 80,
      iamge: "../../images/2.jpg",
      animation: null
    },
    {
      id: 3,
      zIndex: 6,
      opacity: 0.6,
      left: 120,
      iamge: "../../images/3.jpg",
      animation: null
    },
    {
      id: 4,
      zIndex: 8,
      opacity: 1,
      left: 160,
      iamge: "../../images/4.jpg",
      animation: null
    },
    {
      id: 5,
      zIndex: 6,
      opacity: 0.6,
      left: 200,
      iamge: "../../images/5.jpg",
      animation: null
    },
    {
      id: 6,
      zIndex: 4,
      opacity: 0.4,
      left: 240,
      iamge: "../../images/6.jpg",
      animation: null
    },
    {
      id: 7,
      zIndex: 2,
      opacity: 0.2,
      left: 280,
      iamge: "../../images/7.jpg",
      animation: null
    },
    ],
    order: []
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.__set__();
    this.move();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  move: function () {
    var datas = this.data.datas;
    /*图片分布*/
    for (var i = 0; i < datas.length; i++) {
      var data = datas[i];
      var animation = wx.createAnimation({
        duration: 200
      });
      animation.translateX(data.left).step();
      this.setData({
        ["datas[" + i + "].animation"]: animation.export(),
        ["datas[" + i + "].zIndex"]: data.zIndex,
        ["datas[" + i + "].opacity"]: data.opacity,
      })
    }
  },
  /**左箭头 */
  left: function () {
    //
    var last = this.data.datas.pop(); //获取数组的最后一个
    this.data.datas.unshift(last);//放到数组的第一个
    var orderFirst = this.data.order.shift();
    this.data.order.push(orderFirst);
    this.move();
  },
  /** */
  right: function () {
    var first = this.data.datas.shift(); //获取数组的第一个
    this.data.datas.push(first);//放到数组的最后一个位置
    var orderLast = this.data.order.pop();
    this.data.order.unshift(orderLast);
    this.move();
  },
  /**点击某项 */
  choose: function (e) {
    var that = this;
    var id = e.currentTarget.dataset.id;
    var order = that.data.order;
    var index = 0;
    for (var i = 0; i < order.length; i++) {
      if (id == order[i]) {
        index = i;
        break;
      }
    }
    if (index < that.data.iCenter) {
      for (var i = 0; i < that.data.iCenter - index; i++) {
        this.data.datas.push(this.data.datas.shift()); //获取第一个放到最后一个
        this.data.order.unshift(this.data.order.pop());
        // this.right()  
      }
    } else if (index > that.data.iCenter) {
      for (var i = 0; i < index - that.data.iCenter; i++) {
        this.data.datas.unshift(this.data.datas.pop()); //获取最后一个放到第一个
        this.data.order.push(this.data.order.shift());
        // this.left();
      }
    }
    this.move();
  },
  /**新的排列复制到新的数组中 */
  __set__: function () {
    var that = this;
    var order = that.data.order;
    var datas = that.data.datas;
    for (var i = 0; i < datas.length; i++) {
      that.setData({
        ["order[" + i + "]"]: datas[i].id
      })
    }
  },
  //手指触发开始移动
  moveStart: function (e) {
    console.log(e);
    var startX = e.changedTouches[0].pageX;
    this.setData({
      startX: startX
    });
  },
  //手指触摸后移动完成触发事件
  moveItem: function (e) {
    console.log(e);
    var that = this;
    var endX = e.changedTouches[0].pageX;
    this.setData({
      endX: endX
    });
    //计算手指触摸偏移剧距离
    var moveX = this.data.startX - this.data.endX;
    //向左移动
    if (moveX > 20) {
      this.left();
    }
    if (moveX < -20) {
      this.right();
    }
  },
})


wxml:

<view class="teachers_banner">
  <view class="container clearfix teachers_b">
    <view class="slide" id="slide" bindtouchstart='moveStart' bindtouchend='moveItem'>

      <block wx:for="{{datas}}">
        <li animation="{{item.animation}}" style="z-index: {{item.zIndex}} ;opacity:{{item.opacity}};" bindtap="choose" data-id="{{item.id}}">
          <image src="{{item.iamge}}"></image>
        </li>
      </block>

    </view>
  </view>
</view>

wxss:

.teachers_banner {
  width: 100%;
  height: 650px;
  background-size: cover;
  position: relative;
  overflow: hidden;
}

.teachers_b {
  position: relative;
  margin-top: 80px;
}

#slide {
  margin: 0 auto;
  width: 100%;
  height: 350px;
  position: relative;
}

image {
  width: 400rpx;
  height: 550rpx;
}

#slide li {
  position: absolute;
  width: 400rpx;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  align-items: flex-start;
  -webkit-box-align: flex-start;
  -webkit-align-items: flex-start;
  overflow: hidden;
  box-shadow: 0 0 20px #1d374d;
}

#slide li img {
  width: 100%;
  height: 100%;
}

.slide_right {
  padding: 40px;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  min-width: 0;
}

.slide_right dl {
  padding-top: 10px;
}

.arrow .prev, .arrow .next {
  position: absolute;
  width: 50px;
  top: 38%;
  z-index: 9;
  font: 700 96px 'simsun';
  opacity: 0.3;
  color: #fff;
  cursor: pointer;
}

效果:
1.左右滑动时,向相应方向移动一个卡片位置;
2.点击某一项时,将点击项位置移动到中间位置;

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务



前端 之 jQuery

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

文章目录
jQuery
jQuery的安装:
jQuery 语法
选择器
基本选择器:
层级选择器
基本筛选器
样式操作
表单筛选器
遍历方法
jQuery链式操作
jQuery 事件
$(document).ready()
click()
dblclick()
mouseenter()
mouseleave()
mousedown()
mouseup()
hover()
focus()
blur()
input()
取消标签默认的事件
事件冒泡
事件委托
jQuery自带的动画效果
jQuery
jQuery的字面意思其实就是JavaScript和查询(Query),即用于辅助开发JavaScript的库。jQuery 极大地简化了 JavaScript 编程,jQuery使用户可以更加方便地处理HTML(标准通用标记语言下的一个应用)、events、实现动画效果,而且方便地为网站提供AJAX交互。

实例找到div标签并给div标签设置为红色

原生js操作
var d1Ele = document.getElementById('d1');
d1Ele.style.color = 'red';
jQuery操作
$('#d1').css('color','blue');
1
2
3
4
5
jQuery的安装:
您可以从网页中添加 jQuery

1、从官网http://jquery.com/download/下载 jQuery 库

里面分为:Production version(用于实际的网站中,已被精简和压缩)和Development version(用于测试和开发,未压缩,是可读的代码),一般使用Production version压缩版本的。

2、从 CDN 中载入 jQuery, 如从 Google 或 百度 中加载 jQuery

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
或者
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
或者
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.slim.js"></script>
1
2
3
4
5
一定要先导入后使用

jQuery 语法
jQuery 语法是通过选取 HTML 元素,并对选取的元素执行某些操作。

$(selector).action()
1
美元符号定义 jQuery
选择符(selector)“查询"和"查找” HTML 元素
jQuery 的 action() 执行对元素的操作
选择器
jQuery 选择器可以对 HTML 元素组或单个元素进行操作。 jQuery 选择器基于元素的 id、类、类型、属性、属性值等查找HTML 元素。它基于已经存在的 CSS 选择器外,还有一些自定义的选择器。

基本选择器:
ID选择器、类名选择器、标签选择器、组合选择器

选择器 实例 选取
* $("*") 所有元素
#id $("#d1") id=“d1” 的元素
.class $(".name") class=“name” 的所有元素
.class , .class $(".name,.password") class 为 “name” 或 “password” 的所有元素
*element $(“span”) 所有 <span> 元素
el1,el2,el3 $(“h1,div,p”) 所有 <h1>、<div> 和 <p> 元素
提出注意点,原生DOM查找和jQuery查找出来的结果区别DOM对象与jQuery对象
DOM对象与jQuery对象互相转换
$('#d1')[0]
var d1Ele = document.getElementById('d1');
$(d1Ele)
1
2
3
4
层级选择器
选择器 实例 选取
parent > child $(“div > p”) <div> 元素的直接子元素的所有 <p> 元素
parent descendant $(“div p”) <div> 元素的后代的所有 <p> 元素
element + next $(“div + p”) 每个 <div> 元素相邻的下一个 <p> 元素
element ~ siblings $(“div ~ p”) <div> 元素同级的所有 <p> 元素
基本筛选器
选择器 实例 选取
:first $(“p:first”) 第一个 <p> 元素
:last $(“p:last”) 最后一个 <p> 元素
:even $(“tr:even”) 所有偶数 <tr> 元素
:odd $(“tr:odd”) 所有奇数 <tr> 元素
:gt(nu) $(“ul li:gt(3)”) 列举 index 大于 3 的元素
:lt(nu) $(“ul li:lt(3)”) 列举 index 小于 3 的元素
:eq(nu) $(“ul li:eq(3)”) 列举 index 等于 3 的元素
:not(selector) $(“input:not(:empty)”) 所有不为空的输入元素
:has(element) $(“div:has(a)”) 返回拥有一个或多个元素在其内的所有元素
/用ul标签举例
$('#ul>li:first')
$('#u1>li:last')
$('#ul>li:eq(3)')
$('#ul>li:even')
$('#ul>li:odd')
$('#ul>li:gt(3)')
$('#ul>li:lt(3)')
$('#u1>li:not(.c1)')

最后一个has的玩法需要写个三个div:一个空div、一个儿子有a标签、一个儿子没有a,孙子有a标签
$('div:has(a)')
输出:
k.fn.init(3) [div, div#d2, div#d3, prevObject: k.fn.init(1)]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
样式操作
方法 描述
addClass() 向被选元素添加一个或多个类名
after() 在被选元素后插入内容
append() 在被选元素的结尾插入内容
appendTo() 在被选元素的结尾插入 HTML 元素
attr() 设置或返回被选元素的属性/值
before() 在被选元素前插入内容
clone() 生成被选元素的副本
css() 为被选元素设置或返回一个或多个样式属性
detach() 移除被选元素(保留数据和事件)
empty() 从被选元素移除所有子节点和内容
hasClass() 检查被选元素是否包含指定的 class 名称
height() 设置或返回被选元素的高度
html() 设置或返回被选元素的内容
innerHeight() 返回元素的高度(包含 padding,不包含 border)
innerWidth() 返回元素的宽度(包含 padding,不包含 border)
insertAfter() 在被选元素后插入 HTML 元素
insertBefore() 在被选元素前插入 HTML 元素
offset() 设置或返回被选元素的偏移坐标(相对于文档)
offsetParent() 返回第一个定位的祖先元素
outerHeight() 返回元素的高度(包含 padding 和 border)
outerWidth() 返回元素的宽度(包含 padding 和 border)
position() 返回元素的位置(相对于父元素)
prepend() 在被选元素的开头插入内容
prependTo() 在被选元素的开头插入 HTML 元素
prop() 设置或返回被选元素的属性/值
remove() 移除被选元素(包含数据和事件)
removeAttr() 从被选元素移除一个或多个属性
removeClass() 从被选元素移除一个或多个类
removeProp() 移除通过 prop() 方法设置的属性
replaceAll() 把被选元素替换为新的 HTML 元素
replaceWith() 把被选元素替换为新的内容
scrollLeft() 设置或返回被选元素的水平滚动条位置
scrollTop() 设置或返回被选元素的垂直滚动条位置
text() 设置或返回被选元素的文本内容
toggleClass() 在被选元素中添加/移除一个或多个类之间切换
unwrap() 移除被选元素的父元素
val() 设置或返回被选元素的属性值(针对表单元素)
width() 设置或返回被选元素的宽度
常用实例:

三级菜单展示

$(this).next().removeClass('hide').parent().siblings().find('.items').addClass('hide')
1
直接操作css属性

// 两个参数设置属性
$('#p1').css('font-size','24px')
// 一个参数获取属性
$('#p1').css('font-size')

// 一次设置多个属性
$('#p1').css({"border":"1px solid black","color":"blue"})
1
2
3
4
5
6
7
位置操作

// 不加参数获取位置参数
$(".c3").offset()
// 加参数设置位置参数
$(".c3").offset({top:284,left:400})

// position只能获取值,不能设置值

// scrollTop获取当前滚动条偏移量
$('window').scrollTop();
$('window').scrollTop(0);  // 设置滚动条偏移量
1
2
3
4
5
6
7
8
9
10
文本操作

text() html() 不加参数获取值,加参数设置值
val() 不加参数获取值,加参数设置值
1
2
属性操作

// 获取文本属性
$('#d1').attr('s1')  // 获取属性值
$('#d1').attr('s1','haha')  // 设置属性值
$('#d1').attr({'num':50,'taidi':'gay'})  // 设置多个属性
$('#d1').removeAttr('taidi')  // 删除一个属性

// 获取check与radio标签的checked属性
$('#i1').prop('checked')
$('#i1').prop('checked',true)
1
2
3
4
5
6
7
8
9
文档处理

// 标签内部尾部追加元素
$('#d1').append(pEle)
$pEle.appendTo($('#d1'))

// 标签内部头部添加元素
$('#d1').prepend(pEle)
$pEle.prependTo($('#d1'))

// 标签外部下面添加元素
$(A).after(B)// 把B放到A的后面
$(A).insertAfter(B)// 把A放到B的后面

// 标签外部上面添加元素
$(A).before(B)// 把B放到A的前面
$(A).insertBefore(B)// 把A放到B的前面

// 替换标签
replaceWith()  // 什么被什么替换
replaceAll()  // 拿什么替换什么

// 克隆事例
<button id="b2">屠龙宝刀,点击就送</button>
// clone方法加参数true,克隆标签并且克隆标签带的事件
  $("#b2").on("click", function () {
    $(this).clone(true).insertAfter(this);  // true参数
  });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
表单筛选器
选择器 实例 选取
:input $(":input") 所有 input 元素
:text $(":text") 所有带有 type=“text” 的 input 元素
:password $(":password") 所有带有 type=“password” 的 input 元素
:checkbox $(":checkbox") 所有带有 type=“checkbox” 的 input 元素
:submit $(":submit") 所有带有 type=“submit” 的 input 元素
:reset $(":reset") 所有带有 type=“reset” 的 input 元素
:button $(":button") 所有带有 type=“button” 的 input 元素
:image $(":image") 所有带有 type=“image” 的 input 元素
:file $(":file") 所有带有 type=“file” 的 input 元素
:enabled $(":enabled") 所有启用的 input 元素
:disabled $(":disabled") 所有禁用的 input 元素
:selected $(":selected") 所有选定的 input 元素
:checked $(":checked") 所有选中的 input 元素
// 针对表单内的标签
$('input[type="text"]')
// 简化写法
$(':text')

// 找到所有被选中的checkbox
$(':checkbox')  // 注意select框中默认selected标签也会被找到
$('input:checkbox')
1
2
3
4
5
6
7
8
遍历方法
方法 描述
add() 把元素添加到匹配元素的集合中
children() 返回被选元素的所有直接子元素
closest() 返回被选元素的第一个祖先元素
contents() 返回被选元素的所有直接子元素(包含文本和注释节点)
each() 为每个匹配元素执行函数
filter() 把匹配元素集合缩减为匹配选择器或匹配函数返回值的新元素
find() 返回被选元素的后代元素
first() 返回被选元素的第一个元素
is() 根据选择器/元素/jQuery 对象检查匹配元素集合,如果存在至少一个匹配元素,则返回 true
last() 返回被选元素的最后一个元素
next() 返回被选元素的后一个同级元素
nextAll() 返回被选元素之后的所有同级元素
nextUntil() 返回介于两个给定参数之间的每个元素之后的所有同级元素
not() 从匹配元素集合中移除元素
offsetParent() 返回第一个定位的父元素
parent() 返回被选元素的直接父元素
parents() 返回被选元素的所有祖先元素
parentsUntil() 返回介于两个给定参数之间的所有祖先元素
prev() 返回被选元素的前一个同级元素
prevAll() 返回被选元素之前的所有同级元素
prevUntil() 返回介于两个给定参数之间的每个元素之前的所有同级元素
siblings() 返回被选元素的所有同级元素 Returns all sibling elements of the selected element
slice() 把匹配元素集合缩减为指定范围的子集
each() 方法为每个匹配元素规定要运行的函数。
$.each(array,function(index){
  console.log(array[index])
})
$.each(array,function(){
  console.log(this);
})
// 支持简写
$divEles.each(function(){
  console.log(this)  // 标签对象
})
1
2
3
4
5
6
7
8
9
10
11
jQuery链式操作
python代码诠释链式调用,其实就是在调用方法之后讲对象再次返回

<div>
<p>p1</p>
<p>p2</p>
</div>
$('div>p').first().addclass('c1').next().addclass('c2');
1
2
3
4
5
jQuery 事件
事件处理程序指的是当 HTML 中发生某些事件时所调用的方法。

$(document).ready()
$(document).ready() 方法允许我们在文档完全加载完后执行函数。为了防止网页还没加载完,js代码就已经执行,通常利用下面两种方式来书写js代码。

$(document).ready(function(){
// 在这里写你的JS代码...
})

网页最后
$(function(){
// 在这里写你的代码
})
1
2
3
4
5
6
7
8
click()
click() 方法是当按钮点击事件被触发时会调用一个函数。

在下面的实例中,当点击事件在某个<p> 元素上触发时,隐藏当前的 <p> 元素:

$("p").click(function(){ 
  $(this).hide(); 
});
1
2
3
dblclick()
当双击元素时,会发生 dblclick 事件。

$("p").dblclick(function(){ 
  $(this).hide(); 
});
1
2
3
mouseenter()
当鼠标指针穿过元素时,会发生 mouseenter 事件。

$("#p1").mouseenter(function(){ 
  alert("鼠标经过了!"); 
});
1
2
3
mouseleave()
当鼠标指针离开元素时,会发生 mouseleave 事件。

$("#p1").mouseleave(function(){ 
  alert("鼠标离开了!"); 
});
1
2
3
mousedown()
当鼠标指针移动到元素上方,并按下鼠标按键时,会发生 mousedown 事件。

$("#p1").mousedown(function(){ 
  alert("鼠标按下!"); 
});
1
2
3
mouseup()
当在元素上松开鼠标按钮时,会发生 mouseup 事件。

ouseup(function(){ 
  alert("鼠标松开!"); 
});
1
2
3
hover()
hover()方法用于模拟光标悬停事件。当鼠标移动到元素上时,会触发指定的第一个函数(mouseenter);当鼠标移出这个元素时,会触发指定的第二个函数(mouseleave)。

$("#p1").hover(function(){ 
  alert("你的光标悬停!"); 
  }, 
  function(){ 
  alert("你的光标已经离开!"); 
});
1
2
3
4
5
6
focus()
当元素获得焦点时,发生 focus 事件。

$("input").focus(function(){ 
  $(this).css("background-color","#eee"); 
});
1
2
3
blur()
当元素失去焦点时,发生 blur 事件。

$("input").blur(function(){ 
  $(this).css("background-color","#eee"); 
});
1
2
3
input()
input实时监听,输入内容时发生 input 事件

 $('#i1').on('input',function () {
        console.log($(this).val())
    });
1
2
3
取消标签默认的事件
利用preventDefault()
$('input').click(function (e) {
        alert(123);
        e.preventDefault();  
    });
直接返回false
$('input').click(function (e) {
        alert(123);
        return false;
    });
  
1
2
3
4
5
6
7
8
9
10
11
事件冒泡
iv>p>span  // 三者均绑定点击事件
$("span").click(function (e) {
        alert("span");
        e.stopPropagation();  // 阻止事件冒泡
    });
1
2
3
4
5
事件委托
<button>按钮</button>
<script src="jQuery-3.3.1.js"></script>
<script>
    $('body').on('click','button',function () {
        alert(123)
    })
</script>
1
2
3
4
5
6
7
jQuery自带的动画效果
下面的表格列出了用于创建动画效果的 jQuery 方法。

方法 描述
delay() 对被选元素的所有排队函数(仍未运行)设置延迟
dequeue() 移除下一个排队函数,然后执行函数
fadeIn() 逐渐改变被选元素的不透明度,从隐藏到可见
fadeOut() 逐渐改变被选元素的不透明度,从可见到隐藏
fadeTo() 把被选元素逐渐改变至给定的不透明度
fadeToggle() 在 fadeIn() 和 fadeOut() 方法之间进行切换
finish() 对被选元素停止、移除并完成所有排队动画
hide() 隐藏被选元素
queue() 显示被选元素的排队函数
show() 显示被选元素
slideDown() 通过调整高度来滑动显示被选元素
slideToggle() slideUp() 和 slideDown() 方法之间的切换
slideUp() 通过调整高度来滑动隐藏被选元素
stop() 停止被选元素上当前正在运行的动画
toggle() hide() 和 show() 方法之间的切换
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

微信小程序--实现canvas绘图并且可以复盘回看

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

目录结构:



index.wxml:

<view class="canvasBox">
  <canvas canvas-id="myCanvas" class="myCanvas" catchtouchstart='canvasStart' catchtouchmove='canvasMoving'></canvas>
</view>
<view class="btn">
  <button type="warn" bindtap='drawPen'>画笔</button>
  <button type="primary" bindtap='clearCanvas'>清空画板</button>
  <button type="warn" bindtap='clearLine'>橡皮擦</button>
  <button style='background:#000;color:#fff;' bindtap="black">黑色</button>
  <button style='background:yellow;color:#000;' bindtap="yellow">黄色</button>
  <button style='background:red;color:#fff;' bindtap="red">红色</button>
  <button style='background:blue;color:#fff;' bindtap="blue">蓝色</button>
  <button style='background:green;color:#fff;' bindtap="green">绿色</button>
  <button type="warn" bindtap="startRecording">开始录制</button>
  <button type="primary" bindtap='rePlay'>复盘</button>
  <button></button>
</view>
index.wxss:

.canvasBox{
  position: relative;
  top:0;
  left:0;
  width: 750rpx;
  height:800rpx;
  background:#eee;
}
.canvasBox .myCanvas{
  width: 100%;
  height:100%;
  position: absolute;
  top:0;
  left:0;
}
 
.btn{
  width: 750rpx;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.btn button{
  width: 180rpx;
  font-size: 24rpx;
}
index.js:

//index.js
//获取应用实例
import {hisData} from "../../utils/historyOperation.js";
const app = getApp()
var moveToX = 0, moveToY = 0, lineToX = 0, lineToY = 0;
var context = null;
var isStart = false;
var date;
var startDate;//开始时刻
var penType = "drawPen";
var colorStr = "#000";
var operationType = "mapping";
Page({
  data: {
    
  },
  
  canvasStart:function(e){
    var x = Math.floor(e.touches[0].clientX);
    var y = Math.floor(e.touches[0].clientY);
    date = new Date();
    moveToX = x;
    moveToY = y;
    operationType = "mapping";
    if(penType === "clearPen"){
      operationType = "clearLine";
    }
    if (isStart) {
      hisData.hisDataArr.push({
        time: date.getTime() - startDate,
        operation: operationType,
        lineArr: {
          startX: moveToX,
          startY: moveToY,
          currentX: x,
          currentY: y,
          z: 1,
          colorStr:colorStr
        }
      })
    }
  },
  //绘制线条
  canvasMoving:function(e){
    date = new Date();
    var x = Math.floor(e.changedTouches[0].clientX);
    var y = Math.floor(e.changedTouches[0].clientY);
    lineToX = x;
    lineToY = y;
    if(penType === "clearPen"){
      operationType = "clearLine";
      context.clearRect(x-12, y-12, 24, 24);
      context.draw(true);
    }else{
      operationType = "mapping";
      context.setStrokeStyle(colorStr);
      context.moveTo(moveToX, moveToY);
      context.lineTo(lineToX, lineToY);
    }
    if (isStart) {
      hisData.hisDataArr.push({
        time: date.getTime() - startDate,
        operation: operationType,
        lineArr: {
          startX: moveToX,
          startY: moveToY,
          currentX: lineToX,
          currentY: lineToY,
          z: 1,
          colorStr: colorStr
        }
      })
    }
    moveToX = lineToX;
    moveToY = lineToY;
    context.stroke();
    context.draw(true);
  },
  
  clearCanvas:function(){
    context.clearRect(0,0,375,400);
    context.draw(true);
    date = new Date();//记录当前操作时刻
    operationType = "clearCanvas";
    if(isStart){
      hisData.hisDataArr.push({
        time: date.getTime() - startDate,
        operation: operationType,
        lineArr: {
          startX: -1,
          startY: -1,
          currentX: -1,
          currentY: -1,
          z: 0,
          colorStr: colorStr
        }
      })
    }
  },
  
  drawPen:function(){
    penType = "drawPen";
  },
  clearLine:function(){
    penType = "clearPen";
  },
  black:function(){
    colorStr = "#000";
  },
  yellow: function () {
    colorStr = "yellow";
  },
  red: function () {
    colorStr = "red";
  },
  blue: function () {
    colorStr = "blue";
  },
  green: function () {
    colorStr = "green";
  },
  startRecording:function(){
    isStart = true;
    date = new Date();
    startDate = date.getTime();
  },
  rePlay:function(){
    wx.navigateTo({
      url: '../replay/replay',
    })
  },
  onLoad: function () {
    isStart = false;
    context = wx.createCanvasContext('myCanvas');
    context.beginPath();
    context.setStrokeStyle('#000');
    context.setLineWidth(5);
    context.setLineCap('round');
    context.setLineJoin('round');
  }
})
historyOperation.js:该文件用来保存历史操作,以便复盘

const hisData = {
  hisDataArr:[
    {
      time:0,//操作时间
      /**
       * 操作类型
       * 绘图:mapping
       * 拖动球员:moveplayer
       * 清除画布:clearCanvas
       * 橡皮擦:clearLine
       */
      operation:"mapping",//操作类型
      /**
       * 绘制路径
       * startX:开始x坐标
       * startY:开y纵坐标
       * currentX:目标位置的 x 坐标
       * currentY:目标位置的 y 坐标
       * z:1代表画线时鼠标处于move状态,0代表处于松开状态
       * colorStr:线的填充颜色
       */
      lineArr: {    //绘制路径
        startX:0,
        startY:0,
        currentX:0,
        currentY:0,
        z:0,
        colorStr:"#000"
      }
    }
  ]
};
 
export {hisData};
复盘:

reply.wxml:

<!--pages/replay/replay.wxml-->
<view class="replayBox">
  <canvas canvas-id='myCanvas' class="myCanvas"></canvas>
</view>
<button type="warn" bindtap="start">开始</button>
reply.wxss:

/* pages/replay/replay.wxss */
.replayBox{
  position:relative;
  width: 750rpx;
  height:800rpx;
  background: #eee;
}
 
.replayBox .myCanvas{
  position: absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
}
 
reply.js:

// pages/replay/replay.js
import {hisData} from "../../utils/historyOperation.js";
var startDate;
var date;
var curTime;
var context = null;
var timer = null;
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
 
  },
  start:function(){
    context.clearRect(0, 0, 375, 400);
    clearInterval(timer);
    date = new Date();
    startDate = date.getTime();
    var i = 0;
    var that = this;
    var len = hisData.hisDataArr.length;
    timer = setInterval(function(){
      date = new Date();
      curTime = date.getTime() - startDate;
      if (curTime >= hisData.hisDataArr[i].time){
        switch (hisData.hisDataArr[i].operation) {
          case "mapping":
            context.setStrokeStyle(hisData.hisDataArr[i].lineArr.colorStr);
            context.moveTo(hisData.hisDataArr[i].lineArr.startX, hisData.hisDataArr[i].lineArr.startY);
            context.lineTo(hisData.hisDataArr[i].lineArr.currentX, hisData.hisDataArr[i].lineArr.currentY);
            context.stroke();
            context.draw(true);
            break;
          case "clearCanvas":
            context.clearRect(0, 0, 375, 400);
            context.draw(true);
            break;
          case "clearLine":
            context.clearRect(hisData.hisDataArr[i].lineArr.currentX-12, hisData.hisDataArr[i].lineArr.currentY-12, 24, 24);
            context.draw(true);
            break;
        }
        i++;
      }
      if(i >= len){
        clearInterval(timer);
      }
    },2);
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    context = wx.createCanvasContext('myCanvas');
    context.beginPath();
    context.setStrokeStyle('#000');
    context.setLineWidth(3);
    context.setLineCap('round');
    context.setLineJoin('round');
  }
})
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

后端人员如何快速上手css(flex布局

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

网页布局(layout)是 CSS 的一个重点应用。毕竟简单的样式不能总依赖前端人员。
布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。


容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

先说第一个属性flex-direction 属性决定主轴的方向(即项目的排列方向)。
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
废话少说,立刻上代码,验证下。

row:

众所周知,h1和p都是块级元素,都会纵向排列,一旦采用 Flex 布局,就以x和y轴为基础排序,
column:

不但模糊了块级元素和行内元素的区别,而且左右的排序也很灵活。
row-reverse:

flex-wrap属性
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,就会换行。
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
(1)nowrap(默认):不换行。
(2)wrap:换行,第一行在上方。
(3)wrap-reverse:换行,第一行在下方。
wrap:

虽然他换行了,但是每行的元素是不是靠的太近了
在这时候就能用到
justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

flex-start:(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

space-between:

但是还是有点不对劲,原来没有垂直居中。
align-items属性就出来了
align-items属性定义项目在交叉轴上如何对齐。
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

还有很多属性可以灵活的调整页面的排版,我只举例最简单的几种排版。
没有float,没有position,也没有行和块。只要知道x轴和y轴就能轻松布局。
如果想了解flex布局,可以看一下这位大佬的博客:
语法篇:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
实战篇:http://www.ruanyifeng.com/blog/2015/07/flex-examples.html


日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档