在学习应用css之前我们要先了解一下什么是css。CSS是Cascading Style Sheets(层叠样式表)的简称.
边框(border): css控制的边框属性包括border-width, border-color, border-style.
Border之所以让人很困惑主要源于IE5错综复杂的BUG, 由于IE5是一个“will soon be dead” 的浏览器, 这里只例举一个最为知名的关于border-width的BUG, 让大家更好的理解border的含义, 先看下图:
如上图所示, 对象A(白色矩形)周围有蓝色边框B, 可以看出A的实际宽度为ef, 而IE5不这么认为, 它把cd的长度定义为对象A的宽度, 这个bug在边框的宽度小时几乎察觉不到, 但在边框与对象宽度相差不大时显得尤为明显.
新建一个前端学习qun438905713,在群里大多数都是零基础学习者,大家相互帮助,相互解答,并且还准备很多学习资料,欢迎零基础的小伙伴来一起交流。
现在, 结合以上说明, 可以看出border是独立于对象之外, 位于magin与padding之间(后说明), 具有固定宽度, 颜色和样式的区域.
width:160px;
height:60px;
display:block;
background:url(../image/button.png) no-repeat 0 0;
}
可以看到如 Example2 的效果.
width:160px;
height:60px;
display:block;
background:url(../image/button.png) no-repeat 0 0;
}
在css文件中写入以上代码, 目的在于控制盒子中链接的表现, 通过名为”#button a”的选择器来实现. 链接的宽高为160px*60px, 背景为图片button.png.
在这强调一下display:block的作用. 由于在html文件中,链接<a href=”#”> </a>中没有任何的内容(content)填充, 如果没有声明”display:block”, 那么即使声明了选择器”#button a”的宽高, 浏览器也会因为html文件中没有内容而无法显示链接. 所以”display:block”在这里的作用就在于强制浏览器显示没有内容填充的链接.
用伪类选择器a:link声明链接的背景图片在左上角显示, 即距离左边和顶边分别0, 0. 但由于已经在选择器 “#button a”中声明了图片位置, 此代码可有可无.
用伪类选择器a:hover声明鼠标悬停时, 背景图片上移60px, 而使排在第二位的绿色小图片显示出来;
用伪类选择器a:active声明在鼠标点击与释放之间的状态时, 背景图片上移120px, 而使排在第三位的红色小图片显示;
用伪类选择器a:visited声明在链接被点击或访问过时, 背景图片上移180px, 而使排在第四位的灰色小图片显示;
现在你基本了解了css动态按钮的制作过程, 但以上css代码还存在一个严重的缺陷, 相信你会很快发现问题所在——这个按钮居然是一个”一次性按钮“, 也就是说这个按钮在点击第一次后, 就一直显示那个灰色小图片, 你能想出解决方法吗?
文章目录
一、this
1.什么是this
2.this 代表什么
3.绑定 this 的方法
4.this的指向
5.改变指向
二、Function.prototype.bind()
三、call/apply
1.定义
2.语法
3.异同
一、this
1.什么是this
this 关键字在大部分语言中都是一个重要的存在,JS中自然不例外,其表达的意义丰富多样甚至有些复杂,深刻理解this是学习JS、面向对象编程非常重要的一环。
2.this 代表什么
this代表函数(方法)执行的上下文环境(上下文,类似与你要了解一篇文章,了解文章的上下文你才能清晰的了解各种关系)。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
1.在方法中,this 表示该方法所属的对象。
2.如果单独使用,this 表示全局对象。
3.在函数中,this 表示全局对象。
4.在函数中,在严格模式下,this 是未定义的(undefined)。
5.在事件中,this 表示接收事件的元素。
6.类似 call() 和 apply() 方法可以将 this 引用到任何对象。
3.绑定 this 的方法
this的动态切换,固然为 JavaScript 创造了巨大的灵活性,但也使得编程变得困难和模糊。有时,需要把this固定下来,避免出现意想不到的情况。JavaScript 提供了call、apply、bind这三个方法,来切换/固定this的指向。
4.this的指向
1.在一般函数方法中使用 this 指代全局对象
function test(){
this.x = 1; //这里this就是window
console.log(this.x);
}
test(); // 1
JS规定,函数中的this,在函数被调用时确定,它指函数当前运行的环境。
2.作为对象方法调用,this 指代上级对象
var x =3;
function test(){
alert(this.x);
}
var o = {
x:1,
m:test
};
o.m(); // 1
如果函数作为对象的方法时,方法中的 this 指向该对象。
3.作为构造函数调用,this 指代new 出的对象
function test(){
console.log(this);
}
var o = new test();
test();
//可以看出o代表的不是全局对象
new关键词的作用是调用某个函数并拿到其中的返回值,只是调用过程稍特殊。在上面的代码实例中。test函数被new关键词调用时,内部依次执行了以下步骤:
(1)创建一个空对象。
(2)将这个空对象的原型,指向这个构造函数的prototype。
(3)将空对象的值赋给函数内部的this(this就是个空对象了)。
(4)执行函数体代码,为this这个对象绑定键值对。
(5)返回this,将其作为new关键词调用oop函数的返回值。
所以构造函数中的this,依旧是在构造函数被new关键词调用时确定其指向,指向的是当前被实例化的那个对象。
4.箭头函数中的this
箭头函数是ES6的新特性,最重要的特点是它会捕获其所在上下文的this作为自己的this,或者说,箭头函数本身并没有this,它会沿用外部环境的this。也就是说,箭头函数内部与其外部的this是保持一致的。
this.a=20
var test={
a:40,
init:()=>{
console.log(this.a)
function go(){
this.a=60
console.log(this.a)
}
go.prototype.a=50
return go
}
}
var p=test.init()
p()
new (test.init())()
//输出 20 60 60 60
5.改变指向
this的动态切换,固然为 JavaScript 创造了巨大的灵活性,但也使得编程变得困难和模糊。有时,需要把this固定下来,避免出现意想不到的情况。JavaScript 提供了call、apply、bind这三个方法,来切换/固定this的指向。
bind方法和apply、call稍有不同,bind方法返回一个新函数,以后调用了才会执行,但apply、call会立即执行。
二、Function.prototype.bind()
bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;
示例:
function f(y, z){
return this.x + y + z;
}
var m = f.bind({x : 1}, 2);
console.log(m(3));
//6
1
2
3
4
5
6
这里bind方法会把它的第一个实参绑定给f函数体内的this,所以这里的this即指向{x : 1}对象,从第二个参数起,会依次传递给原始函数,这里的第二个参数2,即是f函数的y参数,最后调用m(3)的时候,这里的3便是最后一个参数z了,所以执行结果为1 + 2 + 3 = 6分步处理参数的过程其实是一个典型的函数柯里化的过程(Curry)。
三、call/apply
1.定义
每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
call和apply可以用来重新定义函数的执行环境,也就是this的指向;call和apply都是为了改变某个函数运行时的context,即上下文而存在的,换句话说,就是为了改变函数体内部this的指向。
2.语法
call()
调用一个对象的方法,用另一个对象替换当前对象,可以继承另外一个对象的属性,它的语法是:
Function.call(obj[, param1[, param2[, [,...paramN]]]]);
1
obj:这个对象将代替Function类里this对象
params:一串参数列表
说明:call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为obj指定的新对象,如果没有提供obj参数,那么Global对象被用于obj。
apply()
和call()方法一样,只是参数列表不同,语法:
Function.apply(obj[, argArray]);
obj:这个对象将代替Function类里this对象
argArray:这个是数组,它将作为参数传给Function
说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和obj任何一个参数,那么Global对象将用作obj。
3.异同
相同点
call()和apply()方法的相同点就是这两个方法的作用是一样的。都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向,看个例子:
function add(a, b) {
return a + b;
}
function sub(a, b) {
return a - b;
}
console.log(add.call(sub, 2, 1));//3
为什么add.call(sub, 2, 1)的执行结果是3呢,因为call()方法改变了this的指向,使得sub可以调用add的方法,也就是用sub去执行add中的内容,再来看一个例子:
function People(name, age) {
this.name = name;
this.age = age;
}
function Student(name, age, grade) {
People.call(this, name, age);
this.grade = grade;
}
var student = new Student('小明', 21, '大三');
console.log(student.name + student.age + student.grade);//小明21大三
在这个例子中,我们并没有给Student的name和age赋值,但是存在这两个属性的值,这还是要归功于call()方法,它可以改变this的指向。
在这个例子里,People.call(this, name, age);中的this代表的是Student,这也就是之前说的,使得Student可以调用People中的方法,因为People中有this.name = name;等语句,这样就将name和age属性创建到了Student中。
总结一句话就是call()可以让括号里的对象来继承括号外函数的属性。
至于apply()方法作用也和call()方法一样,可以这么写:
People.apply(this, [name, age]);
1
或者这么写:
People.apply(this, arguments);
1
在这里arguments和[name, age]是等价的。
不同点
从定义中也可以看出来,call()和apply()的不同点就是接收参数的方式不同。
1.apply()方法接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
2.call()方法不一定接受两个参数,第一个参数也是函数运行的作用域(this),但是传递给函数的参数必须列举出来。
在给对象参数的情况下,如果参数的形式是数组的时候,比如之前apply()方法示例里面传递了参数arguments,这个参数是数组类型,并且在调用Person的时候参数的列表是对应一致的(也就是Person和Student的参数列表前两位是一致的)就可以采用apply()方法。
但是如果Person的参数列表是这样的(age,name),而Student的参数列表是(name,age,grade),这样就可以用call()方法来实现了,也就是直接指定参数列表对应值的位置Person.call(this,age,name)。
一、什么是字体图标
字体图标:简单的说,就是一种特殊的字体,通过这种字体,显示给用户的就像一个个图片一样,但它的本质是文字。目前在移动端应用比较广泛!
二、字体图标的使用步骤
这里以阿里巴巴矢量图标库为例!!!
sep1:
百度搜索iconfont,找到阿里巴巴矢量图标库官网
网址在这里https://www.iconfont.cn/
进去之后注册或登录,共有3种登录方式,在这里我使用新浪微博账号登录
好了,登录之后我们就可以在里面选择自己想要的字体图标啦!!!那么,如何选择下载并应用到自己的项目中呢??别着急,跟着我走!
sep2:下载字体图标字体库
在这里我们可以根据自己的需求输入相应的关键字进行搜索(中英文都可以)
鼠标放上去,然后就可以把自己喜欢的宝贝加入购物车啦!
网购的赶脚有木有,
我知道,看到这里大家就该有疑问了,
还要花钱买吗?
放心!
答案是:不需要!
我们选的东西都在购物车里啦!
打开购物车,就能看到你选的图标了!!
接下来你要做的是把它们下载到本地。
由于要在网页中使用
在这里我们选择 下载代码
下载后将压缩包解压,为了方便后续使用我们改一下文件夹名称,在这里我改为 icon (注意:在HTML中导入路径时,记得带上你所改的文件夹名称)
打开之后你会发现里面有不同类型的文件(建议都不要删除)
打开后缀名为.html的这个文件(可以更直观地查看自己下载的字体图标)
step3:在项目中引用字体图标
不要走开,重点来了!!!
官方提供了三种引用方法(下面对应的都有步骤)
Unicode 引用
Unicode 是字体在网页端最原始的应用方式,特点是:
兼容性最好,支持 IE6+,及所有现代浏览器。
支持按字体的方式去动态调整图标大小,颜色等等。
但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式
Unicode 使用步骤如下
第一步:拷贝项目下面生成的 @font-face
@font-face { font-family: 'iconfont'; src: url('iconfont.eot'); src: url('iconfont.eot?#iefix') format('embedded-opentype'), url('iconfont.woff2') format('woff2'), url('iconfont.woff') format('woff'), url('iconfont.ttf') format('truetype'), url('iconfont.svg#iconfont') format('svg'); }
第二步:定义使用 iconfont 的样式
.iconfont { font-family: "iconfont" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
第三步:挑选相应图标并获取字体编码,应用于页面
<span class="iconfont">3</span>
font-class 引用
font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。
与 Unicode 使用方式相比,具有如下特点:
兼容性良好,支持 IE8+,及所有现代浏览器。
相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
不过因为本质上还是使用的字体,所以多色图标还是不支持的。
使用步骤如下:
第一步:引入项目下面生成的 fontclass 代码:
<link rel="stylesheet" href="./iconfont.css">
第二步:挑选相应图标并获取类名,应用于页面:
<span class="iconfont icon-xxx"></span>
symbol 引用
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:
支持多色图标了,不再受单色限制。
通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
兼容性较差,支持 IE9+,及现代浏览器。
浏览器渲染 SVG 的性能一般,还不如 png。
使用步骤如下:
第一步:引入项目下面生成的 symbol 代码:
<script src="./iconfont.js"></script>
第二步:加入通用 CSS 代码(引入一次就行):
<style> .icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style>
第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon" aria-hidden="true"> <use xlink:href="#icon-xxx"></use> </svg>
下面,我就跟大家详细说说 font-class 引用的引用方式:
打开编辑器(在这里我使用的是 VS Code编辑器),新建一个项目文件夹(demo)
将解压后的字体图标文件夹(icon)直接放到demo目录下
在demo文件夹下面新建一个html文件 demo.html
导入icon文件夹里面的外部样式表
<link rel="stylesheet" href="./icon/iconfont.css">
iconfont.css 里面就是我们下载的字体图标的所有css样式了,我们打开看看吧!
你会发现里面有一个 iconfont类名(这里划重点!后面要用),它是所有字体图标的公用样式。
这时我们就可以在页面中使用这些字体图标啦!上面我们只是导入了整个css样式表,现在我们要针对性地把某个图标引用到html页面中,并在网页中显示出来。
下面 我们就开始写页面的主体部分吧!
<p> 我有一个梦想:能够拥有一套 <span class="iconfont icon-home"></span> </p>
这里的span标签里面放的就是要用的某个字体图标了,你会发现它用了两个class类名。
第一个是iconfont,也就是我前面划的重点(到这里不明白的话,可以再回头看看)
第二个是icon-home,这个类名从何而来呢?
来,继续往下看,再次打开icon文件夹下的
话不多说,直接看图
是不是对应上啦!简单地说就是你要用那个图标就添加它的class类名。
到这里,恭喜你已经学会了如何在网页中插入字体图标啦!!!
那么,赶快运行一下看看效果吧!
到这里是不是还满足不了你的需求,会有这样的疑问:如果是这样的效果,跟一张图片有什么区别呢???
当然不是啦!
之所以叫做字体图标,顾名思义,它在网页中就是一种字体的存在,不过它比普通字体长得好看些有木有!
我们可以像更改文字样式一样去更改它的样式,比如说 大小、颜色、阴影…
Symbol 引用方式还可以实现下面原图标的彩色效果哦!可以自己照着官方提供的步骤试试看
下面附上Font class引用方法的 源代码 供参考
前面的步骤一定要看!!!
如果前期工作没做的话,直接用我的源代码是实现不了的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>字体图标</title>
<link rel="stylesheet" href="./icon/iconfont.css">
<style>
.iconfont{
font-size: 200px;
color: palevioletred;
text-shadow: 18px 17px 17px gray;
}
</style>
</head>
<body>
<p>
我有一个梦想:能够拥有一套
<span class="iconfont icon-home"></span>
</p>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
花费了很长时间整理出来的。
很简单是不是!!!
看到这里还不会的话,建议重新再看一遍!
其中有错误的话,还请指出,我会虚心接受并改正!!!
————————————————
版权声明:本文为CSDN博主「Humy.」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42678796/article/details/104569773
左右布局响应策略动态演示。考虑到gif被压缩后效果不理想,所以做了一小段视频来帮助大家更好的理解响应策略。视频如果看着不清晰,选择清晰度为1080p蓝光观看即可
一、什么是响应式?
按照本人自己的理解,响应式就是通过合理的设计方案配合规范的技术实现策略,使同一个Web页面在各个终端(设备)不同分辨率屏幕上都能有最佳的用户体验。
这里说是用户体验而不是视觉效果是因为用户体验包含了性能、交互、效率等多方面内容,也就是说,对于一个线上的响应式页面,我们不仅要关注视觉上看到的,也要关注我们操作、使用时的感受,这些综合因素最终影响着用户使用后台系统时的效率与体验。而这里我提到的“合理的设计方案”就是本篇文章跟大家分享的重点:如何利用栅格系统完成后台页面的响应式设计。对于交互与性能方面内容,本篇文章不做介绍,因为两者涉及到我不太了解的技术相关知识。我提出这个观点主要希望大家在执行设计时,能有更全局的考虑,多跟交互与开发沟通,协力打造更好的用户体验
三、响应式的目的是什么?
后台系统做响应式设计的目的:提高屏幕利用率,最大化操作效率
1、提高屏幕利用率最简单的理解就是在大屏幕上显示更多内容,在小屏幕上通过数据筛选展示关键信息。一直以来大家普遍认为移动端碎片化严重,但实际上桌面端设备的分辨率也是有着不太均匀的分布,而随着新设备的更新,更多高分辨率屏幕不断加入,这种碎片化的趋势会更加明显,因而要想利用好每一块屏幕,让不同分辨率的用户都有好的体验,显然传统固定的布局是做不到了。
2、后台系统的应用特性,决定了响应式在后台设计中具有很高的实用价值。后台系统有两大主要功能:查看与操作。查看主要是各种数据,是系统自动生成的内容;操作是需人工干预、人工决策的任务,查看的数据为操作提供了依据,而操作支撑了公司或部门业务的正常运行。所以后台系统设计最基础的目标之一是如何通过良好的数据展示帮助用户提高操作、决策效率,而充足的展示空间显然是实现这一目标的基础,响应式设计通过为每个分辨率设定合理的版式布局,使数据在每块屏幕上都尽可能展示的最佳。优化后的数据展示,帮助用户更获取信息,从而提高了用户使用后台系统的效率与体验。
四、为何要利用栅格系统来进行响应式设计
响应式可以响应的前提有两点:1、页面布局具有规律性、2、元素宽高可用百分比代替固定数值,而这两点正是栅格系统本身就具有的典型特点,所以利用栅格系统进行响应式的设计是顺理成章的,也比较快捷,所以响应式与栅格化天生一对好搭档
栅格系统页面布局具有规律性、元素宽高可用百分比表示
五、利用栅格系统完成后台页面响应式设计的步骤
1、确立设计稿基准尺寸
设计稿基准尺寸是指我们从哪一个分辨率开始设计,也就是我们新建画板时画板的尺寸应该是多大。而这个尺寸确定的主要依据是我们后台系统所面向的主要用户的屏幕分辨率;我们分两大类情况来讨论这个问题。
(1)、如果我们的系统是给公司内部员工使用,由于公司批量采购设备的原因,公司内部员工的屏幕分辨率往往会比较统一,这种情况下我们需要拿到这个数据,然后以它作为基准尺寸开始设计。因为虽然响应式设计的目标是让页面在每个分辨率下都有最佳的体验,但实际开发中毕竟存在损坏,设计还原很难100%,因而大多数情况下还是基于基准尺寸的设计与开发,在用户端显示效果最佳、体验最好
。
(2)、如果我们的系统是平台级面向全网用户,或者虽然是公司内部使用,但是并不能统计到内部员工屏幕分辨率情况,就可以以1440*900作为基准尺寸开始设计。从统计数据来看,目前国内PC端用户屏幕分辨率排名前三的分别是1920*1080、1366*768、1400*900;1440的尺寸实际上是处于中间位置,如果以它为基准设计,最终向上向下响应适配后,相对误差最小,从而达成用户体验的最大公约数。
2、确定页面布局结构
页面的布局结构,是页面基本框架,后续的设计都是在这个大的框架下完成的,所以确定页面基准设计尺寸后,需要跟交互设计师或产品经理配合,根据实际业务情况讨论确定页面布局结构。一般来讲,后台系统有两种最典型的页面布局结构:左右布局与上下布局(这两种布局是最典型也是最基础的布局形式,其余布局,下期内容讲)
上下布局
上下布局的结构在传统网页中非常常见,而在后台系统中并不常用。这种布局的优点是符合用户认知,遵循用户从上而下浏览页面获取信息的习惯;贯穿全屏的导航栏设计也使页面显得正式稳重,除却导航栏之后相对较大的空间也为内容展示提供了比较充足的空间。缺点是顶部一级导航受页面宽度限制,数量会比较局限,同时导航层级较深时,交互效率也不够理想。所以该布局适合那些导航层级较少,内容展示充分的后台系统设计
左右布局
拥有侧边导航的左右布局页面结构,是在后台系统中更常见的页面布局形式。侧边导航栏可以固定也可以收起,相对比较灵活,同时文字横向排列的形式可以在竖向上展示更多内容,因此侧边导航比顶部导航能容纳更多一级内容,而层叠式的内容展示也使得一、二、三级导航内容关联更为顺畅,可扩展性也得到加强;由于侧边栏可以常驻在页面左侧,所以对于右侧内容的指示性也优于顶部导航,切换起来也更加方便。但同时,因为侧边栏的常驻,导致右侧内容区域空间被挤掉部分,所以相对上下布局的结构,左右布局的结构,内容区域空间会比较小;一般为了与页面其它区域做区分,导航部分会用更深的颜色、安排更多的图标和文字,这也导致了在视觉上左右布局的页面不够平衡,会有左边重右边轻的感觉。
3、对内容区域建立栅格系统
根据不同的布局类型,对页面内容区域建立栅格系统。对于一个利用栅格系统做响应式设计的页面来讲,主要有三大数值需要规范:Column、Gutter、Margin;对于Column、Gutter我们在上一期内容中已经有很详细的介绍,不再赘述,而Margin是页边距,主要确定了内容区域距离页面边缘的距离,它分布在内容区域的两侧,主要作用是通过留白把内容区域与周围环境隔离出来,从而突出内容区域的显示,此外还可通过Margin值来调整内容区域显示比例,使页面在视觉上有更好的呈现效果。所以一个用于响应式的栅格系统事实上由Columns、Gutters、Margins三部分组成。
上下布局结构与其对应的栅格系统
左右布局结构与其对应的栅格系统
4、根据实际业务内容确定盒子(Box)比例
上下布局结构的盒子
左右布局结构的盒子
5、确定响应策略
响应策略就是当视窗(Viewport)发生变化时,内容区域的元素如何去响应,具体到我们当前的栅格系统,就是Columns、Gutters、Margins以及由Columns跟Gutter组成的盒子(BOX)四者的值(主要是宽度)如何变化,以及在这种变化之下我们页面的布局如何调整。
为了方便直观的向开发工程师与团队里的其它小伙伴沟通,我们可以把这个响应策略制作成如下的表格,并在页面中标注说明相关元素的变化规律,供自己与开发参考。
由于带左侧导航的响应式规则相对复杂,所以我先以它为例跟大家交流下响应策略如何制定
左右布局响应策略表
如图,响应式是以视窗的最小宽度作为基本依据来制定每种宽度下Columns、Gutters、与Margins的响应策略,也就是说Viewport Min-width是做出响应的触发条件,视窗每达到一个最小宽度,就会触发该宽度下预设的页面布局方式,而每种布局都是在该宽度下的最佳布局,也是因此,响应式才会在各种复杂分辨率条件下都能给用户比较好的体验。
每个视窗宽度的最小值是触发响应的关键值,因此我们给这些用于触发的关键值起了个名字叫“Breakpoint”,每个Breakpoint触发一种响应策略,而每个策略持续(保持)的宽度范围就是图中绿色矩形的范围。以图中第二行矩形为例,该矩形代表的响应策略是:栏目数是8、水槽宽度16(SM)、页边距32、侧边栏收起且仅展示图标,当点击侧边栏展开图标时侧边栏以Push的方式展开,该策略触发的Breakpoint是768,保持范围是577~768。也就是当视窗宽度缩放至768时,栏目数量由上一级的12变为8,水槽宽度由24变为16,侧边导航由完全展开状态自动收起文字部分,仅保留图标,然后保持这些关键数值不变,直到视窗宽度达到另一个Breakpoint。需要特殊说明的是,第一行矩形中0~576(Min&Fixed)这个范围的视窗宽度是固定的,也就是在该套响应策略中,页面最小响应到576的页面宽度,当视窗到达这个宽度时,浏览器会限制视窗进一步缩小,因为当页面宽度比它还小时已经无法有效展示数据了,所以进一步的缩放是毫无意义的。
左右布局响应策略动态演示
考虑到gif被压缩后显示效果不理想,所以我做了一小段视频来帮助大家更好的理解上述响应策略在实际页面中如何发挥作用。视频如果看着不清晰,选择清晰度为1080p蓝光观看即可
左右布局响应策略标注
对于上下布局的后台系统我们根据内容区域(Container)宽度定义的不同方式,可以把它们分为两类:
1、内容区域定宽的后台系统( Fixed-width Container )
内容区域定宽是指内容区域在每一组视窗宽度区间内,都会设定一个最大值(Max-with),当内容区域宽度小于最大值时,区域内元素会响应视窗的变化;达到最大值后,内容区域不再响应视窗的变化,而是宽度保持该最大宽度值不变,此时我们通过增加页面两侧的margin值来响应视窗的变化。Flex Margin就是应对此情况的动态页边距。
上下布局响应策略表(内容区域定宽( Fixed-width Container ))
2、内容区域宽度流式 (fluid-width Container)
内容区域宽度流式 (fluid-width Container) 的后台系统,它的内容区域 (Container) 距离页面两侧的页边距Margin是定值,因此视窗有多大内容区域就展示多大。
Q&A
1、后台系统必须做成响应式么?
并不是必须的,是否要做响应式主要是根据后台产品面向的用户来定的。如果是公司内部使用的系统,且员工配备的桌面设备都是有统一的分辨率,就可以不做响应式;如果是面向全网用户的后台产品(比如淘宝商家的后台管理系统,阿里云的控制台)或公司(部门)内部的桌面设备并没有统一的分辨率规格,那么就需要做成响应式。当然了,更实际的环境中是否做响应式还有技术实现、时间、人员成本等各方面因素的考虑,有时为了尽快的让业务运营起来,后台系统会做的比较“简陋”
2、为什么栅格系统没有适配到移动端的分享?
因为后台管理系统的使用场景主要是工作时间在桌面设备上使用,由于庞杂的数据内容在移动设备上展示困难、操作不便,因而很少有公司会把后台系统响应到移动端使用,所以我们今天说的后台响应式仅针对桌面设备屏幕。
3、对于iMac4k、5K这类超高分辨率的屏幕如何做响应式设计?
对于左右布局的后台系统,实际上它是全屏展示的,也就是屏幕有多大就展示多大,因而iMac的响应策略也是按照左右布局响应策略表里的策略来响应对于上下布局,内容区域定宽的后台系统,iMac的响应策略使用上下布局响应策略表里的策略来响应即可;
对于内容区域宽度流式的后台系统,iMac的响应策略可以参考左右布局的响应策略表来处理栏目、水槽的变化,页边距保持定值即可。
4、在以8为原子单位的栅格中,Margin需要按8n的规律变化么?
能以8n的规律变化是最好的,如果无法做到也可以使用其它数值。Margin是页边距,主要作用是通过留白的方式将页面内容区域与周围环境隔离区分出来,从而突出内容;一般我们会优先考虑内容区域匹配8n的变化规律,安排完内容区域后剩余的空间自然成为页边距(margin)
5、响应策略制定的时机是什么?如何去制定?文中示例的策略表我可以借鉴套用么?
响应策略表一般是在主要页面设计完成,要交付开发实现的时候来跟开发一起商定。这块需要注意两点:
1、如果开始设计时就已确定页面是要具备响应式的能力,那么最好开始设计时就去跟开发沟通,看他们现有技术是如何来做响应式的,因为他们很有可能是在用Bootstrap、Foundation这类组件库来做开发,而这些组件库一般都有自己现成的响应规则,这种情况下我们需要了解开发他们的规则,让自己的设计匹配已有的策略。当然了,如果他们的规则并不能很好满足我们的业务需要,一般也是可以在这些组件的基础上让开发去修改调整的。
2、响应策略表只是对响应方式的结果的呈现,而这个策略的制定事实上是从设计开始执行时就要去考虑的,从我个人经验来讲,我一般会挑两类页面来做响应策略的研究与适配,一个是控制台(Dashboard)页面,另一个是表单(Form)页面。优先规划这两个页面的设计,考虑他们在各个Viewport下如何布局如何展示如何缩放变化,并且跟开发沟通想法,听取意见,制定初步的响应计划,当这两个页面设计完成,就可以更大范围的执行设计。
3、文中示例的策略表是基于我自己项目经验总结而来,具有实际应用价值,可以借鉴。但我更想做的是通过那个表希望跟大家分享一种与开发交流、沟通的方法和技巧。实际工作中我们并非一定要做出那么一个经过精心设计细致考虑的表,我们可能会找张纸画一画给开发看就可以了,这块的重点是如何把我们设计师的想法更可视化更直观准确的传达给开发工程师。所以那张表是启发而非标准。
控制台(Dashboard)页面示例(素材图片作者:Coderthemes)
表单(Form)页面示例
关于栅格系统文章不少,但鲜有专门针对栅格系统在后台设计中相关应用的介绍。本文抛砖引玉,希望引起更多同行的交流与讨论
栅格系统的目的
栅格系统在页面排版布局、尺寸设定方面给了设计者直观的参考,它让页面设计变得有规律,从而减少了设计决策成本;栅格化提高了页面布局的一致性跟复用性;避免了设计师与开发者在细节上的反复沟通确认,从而提升了整个设计开发流程的效率、并能帮助开发者实现较为理想的设计还原。
但实际应用中,由于对栅格系统理解的不充分,很多设计师在应用栅格系统的实践中产生了各种问题,本来帮助设计的工具现在反而成了设计中需要解决的问题。结合我自己后台设计的经验,本篇文章跟大家聊聊栅格系统在后台设计中如何应用。
建立栅格系统的方法与规则
1、第一步:确立栅格系统的原子单位(网格)
如图,一个比较完整的栅格系统是由许多规格一致的小网格组成,这些网格辅助我们更规范的排版、布局。
后台系统设计中,由于后台页面主要以Web形式呈现,而对于web,用户已习惯通过鼠标滚轮或滚动条(scrollbar)来纵向浏览页面内容,因此,在不考虑内容优先级的情况下,Web可以实现竖直方向的“无限”加载,即竖直方向可以无限延伸,因此基于Web的后台页面,它的栅格系统在水平方向的栅格可以不体现出来,我们在执行设计时只要在竖直方向保持规律的变化就可以了。标准的栅格系统简化为适用于Web后台的设计如下图所示
如上图,对于后台设计来讲,栅格系统是由栏目(Column)跟水槽(Gutter)交替分布形成的,栏目(Column)是接纳网页内容的容器,水槽(Gutter)用来调节相邻两个栏目间距,把控页面留白;由于栏目跟水槽的宽度是以网格作为基本单位来增加或者减小,所以栅格化的第一步需要先定义好栅格的原子单位“网格”的大小。根据本人的设计实践以及其它已有规范经验,目前后台栅格系统网格大小定义为8是最普适易用的。具体原因有以下几点:
(1)目前主流桌面设备的屏幕分辨率在竖直与水平方向基本都可以被8整除,使用8作为最小原子足够普适.
我们选取4、6、8、10、12为栅格的候选原子单位,然后用目前主流屏幕分辨率与其相除,判断各个分辨率在竖直(Y)与水平 (X)方向能否被候选原子整除,统计结果如图。
显然,对于目前市场桌面设备屏幕而言,4是整除率最高的一个原子,接下来依次是8、10、6、12。但4作为基本原子实在过于小了,太小的步进单位将导致我们决策成本的增加,因为我们将元素间间距增加4px或者减小4px视觉感受到的差异并不明显,这种情况下我们为了找到那个“合适、满意”的间距,就需要反复调试,这就造成了时间上的浪费,尤其对于没有经验的新人,这点会更为突出。但这种调整并不合适,原因是后台管理系统设计重点在于面向用户使用的效率与逻辑,其次才是视觉呈现,使用栅格系统的目的之一也是想减少设计师在“细节”上的纠结,希望设计师站在更全局的角度看待设计,合理安排时间,因此我们舍弃4。在剩下的6、8、10、12四个单位中,8的整除率最高(80%),以8像素作为一个步进单位的变化,我们视觉上也是能感受到较为明显的差异,因此选取整除率最高的8做为栅格系统的原子单位。
(2)以8为单位符合“偶数原则”。偶数原则可以在页面缩放中的避免类似于0.5、0.75、1.25等次像素的出现,从而使页面各类元素在大多数场景下都能有比较精致的细节表现
虽然对于后台设计而言,通常设计师是直接在目标尺寸下进行设计,并在此基础上标注、切图给开发实现,并不存在像移动端那样需要对各种尺寸、各种像素密度的设备进行适配的情况,但对于Web页面来讲,仍存在向上向下适配的可能,因而从页面的兼容性、可扩展性及可维护性层面来讲,我们设计师还是有必要考虑的更加长远,遵循“偶数原则”可以上避免各种潜在的问题。
(3)开发工程师使用的前端开源组件库比如Metronic、Antdesign等也是基于8的原子单位来设计,因此如果设计师也使用以8为基本单位的栅格系统,开发与设计师相互对接就会更加方便,开发实现页面时也能更高品质的去还原我们设计师的稿件
2、第二步:建立基于原子单位的栅格系统
经过第一步讨论,我们现已确定后台设计的原子单位为8,而我们也知道栅格系统是由栏目(Column)跟水槽(Gutter)交替分布形成的,所以接下来我们要利用原子单位确定栏目跟水槽在具体的页面中如何分布以及它们各自的宽度。
通常,在一套后台设计系统中,水槽宽度会是几个比较固定的数值(因为后台系统的页面相对于其它类型的Web页面,表现的更加整齐、规律,所以留白的方式比较固定,加之后台往往有大量的数据、内容需要呈现,所以要尽可能提高页面利用率,可以留白的空间也比较有限);而栏目宽度更加灵活,它可以根据页面水平方向尺寸的改变而增大或减小以响应页面的变化(遵循8n的变化规律,此处变化规律在下期文章《栅格化与响应式》里会详细介绍)。
当我们做后台设计的时候首先需要确定在什么样的分辨率下做设计,也就是首先需要确定设计稿的尺寸,当设计稿尺寸确定后,便可建立基于该尺寸的栅格系统。假设页面内容区域宽度为W,栏目个数为A,水槽个数为B,栏目(Column)宽度为C,水槽(Gutter)宽度为G,则W=A*C+B*G。栅格系统建立初期,由于我们并不确定之后会有什么样的内容呈现我们的页面上,所以为了让栅格更加灵活、普适,我们先假定单个栏目与水槽的宽度是相同的,即C=8n(n=1、2、3、4...)=G,然后以此将页面内容区域等分,形成初步的栅格,之后再按实际内容需要,按比例调整两者宽度或者按比例对两者进行组合,形成承载业务内容的盒子。目前有两种比较主流的等分方式:12等分与24等分。
12等分的栅格系统在流行的前端开发开源工具库Bootstrap与Foundation中广泛使用,适用于业务信息分组较少,单个盒子内信息体积较大的中后台页面设计;
24等分的栅格系统适用于业务信息量大、信息分组较多、单个盒子内信息体积较小的中后台页面设计;相对12栅格系统,24栅格系统变化更加灵活,更适合内容比较多样复杂的场景。
栅格系统的应用
1、页面布局与版式设计
(1)、了解承载业务内容的盒子模型(Box Model)
建立好栅格系统后,就可以根据自己的实际业务,在栅格系统上安排内容了。页面上最终承载内容的其实是一个个“盒子(Box)”,这个盒子的高度由盒子要容纳的内容与页面版式设计决定,按8n规律变化;宽度则由栏目与水槽按比例组合得到。
在栅格系统上容纳业务内容的容器我们把它称之为盒子(Box),栅格系统上的盒子其实跟前端工程师写页面时用到的盒子是一致的。如图所示,当我们浏览任何一个网页时,右键>检查元素(审查元素),然后在style菜单下就可以看到这个盒子结构了。其中Padding就是主体内容(Element)距离盒子外侧的距离,我把它称之为内边距,(Element可以是一个按钮,一段文本、一张图片或者一个表格等;)而Margin就是相邻两个盒子间的距离,对应在后台栅格系统中其实就是水槽的大小。了解完栅格系统的盒子模型之后,下一步我们需要根据具体业务内容来确定盒子的宽度,也就是如何利用栅格系统做实际内容的布局与版式设计
(2)、根据业务内容分配页面比例,确定盒子宽度
以24栅格系统为例,一个24栅格系统可以根据业务需要被2等分、3等分、4等分、6等分、8等分、12等分,还可以被1:1:1、1:2:1、1:3:2、2:3:3、1:2、1:3、1:5、3:5等不对称分割,具体采用哪种比例的组合需要我们根据自己业务需求来定,我们此处所说的比例实际上就是盒子的宽度。
上图展示了盒子在24栅格系统上的分布情况,图中只列举了部分比例,实际业务中,同一个页面上使用一到两组比例值的组合来布局是比较合适的(如下图),组合形式过多页面就会显得琐碎、杂乱,不利于阅读和使用。因为盒子的高度根据内容来定,故下图中没有体现高度这一维度的变化规律。
当我们完成上图规划后,需要做的便是根据实际内容往每个盒子里安排内容,做视觉与交互的落地了。
2、元素对齐与间距设定
栅格系统大的层面可以帮助设计者更好的进行版式设计与内容布局,而小的方面可以辅助设计师规范页面内各种元素的对齐与间距的设定。从用户体验角度来讲,这两者同等重要,从执行层面来讲,我们一般先做版式设计与布局,然后再填充内容、调整细节。
栅格系统辅助对齐的作用类似于各种设计软件中的参考线,它能让我们更直观的安排、调整内容的位置及对齐方式,可以使内容变得规律、有序,方便用户浏览阅读,帮助用户提高获取信息的效率。
栅格系统对于元素间间距设定的帮助是直观的,当我们定义了栅格原子单位为8时,这意味页面上各元素间距的变化也应遵循8n的规律,一致的变化规律让页面富有节奏感跟韵律感,在提高页面一致性的同时也减少了设计决策成本。我们知道,栅格系统中水槽与栏目的变化也遵循8n的变化规律,此处n为大于0的正整数,即n=1、2、3...;但是用于规范元素间距的8n,n可以是0.5、1.5这类包含二分之一8的情况,原因是实际工作中,我们面临的情况是复杂的,这样处理可以让间距的设定适应一些特殊的场景,从而使其更灵活普适。
注意事项
1、水槽宽度的设定
确定好内容模块比例后,我们会发现由于之前等分的缘故,此时水槽较宽,我们需要调整水槽宽度到一个合适的值。
水槽的宽度是8n,也就是水槽可以以8为基本单位去增加或减小。为了减少设计决策成本,我们会事先设定好一系列水槽宽度,并定义好每个宽度对应的使用场景,然后设计中根据每个场景使用对应数值就可以了。我定义了一组水槽的值是8、16、 24、32 、40,为了区分它们的使用场景我们依次为其命名为XS、SM、MD、LG、XL。根据实践经验,正常情况下,两个盒子间距(水槽)的值为24(MD)时,视觉上是最为舒适。
栅格化工具推荐(插件请在附件中下载)
Ps栅格系统工具
1、PS自带栅格系统设定:新建参考线版面(重点推荐)
Ps有个功能叫做“新建参考线版面”,打开这个面板后,在预设这里可以看到Ps已经预设了8列、12列、16列、24列的栅格系统,选择对应列数就可以看到页面上参考线的变化。预设中“装订线”的宽度即栅格系统中水槽的宽度。默认均为20px,我们可以根据之前讨论的8的倍数原则,将其手动更改为24;
如果预设的栅格系统无法满足我们工作需要,我们也可以自定义栅格系统,并能将栅格参数保存为预设,这样就可以重复利用自定义的栅格系统了;栅格系统还可以选择将其应用在当前画板或者所有画板,十分方便易用。由于是Ps自带的参考线,所以它可以通过快捷键灵活的控制显示或隐藏
2、利用Ps标注工具Assistor Ps 进行栅格系统的建立
Assistor Ps在之前主要是一款页面标注工具,但是随着蓝湖等自动标注工具的流行,这个小软件基本没人用了,但我发现它设置参考线的功能还是很强大的,可以媲美大名鼎鼎的guideguid(这款插件目前对Ps cc 2017及以上版本貌似已经不支持,软件本身安装也挺麻烦),所以就介绍给大家。(安装包在文末下载,Win&Mac,解压后跟常规装软件一样,正常安装就行)。但是这个插件由于很多数值都要自己算,实际上没有Ps自带的新建参考线面板的功能好用。算是一个工具的补充吧
Sketch栅格系统工具
1、Sketch自带栅格系统设定:Layout Settings
Sketch端利用sketch自带的栅格工具Layout Settings即可完成栅格系统的设置,由于sketch的栅格工具是自带的,与Ps类似,它也可以通过快捷键快速显示或隐藏,点击左下角“Make Default”还可以将自定义的栅格系统设置为默认的栅格系统,方便以后重复调用,但sketch貌似只能储存一组栅格系统的数值,而Ps可以储存多组。
2、Sketch栅格系统插件:BootstrapGrid-maste
BootstrapGrid是一个专门用于建立栅格系统的插件(插件在文末附件中下载),插件可以对栅格系统的基本数据做个性化的设定,可以对多个形状同时建立栅格系统,还可以通过快捷键快速调用。具体用法:先选中要建立栅格的画板或者画板里的形状(可以多选),然后:插件>Bootstrap Grid(Plugins -> Bootstrap Grid)
栅格系统参数设计
单个形状(画板)建立栅格系统动图演示
多个形状(画板)建立栅格系统动图演示
跨平台的web端栅格工具 http://grid.guide/
GridGuide 最大优点是可以针对一种栅格系统生成4组不同水槽宽度的栅格化方案,能比较直观的比较不同水槽宽度下各个栅格系统的视觉感受。使用方法:在右上角设置好页面宽度以及栏目数量,页面内就会自动生成可以下载为png图片的栅格。
QAQ(常见问题解答)
(1)当栅格系统中奇数不可避免的出现时,如何处理?
理想状态下,我们应该调整内容区域的大小,使其尽可能成为可以被8整除的尺寸,但实际应用中,有时会出现无法整除的情况。基于对盒子模型的理解,此时我们保持padding、margin的值不变,改变盒子的大小去适应奇数的页面(元素)即可,因为一致性跟效率才是栅格化要达成的首要目的,偶尔有一些不“完美”的尺寸是完全允许的,因为用户在实际使用页面时,并不能看到我们使用的栅格系统,也很难注意到那几像素的变化,他们能感受到的是页面整体呈现出来的节奏与韵律感,以及持续、一致的视觉语言带给他们的严谨、可靠的心里感受。
(2)栅格系统必须以8作为原子单位?使用其它数值是否可以
首先需要指出的是使用其它数值当然也可以,栅格系统只是手段,提升设计效率、减少沟通成本、提高页面一致性才是最终目的,所以如果你所在团队有其它栅格化习惯,且一直以来效果良好,那么继续使用它也是没问题的。但是对于设计新人来讲,如果能理解前人的经验,并能较好的运用,对于他们来讲,是会少一些弯路,更好的完成设计工作。
(3)栅格系统建立初期是否必须使栏目宽度与水槽宽相等,并等分内容区域?
建立栅格系统时并不是必须使栏目宽度与水槽宽相等,并等分内容区域。本篇文章介绍栅格系统时采用这种处理方式是为了让大家更好的理解栅格系统建立的原理与过程,事实上,栏目的宽度在实际应用中往往大于水槽宽度,我们通常会先计划好水槽的宽度、内容区域总宽度与栏目的数量,这时候栏目的宽度通过计算可得到,对于响应式页面,栏目的宽度可以是百分比而不是具体的数值(关于响应式的内容下期文章跟大家分享)。
转自UI中国-BYMD
<view class="gallery">
<view class="item" wx:for="{{images}}" wx:key="">
<image src="{{item}}" data-src="{{item}}" bindtap="previewImage" mode="aspectFill" />
<!-- 删除按钮 -->
<view class="delete" bindtap="delete" data-index="{{index}}">X</view>
</view>
<view class="item" bindtap="chooseImage">
<view class='addIcon'>+</view>
</view>
</view>
<button type="primary" bindtap="submit">提交</button>
————————————————
/* pages/index/index.wxss */
/*画廊*/
.gallery {
width:630rpx;
margin: 0 auto;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
/*每张图片所占容器*/
.item {
position: relative;
margin:10rpx 5rpx;
width: 200rpx;
height: 200rpx;
}
.item image{
width: 100%;
height: 100%;
}
/*add按钮*/
.item .addIcon{
position:relative;
width:200rpx;
height:200rpx;
text-align:center;
line-height:200rpx;
font-size:80rpx;
background: #f2f2f2;
color: #555;
}
/*删除按钮*/
.delete {
position:absolute;
right:0;
top:0;
/* background:#ccc; */
opacity:1;
height: 36rpx;
font-size:22rpx;
font-weight:700;
padding:0 8rpx 0 10rpx;
}
————————————————
var that;
Page({
data: {
images: [],
uploadedImages: [],
//imageWidth: getApp().screenWidth / 4 - 10
},
onLoad: function (options) {
that = this; var objectId = options.objectId; console.log(objectId);
},
chooseImage: function () {
// 选择图片
wx.chooseImage({
count: 3, // 默认9
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
// 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths;
console.log(tempFilePaths);
that.setData({
images: that.data.images.concat(tempFilePaths)
});
}
})
},
// 图片预览
previewImage: function (e) {
//console.log(this.data.images);
var current = e.target.dataset.src
wx.previewImage({
current: current,
urls: this.data.images
})
},
// submit: function () {
// // 提交图片,事先遍历图集数组
// that.data.images.forEach(function (tempFilePath) {
// new AV.File('file-name', {
// blob: {
// uri: tempFilePath,
// },
// }).save().then(
// // file => console.log(file.url())
// function (file) {
// // 先读取
// var uploadedImages = that.data.uploadedImages;
// uploadedImages.push(file.url());
// // 再写入
// that.setData({
// uploadedImages: uploadedImages
// }); console.log(uploadedImages);
// }
// ).catch(console.error);
// });
// wx.showToast({
// title: '评价成功', success: function () {
// wx.navigateBack();
// }
// });
// },
delete: function (e) {
var index = e.currentTarget.dataset.index; var images = that.data.images;
images.splice(index, 1);
that.setData({
images: images
});
}
})
————————————————
<button data-name="shareBtn" open-type="share" plain="true">转发</button>
添加plain=”true”后button的边框样式可自定义 ↓ ↓
button[plain]{ border:0 }
//转发
onShareAppMessage: function (options) {
var that = this;
// 设置菜单中的转发按钮触发转发事件时的转发内容
var shareObj = {
title: "这是一个标题!", // 默认是小程序的名称(可以写slogan等)
//path: '/page/index/index/user?id=123', // 默认是当前页面,必须是以‘/’开头的完整路径
imageUrl: '../../img/xiaochengxu-share.jpg', //自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径,支持PNG及JPG,不传入 imageUrl 则使用默认截图。显示图片长宽比是 5:4
success: function (res) {
// 转发成功之后的回调
if (res.errMsg == 'shareAppMessage:ok') {
}
},
fail: function (res) {
// 转发失败之后的回调
if (res.errMsg == 'shareAppMessage:fail cancel') {
// 用户取消转发
console.log("用户取消转发");
} else if (res.errMsg == 'shareAppMessage:fail') {
// 转发失败,其中 detail message 为详细失败信息
}
},
complete: function(){
// 转发结束之后的回调(转发成不成功都会执行)
},
};
// 来自页面内的按钮的转发
if(options.from == 'button') {
var eData = options.target.dataset;
console.log(eData.name); // shareBtn
// 此处可以修改 shareObj 中的内容
//shareObj.path = '/pages/btnname/btnname?btn_name=' + eData.name;
}
// 返回shareObj
return shareObj;
————————————————
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" circular="{{duration}}" current="{{swiperCurrent}}" bindchange="swiperChange" class="swiper">
<block wx:for="{{imgUrls}}" wx:key="unique">
<swiper-item>
<image src="{{item}}" class="img" bindtap="swipclick" />
</swiper-item>
</block>
</swiper>
————————————————
/* swiper {
height: 421.5rpx;
} */
swiper-item image {
width: 100%;
height: 100%;
}
.swiper-container{
width: 100%;
position: relative;
}
.swiper-container .swiper{
height: 300rpx;
}
.swiper-container .swiper .img{
width: 100%;
height: 100%;
}
————————————————
const app = getApp()
Page({
data: {
swiperCurrent: 0,
indicatorDots: true,
autoplay: true,
interval: 3000,//自动切换时间间隔
duration: 800,//滑动动画时长
circular: true,//是否采用衔接滑动
imgUrls: [
'../../img/index/1.jpeg',
'../../img/index/2.jpeg',
'../../img/index/3.jpeg'
]
},
//轮播图的切换事件
swiperChange: function (e) {
this.setData({
swiperCurrent: e.detail.current
})
//console.log(e.detail.current);
},
//点击指示点切换
chuangEvent: function (e) {
this.setData({
swiperCurrent: e.currentTarget.id
})
},
//点击图片触发事件
swipclick: function (e) {
console.log(this.data.swiperCurrent);
wx.switchTab({
url: this.data.links[this.data.swiperCurrent]
})
},
})
————————————————
前提:真机和PC端在同一个局域网内。
1、安装nodejs环境 (node -v 查看版本号)
2、在所在的项目下输入命令:npm install anywhere -g
3、直接输入命令:anywhere,这里浏览器自动打开所有项目的根目录,点击就可以看到,同一网段下,然后手机直接预览这个地址就可以
————————————————
蓝蓝设计的小编 http://www.lanlanwork.com