最近方正集团负债千亿,被银行申请破产重整的消息让众多设计师兴奋不已,心里暗自在想,那方正字库一万多款字体是不是就可以免费使用了?醒一醒,不太可能,身为设计工作者,尊重他人的设计和拥有版权意识是很重要的。
方正字库属于北京北大方正电子有限公司,而这个公司是方正集团的子公司。就算方正集团真的破产倒闭了,根据我国法律,方正字库何去何从也跟这两家公司的法人是否一致有关,如果一致,那么就可能被收购重组,如果不一致,那么就继续独立运营。关键是,无论是什么结果,方正字库里所有的字体都是有版权的,如果随意商用,就会导致侵权,乃至把整个公司都赔进去。
直接去网页搜索,便有数不清的方正字体侵权案例。大到电影和游戏的宣发,小到淘宝店铺的页面,只要你使用了方正字库的必须购买版权才可商用的字体,都有可能收到来自方正字库的律师函。那么该如何避免字体侵权呢?其实最好的方法就是使用免费可商用的字体,或者乖乖去买下字体的使用权。
一篇文章告诉你,该怎么判别字体是否侵权:
如果你实在要免费用方正字库的字体的话,那么就选择「方正黑体简体、方正书宋简体、方正仿宋简体、方正楷体简体」这四种字体吧,已经向方正字库授权服务官方求证过,这四款字体可以直接免费商用,不需要书面授权。
不过有那么多免费、适用度广、并且可以商用的字体,为什么要执着于方正呢?优设标题黑和优设好身体这两款字体,无论是做 banner、海报还是文字设计都很合适,还没拥有的设计师们快来下载。
优设标题黑:
优设好身体:
还有优设精心为大家挑选整理成的 2020 年免费可商用中文字体最全合集,链接给你们,正好需要的话,就快去下载使用。
最后,介绍两个可以查询和下载免费可商用字体的网站。
1. 字由网
网站链接:https://www.hellofont.cn/home
第一个是字由网,虽然需要下载客户端激活字体进行使用,不过截至今日,字由拥有 511 款免费可商用字体,对比一下乱用字体可能产生的侵权费用和烦恼,还是下载客户端性价比比较高。
网站及使用介绍:
2. 猫啃网
网站链接:http://novicehou.gz01.bdysite.com/
第二个是猫啃网,是免费开源可商用的公益字体网站,截至今日,网站上共有 155 款字体,可供设计师们选择和下载使用。
文章来源:优设
讲一个老东家的故事。一次产品迭代会上,老板在台上讲到打算重构 C 端产品框架,想重整标签栏的标签设定。可在讲到这一部分的时候卡壳了,迟迟说不出「标签栏」这个控件名,气氛有些尴尬。这时一名产品经理说道:底部导航栏!会议得以继续。
不全错,这么说也算能理解。控件在界面底部,能引导用户切换页面。但如果标签栏把导航栏的名字占了……那原本的导航栏应该叫什么呢?顶部标题栏?那导航栏里的内容控件又应该叫什么?左上角或者右上角的按钮?
接地气的名称让我们一听就懂,直到有一天你打算跳槽,你拿着自己的作品到下家面试,设计总监几个术语啪啪把你问得不知所云。这些「死控件」、「死栏目」在页面上不可或缺,在设计每一个页面时你以为对它们早已了如指掌,偏偏在关键时刻,它们却六亲不认了。
「我又不走形式主义,为什么一定要说专用名词呢?接地气的名称不是挺好吗,沟通。」很简单的道理,如果名词和概念都混淆不清,有没有花功夫在 UI 设计领域进行深度专研也就一目了然了,还何以谈论如何将它们运用自如呢?
这样的经历,让我产生了一个想法。是时候做一些知识内容沉淀与分享了,不能让更多的人走我踩过的坑。第一期我们便来讲一讲导航栏。
导航栏 Navigation Bar,也简称为 Navbar。一定会有不少刚入门的 UI 新人,在诸多的 Bar 控件中,难以区分它所指代的区域。
在 iOS 上,导航栏是指显示在应用程序顶部,位于状态栏下方的容器区域,层级应高于当前页面内容。
在安卓上,Google 公司在 Material Design 中也赋予了它同样的定义,但是却给了它另一个名称,顶部应用栏(Top App Bar)。
△ iOS与安卓的规范与命名区别
请务必要记住:导航栏是用于构架当前屏幕的内容,阐述当前屏幕的状态,并且起到连接父子级页面层次结构的作用。所以回到开头的小故事,为什么标签栏不能叫做底部导航,因为标签栏是构架了多个屏幕之间平级页面的内容切换,和「导航」的定义没有关系。
一个基本的导航栏容器一般承载的信息可能会有:标题、导航按钮、内容控件按钮、其他控件(比如搜索栏、分页标签或分页控件等),千万别忘了还有分割线。(比如微信的导航栏)
1. 导航栏标题
时间倒退回 2017 年以前,这时候的移动端规范下的导航栏还是循规蹈矩的,样式单一。但随着 iPhone X 等一系列全面屏手机相继问世后,移动设备在屏幕高度上有了进一步的扩展,界面设计在一屏内的发挥空间也随之增加。iOS11 发布后,大标题导航栏设计风格兴起,随后被引入平台规范。
于是现在 iOS 与 Material Design 在导航栏上也都定义了两种导航栏标题规范,常规标题与大标题。
常规标题是指在高度为 88px(iOS@2x下)的导航容器中,居中放置一个当前页面的标题。标题字号一般为 34px-38px(34px 为 iOS 标准规范,但实际项目中可以尽量在不小于 34px 标准的情况下根据设计需求确定)。
△ 常规导航不同标题字号的案例及视觉效果
大标题是将导航栏高增加到 192px(iOS@2x),保留高度为 88px 的导航容器来承载内容控件按钮,将标题下坠居左。iOS 的标准规范定义大标题的字号为 68px。但由于英文有大小写区分,在视觉上有一定的层次表现,而中文因为缺少一定的层次结构,并且相同字号的中文视觉大小大于英文,所以大多数时候我们在进行大标题设计时,会适当缩小,一般为 56px-64px 居多。
△ 大标题不同标题字号的案例及视觉效果
大标题导航栏的优点毋庸置疑,页面留白更多,呼吸感更强,大气现代、格调更高,因为页面标题巨大,能够帮助用户快速确认当前所处位置。采用统一的大标题,让页面布局风格快速统一。但缺点也显而易见,因为增加了导航栏的高度,导致屏幕利用率降低,一些通过广告变现或更加注重一屏内内容呈现的应用便中和了常规导航与大标题导航的优缺点,进行了风格改进。
△ 改进的大标题案例
那我们如何在常规标题和大标题之间抉择呢?这可不单单是设计风格的问题,还受产品定位与功能的影响。苹果的设计师在 Apple Music 中实验并验证了一条结论——在内容非常丰富、层级结构较深的产品当中,大标题能够帮用户快速确认自己的位置。
所以我理解的适合使用大标题风格的产品一定是:突出内容呈现而不是功能繁琐的;产品定位更偏向于现代或文艺艺术的;需要快速统一界面风格的。而层级结构需不需要很深,这并不一定,我反而觉得功能越单一、产品体量级越轻的应用,越适合大标题。
所以如此看来,国内使用大标题成功的案例就为数不多了,这可能与中文字体还有国内 app 产品功能都比较繁琐的原因有关,真正做到了使用大标题快速帮助用户确认自己位置,并且结合了产品特性与风格的,我认为人人都是产品经理的移动端在这方面做得非常棒。
2. 导航按钮及内容控件按钮
iOS 规定导航按钮位置仅能用于放置返回按钮,可以添加一个层级的面包屑,帮助用户有效地明确当前页面层级;Material Design 中,不仅可以放置返回按钮,还另有作用,菜单图标-用于打开导航抽屉或者关闭图标-关闭工具栏。
△ iOS与安卓的导航按钮区域区别
这一点与 iOS 的定义有着天壤之别,iOS 非常明确地赋予了工具栏的定义,并且将导航栏和工具栏(Toolbars)彻底地分离开,典型案例就是 Safari。
△ iOS明确地将导航栏与工具栏分离开
在内容控件上 iOS 与 Material Design 也大相径庭,Material Design 不去限制你的内容控件多少,因为它提供了溢出菜单,并可以根据屏宽的变化,自适应释出和收纳溢出菜单中的控件。
而 iOS 则规定我们,要给内容控件按钮足够多的空间,必要的时候,隐藏导航栏标题也未尝不可。
那么真实的项目中,我们往往为了快速落地,会存在一稿适配双平台的情况。这时候我们应该遵从哪一个平台的规范呢?答案是:许多大厂的做法已经向我们验证,规范不分家。
在 iOS 诸多的应用中溢出菜单早已普及,尽管这是 Material Design 提出的设计理念。
△ Material Design的溢出菜单也被运用在iOS端
虽然国内遵从 Material Design 进行 Android 应用设计的情况相对较少,但它提供的设计理念与方案却并不局限在安卓平台。
3. 分割线
分割线只是一种体现形式,我想要表达的是,别忘记区分导航栏与内容界面的视觉层级关系。Matetial Design 提醒我们,顶部应用栏可以与内容位于同一高度,但滚动时,请增加导航栏的视觉高度,让内容在其后方滚动。而 iOS 则默认采用了背景模糊的方式区分了导航栏与内容区域的层级关系。
△ 区分导航栏与内容区域的层级关系
缺少视觉分割会让用户分不清导航栏与内容界面,它们看起来会更像一个平级。对用户视觉区分内容主次其实是极不友好的。
4. 其他控件
关于其他控件,iOS 只在规范中提及到了分页控件。苹果设计师考虑到部分场景在当前页面中还存在信息层级结构划分,此时建议可以在导航栏中使用分段控件。
但国内的应用程序早已将导航栏容器的作用发挥到,基于导航栏层级始终高于内容区域的特性,我们通常可以将分段控件、分页标签、搜索栏等等用户可能随时使用的工具放在导航栏中。
△ 导航栏通常会承载的其他控件
导航栏是几乎每一个界面都必定存在的控件,正因为无法轻易删减,逃不掉就必须用好它,不然很容易沦为页面的减分项。
设计好导航栏不仅仅是视觉上的工作,表现的方式、承载的按钮与组件、滚屏时的组合操作还能给用户带来极大的体验增益。
文章来源:优设 作者:
1.文字滚动
<html>
<head>
<title>我的第一个页面</title>
</head>
<body>
<marquee behavior="scroll" direction="up" height="30" style="overflow:hidden;" scrollamount="1" width="300" onMouseOver="stop()" onMouseOut="start()">
雷电黄色预警!<br />
大雨黄色预警!<br />
</marquee>
</body>
</html>
direction:方向
up:上 down:下 left:左 right:右
scrollamount:滚动速度-----------------scroll:滚动 amount:数值
width:宽度 height:高度
onmouseover:当鼠标移上去
onmouseout:当鼠标离开
stop():停止
start():开始
behavior:
scroll 循环滚动
alternate 来回滚动
slide 滚动一次停止
一.有关于内置对象的作用域
主要说明2个对象,request,session
1、request 对象
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。
request只在2个页面之间传递,每一次新的请求都会新建一个request对象,也就是说可能会request对象不一致导致空指针异常。
2、session 对象
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
session对象在整个会话只有一个,也就是说session对象的数据会一直保留直到主动进行数据更改。
二.表单提交
在index.jsp中使用form进行数据的提交,action的目标是check.jsp,method是post
三.验证跳转
当form提交信息后交给check.jsp验证,使用getParameter来得到form的信息,并使用setAttribute保存。在check.jsp中判断账号密码是否正确后,使用
<jsp:forward page=".jsp"></jsp:forward>
1
进行跳转,.jsp是想要跳转的页面路径。
四.详细代码
index.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陆</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="check.jsp" method="post">
请输入用户名:
<input type = "text" name = "username"><br/>
请输入密码:
<input type = "password" name = "passwd"><br/>
<input type="submit" name="submit" value="登录">
</form>
</body>
</html>
check.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>验证</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getParameter("username");
String passwd = (String)request.getParameter("passwd");
request.setAttribute("username", username);
request.setAttribute("passwd", passwd);
if(username.equals("admin")&&passwd.equals("123")){
%>
<jsp:forward page="succeed.jsp"></jsp:forward>
<%}else{ %>
<jsp:forward page="failed.jsp"></jsp:forward>
<%} %>
</body>
</html>
succeed.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陆成功</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getAttribute("username");
String passwd = (String)request.getAttribute("passwd");
%>
<%=username %>登陆成功
</body>
</html>
failed.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陆失败</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getAttribute("username");
String passwd = (String)request.getAttribute("passwd");
%>
<%=username %>登陆失败
</body>
</html>
五.注意事项
在jsp中使用form提交表单不能直接进行跳转,否则操作不慎就容易出现空指针异常,建议交由单独的跳转页面处理
下面这段代码是实现简单的导航效果:
在这里插入代码片<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin:0px;
padding:0px;
list-style:none;
}
.nav{
width:700px;
margin:100px auto;
}
.nav ul li{
float:left;
margin-right:5px;
}
.nav ul li a{
width:100px;
height:30px;
color:#fff;
display:block;
line-height:30px;
margin-right:5px;
text-decoration:none;
background:red;
text-align:center;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.nav ul li a:hover{
background:yellow;
color:blue;
text-decoration:underline;
}
</style>
</head>
<body>
<div class="nav">
<ul class="clearfix">
<li><a href="#">导航</a></li>
<li><a href="#">导航</a></li>
<li><a href="#">导航</a></li>
<li><a href="#">导航</a></li>
<li><a href="#">导航</a></li>
</ul>
</div>
</body>
</html>
实现效果如图:
容易犯错的地方:刚开始我把display:block;属性写在最前面,结果一直出不来,后来发现display属性应该放在height和width属性后面
我还学到一个知识点:关于父元素塌陷问题:
在文档流中,父元素的高度默认是被子元素撑开的,也就是说父元素多高,子元素就多高
但是为子元素设置浮动以后,子元素就会完全脱离文档流,此时将会导致子元素无法撑起父元素的高度,导致父元素的高度塌陷
由于父元素的高速塌陷了,则父元素下所有的元素都会向上移动,这样会导致页面布局混乱
所以我们在开发中一定要避免出席那高度塌陷的问题,这时候我们可以将父元素的高度写死,这样可避免塌陷的问题出现,但是一当高度写死,父元素的高度将不能自动适应子元素的高度,所以这种方式是不推荐使用的
1
解决的方案:
根据W3C标准,在页面中元素有一个隐含的属性叫做Block Formatting Context
方案一:*(设置zoom为1和overflow为hidden)
当开启元素的BFC后,元素会有以下特性:
父元素的垂直外边距不会和子元素重叠
开启BFC的元素不会被浮动元素所覆盖
开启BFC的元素可以包含浮动的子元素
那如何开启元素的BFC呢?
设置元素浮动
设置元素的绝对定位
设置元素为inline-block(但是设置inline-block可以解决问题,但是会导致宽度丢失,所以不推荐使用这种方式)
将元素的overflow设置为一个非visible的值(推荐方式:将overflow:hidden这个是副作用最小的开启BFC方式,所以可以这么说,以后若是再塌陷,就给父元素加上overflow:hidden属性)
但需要注意的是:
在IE6以及以下的浏览器中并不支持BFC,所以使用这种方式并不能兼容IE6,在IE6中虽然没有BFC,但有另一个隐藏属性叫做hasLayout该属性作用和和BFC类似。但在IE6浏览器可以通过开hasLayout来解决问题
开启方式很多,我们可以直接用一种副作用最小的直接将元素的zoom设置为1,比如父元素是box1,我们可以在父元素中加上zoom:1;
在这里解释一下zoom表示放大的意思,后边跟着一个数值,写几就可以将元素放大几倍,所以zoom:1表示不放大元素,但是可以通过该样式可以开启hasLayout.
但需要注意的是zoom属性放IE6可以,别的浏览器比如Chrome就不行
****所以重头戏来了:若我们想要兼容所有浏览器?
1.引入
三种引用方式
第一种 npm安装
项目根目录命令行执行
npm install uni-simple-router
1
第二种 插件市场(使用HBuilderX导入插件)
第三种 ZIP下载 解压
2.项目中引入
import Vue from 'vue'
import {RouterMount} from 'uni-simple-router';
import Router from './router'
Vue.use(Router)
//...后续代码
引入之后就开始我们的正式使用。
第一步先在项目的根目录下创建一个router文件夹。
格式为:
router
|---modules
|---index.js
|---index.js
router中的modules文件夹是用来放路由表模板的。modules中的index.js内容为
const files = require.context('.', false, /.js$/)
const modules = []
files.keys().forEach(key => {
if (key === './index.js') return
const item = files(key).default
modules.push(...item)
})
export default modules
这个文件用来把同目录下的js文件读取并整合所有路由。
在这里创建的js文件代码示例:
const home = [
{
//注意:path必须跟pages.json中的地址对应,最前面别忘了加'/'哦
path: '/pages/home/index',
aliasPath:'/', //对于h5端你必须在首页加上aliasPath并设置为/
name: 'index',
meta: {
title: '首页',
},
},
{
path: '/pages/home/list',
name: 'list',
meta: {
title: '列表',
},
},
]
export default home
第二步配置router下的index.js
import modules from './modules'
import Vue from 'vue'
//这里仅示范npm安装方式的引入,其它方式引入请看最上面【安装】部分
import Router from 'uni-simple-router'
Vue.use(Router)
//初始化
const router = new Router({
routes: [...modules]//路由表
});
//全局路由前置守卫
router.beforeEach((to, from, next) => {
next()
})
// 全局路由后置守卫
router.afterEach((to, from) => {
})
export default router;
第三步 就是配置main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import { RouterMount } from 'uni-simple-router'
App.mpType = 'app'
const app = new Vue({
...App
})
//v1.3.5起 H5端 你应该去除原有的app.$mount();使用路由自带的渲染方式
// #ifdef H5
RouterMount(app,'#app');
// #endif
// #ifndef H5
app.$mount(); //为了兼容小程序及app端必须这样写才有效果
// #endif
这样你的路由就配置好了。
如果不想繁琐的配置modules下的文件,可以用webpack自动构建路由表
安装
npm install uni-read-pages
1
配置 vue.config.js (可能需要手动创建)
const TransformPages = require('uni-read-pages')
const tfPages = new TransformPages({
//如果你需要获取更多参数,那么请配置参数!
includes:['path','name','meta']
})
module.exports = {
configureWebpack: {
plugins: [
new tfPages.webpack.DefinePlugin({
ROUTES: JSON.stringify(tfPages.routes)
})
]
}
}
然后去pages.json里面更改配置,加入所需要的内容
最后配置路由表
import Vue from 'vue'
//这里仅示范npm安装方式的引入,其它方式引入请看最上面【安装】部分
import Router from 'uni-simple-router'
Vue.use(Router)
//初始化
const router = new Router({
routes:ROUTES //路由表
});
//全局路由前置守卫
router.beforeEach((to, from, next) => {
next()
})
// 全局路由后置守卫
router.afterEach((to, from) => {
})
export default router;
所谓闭包就是说,闭包是指有权访问另外一个函数作用域中的变量的函数.可以理解为(能够读取其他函数内部变量的函数)
闭包的三大特点为(既是优点,也是缺点):
1,函数作用域空间不会被销毁
优点是:空间中的内容,永远存在
缺点是:占用大量的内存空间
2,可以从外部访问函数内部的变量
优点是:使用变量数据方便
缺点是:容易泄露数据信息
3,保护私有作用域变量
优点是:确保私有作用域变量一直存在
缺点是:占用内存空间 闭包的最大问题是:有可能造成占用大量的内存空间,降低程序的执行效率,甚至有可能造成数据溢出或者是数据泄露 因为为了保护数据的安全性,特殊情况下,才会使用闭包举例来说:
// 记数器:
//全局变量 全局变量降低函数的独立性
1
// var count = 0;
// function add(){
// return count++;
// }
// console.log(add());
// console.log(add());
// console.log(add());
//局部变量 函数执行外 局部变量销毁
1
// function add(){
// var count = 0;
// return count++;
// }
// console.log(add());
// console.log(add());
// console.log(add());
//plus定义在add的内部,可以访问add局部变量count
//f为一个全局变量,通过赋值后,成为add的返回值,也就是plus方法
//访问到了add中的局部变量count
//所以count虽然是局部变量,但不允许被销毁,plus就是闭包
1
2
3
4
// function add(){
// var count = 0;
// function plus(){
// return count++;
// }
// return plus;
// }
//
// var f = add();
//
// console.log(f());
// console.log(f());
// console.log(f());
//变身
1
// function add(){
// var count = 0;
// return function(){
// return count++;
// }
// }
//
// var f = add();
//
// console.log(f());
// console.log(f());
// console.log(f());
//继续变身
1
// var f = (function (){
// var count = 0;
// return function(){
// return count++;
// }
// }());
//
// console.log(f());
// console.log(f());
// console.log(f());
//JS中,没有块作用域,但是在闭包的写法里,可以体现出来。
function outerFunc(){
var outVar = 10;
var innerF = function (){
var innerVar = 20;//该变量虽然隶属于outerFunc内部,但是它的作用域范围只在innerF对应的函数体内,属于块级作用域
}
alert(innerVar);
return innerF;
}
闭包的作用:
正常函数执行完毕后,里面声明的变量被垃圾回收处理掉,但是闭包可以让作用域里的 变量,在函数执行完之后依旧保持没有被垃圾回收处理掉
可以读取函数内部的变量
让这些变量的值始终保持在内存中。
增加块级作用域
总结:
1、 闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。
2、 闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
3、不必纠结到底怎样才算闭包,其实你写的每一个函数都算作闭包,即使是全局函数,你访问函数外部的全局变量时,就是闭包的体现。
————————————————
版权声明:本文为CSDN博主「澈野」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fie_ld/article/details/104595753
Echarts饼图之数据展示
1、组件简介
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
官网链接:Echarts官网
W3C教程:W3C–Echarts教程
2、前端代码实现
首先,下载库,并引入到项目文件;
话不多说,直接上代码。
/* 封装的组件 HTML代码
<div class="echart-wrap-box">
<div class="echart-content"></div>
</div>
*/
let echarts = require("echarts/echarts.min");
defaults: {
option: {
echartsObj: {},
tooltip: {//提示框浮层内容。
trigger: 'item',//数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
formatter: "{b} : {c}万人"//提示框浮层内容格式器,{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
//如果系列没有设置颜色,则会依次循环从默认列表中取颜色作为系列颜色。
color: ["#369DFD", "#32C8CA", "#49C872", "#F6CE36", "#EE607A", "#935CE3", "#3436C7", "#3E4D86"],
legend: {//图例组件。
orient: 'vertical',//图例列表的布局朝向:垂直的
x: '80%',//图例组件离容器左侧的距离。
y: '60%',//图例组件离容器上侧的距离。
// width: 100,
textStyle: {},//图例文字的样式
// left: 'right',//图例组件离容器左侧的距离。
top: 'center',//图例组件离容器上侧的距离。
data: [],//右侧图例小组件信息数据
},
series: [{//饼图信息
name: '',
type: 'pie',//饼状图
radius: 140,//饼图的半径。
center: ['50%', '50%'],
minAngle: 5, //最小的扇区角度(0 ~ 360),用于防止某个值过小导致扇区太小影响交互
label: {//展示文本设置
normal: {
show: true,
formatter: "{b} : {c}万人",//视觉引导线内容格式器,{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
emphasis: { //文本样式
show: true, //展示
textStyle: { //文本样式
fontSize: '16',
fontWeight: '600',
}
}
},
labelLine: {//视觉引导线设置
normal: {
show: true
}
},
data: [],//饼状图信息数据,value(数量)和 name为默认数据;
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}],
},
onInit(event) {
vm = event.vmodel;
let data;//假设这里通过ajax获取到了需要展示的数据;
if (data.length == 0) {
return
}
data = data.sort((a, b) => { return b.number - a.number });//数据根据数量number从大到小排序
if (data.length > 7) {//从大到小的第八个新增粉丝数量的年份 开始统一归为 其他年份新增粉丝数量
let arr = data.slice(7);
let num = 0, rate = 0;
for (let i = 0; i < arr.length; i++) {//第七个之后累数量和比率
num += Number(arr[i].number);
rate += Number(arr[i].rate);
};
let objOtherYear = {
value: num,
name: '其他年份__nana新增粉丝数量',
rate: rate
};
let arr2 = data.slice(0, 7);
arr2.push(objOtherYear);
data = arr2;
data = data.sort((a, b) => { return b.number - a.number });//数据根据数量number从大到小排序
}
this.option.series[0].data = [];
this.option.legend.data = [];
for (let i = 0; i < data.length; i++) {
let seriesData = {
value: 0,
name: '',
rate: ''
};
seriesData.value = data[i].number;
seriesData.name = data[i].year;
seriesData.rate = data[i].rate;
this.option.series[0].data.push(seriesData);//给饼图赋值数据
let legendData = {
name: '',
icon: 'circle',//强制设置图形为:圆形
textStyle: {
color: '#000'
}
}
legendData.name = data[i].year;
this.option.legend.data.push(legendData);//给图例组件赋值数据
}
},
callFun: avalon.noop,//点击饼状图后的回调
isClickEchartsOUt: avalon.noop,//是否为饼图外的点击,父组件进行判断后传过来
onReady(event) {
this.echartsObj = echarts.init(event.target.children[0]);//初始化
this.echartsObj.setOption(this.option);
$(window).resize(() => {
this.echartsObj.resize();
});
let dataIndex;//保存选中扇区的序号
let _this = this;
this.$watch('isClickEchartsOUt', () => {
if (this.isClickEchartsOUt) {//如果不是饼状图扇区的点击,则取消选中;
_this.echartsObj.dispatchAction({
type: 'pieUnSelect',//取消选中指定的饼图扇形。
// 可选,系列 index,可以是一个数组指定多个系列
seriesIndex: 0,
// 可选,数据的 index
dataIndex: dataIndex,
})
}
});
// 处理点击饼图内部的事件
this.echartsObj.on('click', function (params) {
if (params.dataIndex != dataIndex) {//如果不是前一次选中的扇区,则取消选中
_this.echartsObj.dispatchAction({
type: 'pieUnSelect',//取消选中指定的饼图扇形。
// 可选,系列 index,可以是一个数组指定多个系列
seriesIndex: 0,
// 可选,数据的 index
dataIndex: dataIndex,
})
}
dataIndex = params.dataIndex;
_this.echartsObj.dispatchAction({
type: 'pieSelect',//选中指定的饼图扇形。
// 可选,系列 index,可以是一个数组指定多个系列
seriesIndex: 0,
// 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据
dataIndex: dataIndex,
})
vm.callFun(params);//回调,传点击获取到的数据给父组件
});
},
onDispose() {}
}
HTML 样式
通过使用 HTML4.0,所有格式化代码均可移出 HTML 文档,然后移入一个独立的样式表。
先来看一个例子,代码如下:
<head>
<style type="text/css">
h1 {color: red}
p {color: blue}
</style>
</head>
<body>
<h1>header 1</h1>
<p>A paragraph.</p>
</body>
页面上显示为:
header 1
A paragraph.
当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化。有以下三种方式来插入样式表:
外部样式表 link
当样式需要被应用到很多页面的时候,外部样式表将是理想的选择。使用外部样式表,你就可以通过更改一个文件来改变整个站点的外观。
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
link : 定义资源引用
rel : 告诉浏览器引用的是一个样式表文件
type : 文件类型
href : 文件地址
内部样式表
当单个文件需要特别样式时,就可以使用内部样式表。你可以在 head 部分通过 <style> 标签定义内部样式表。
<head>
<style type="text/css">
body {background-color: red}
p {margin-left: 20px}
</style>
</head>
style : 定义样式定义
新建一个前端学习qun438905713,在群里大多数都是零基础学习者,大家相互帮助,相互解答,并且还准备很多学习资料,欢迎零基础的小伙伴来一起交流。
内联样式
当特殊的样式需要应用到个别元素时,就可以使用内联样式。 使用内联样式的方法是在相关的标签中使用样式属性。样式属性可以包含任何 CSS 属性。以下实例显示出如何改变段落的颜色和左外边距。
<p style="color: red; margin-left: 20px">
This is a paragraph
</p>
优先级说明
(外部样式)External style sheet < (内部样式)Internal style sheet < (内联样式)In
1.下列方法表示调用外部样式表的是?
A<style type="text/css">h1 {color: red }</style>
B<link rel="stylesheet" type="text/css" href="css/style.css">
C<p style="color: red; margin-left: 20px">style</p>
2.下面三种方法可以起到改变文档样式的是?
A<style type="text/css">h1 {color: red }</style>
B<link rel="stylesheet" type="text/css" href="css/style.css">
C<p style="color: red; margin-left: 20px"></p>
D以上三种都可以
————————————————
版权声明:本文为CSDN博主「html前端基础入门教程」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/htkms87/article/details/104600003
在我们的日常开发工作中,文本溢出截断省略是很常见的一种需考虑的业务场景细节。看上去 “稀松平常” ,但在实现上却有不同的区分,是单行截断还是多行截断?多行的截断判断是基于行数还是基于高度?这些问题之下,都有哪些实现方案?他们之间的差异性和场景适应性又是如何?
一般来说,在做这样文字截断效果时我们更多是希望:
兼容性好,对各大主流浏览器有好的支持
响应式截断,根据不同宽度做出调整
文本超出范围才显示省略号,否则不显示省略号
省略号位置显示刚好
基于上述的准则,下面我们通过编码实践,给出一些答案。
单行文本溢出省略
核心 CSS 语句
overflow: hidden;(文字长度超出限定宽度,则隐藏超出的内容)
white-space: nowrap;(设置文字在一行显示,不能换行)
text-overflow: ellipsis;(规定当文本溢出时,显示省略符号来代表被修剪的文本)
优点
兼容性好,对各大主流浏览器有好的支持
响应式截断,根据不同宽度做出调整
文本溢出范围才显示省略号,否则不显示省略号
省略号位置显示刚好
短板
只支持单行文本截断,并不支持多行
适用场景
适用于单行文本溢出显示省略号的情况
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
.demo {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
多行文本溢出省略(-webkit-line-clamp)
核心 CSS 语句
overflow: hidden;(文本溢出限定的宽度就隐藏内容)
-webkit-line-clamp: 2;(用来限制在一个块元素显示的文本的行数, 2 表示最多显示 2 行。 为了实现该效果,它需要组合其他的WebKit属性)
display: -webkit-box;(和 -webkit-line-clamp: 2;结合使用,将对象作为弹性伸缩盒子模型显示 )
-webkit-box-orient: vertical;(和 -webkit-line-clamp: 2;结合使用 ,设置或检索伸缩盒对象的子元素的排列方式 )
text-overflow: ellipsis;(多行文本的情况下,用省略号“…”隐藏溢出范围的文本)
优点
响应式截断,根据不同宽度做出调整
文本溢出范围才显示省略号,否则不显示省略号
浏览器原生实现,所以省略号位置显示刚好
短板
兼容性一般: -webkit-line-clamp 属性只有 WebKit 内核的浏览器才支持
适用场景
多适用于移动端页面,因为移动设备浏览器更多是基于 WebKit 内核
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
.demo {
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
多行文本溢出省略(伪元素 + 定位)
核心 CSS 语句
position: relative; (为伪元素绝对定位)
overflow: hidden; (文本溢出限定的宽度就隐藏内容)
position: absolute;(给省略号绝对定位)
line-height: 18px; (结合元素高度,高度固定的情况下,设定行高, 控制显示行数)
height: 36px; (设定当前元素高度)
::after {} (设置省略号样式)
word-break: break-all; (如果文本中有英文,可以使一个单词能够在换行时进行拆分)
优点
兼容性好,对各大主流浏览器有好的支持
响应式截断,根据不同宽度做出调整
短板
无法识别文字的长短,无论文本是否溢出范围,一直显示省略号
省略号显示可能不会刚刚好,有时会遮住一半文字,跟文字没有贴合的很紧密
适用场景
文字内容较多,确定文字内容一定会超过容器的
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
1
2
3
.demo {
position: relative;
line-height: 18px;
height: 36px;
overflow: hidden;
word-break: break-all;
}
.demo::after {
content:"...";
font-weight:bold;
position:absolute;
bottom:0;
right:0;
padding:0 20px 1px 45px;
/ 为了展示效果更好 /
background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}
多行文本溢出省略(Float)
核心 CSS 语句
line-height: 20px;(结合元素高度,高度固定的情况下,设定行高, 控制显示行数)
overflow: hidden;(文本溢出限定的宽度就隐藏内容)
float: right/left;(利用元素浮动的特性实现)
position: relative;(根据自身位置移动省略号位置, 实现文本溢出显示省略号效果)
word-break: break-all;(如果文本中有英文,可以使一个单词能够在换行时进行拆分)
优点
兼容性好,对各大主流浏览器有好的支持
响应式截断,根据不同宽度做出调整
文本溢出范围才显示省略号,否则不显示省略号
短板
省略号显示可能不会刚刚好,有时会遮住一半文字,跟文字没有贴合的很紧密
适用场景
文字内容较多,确定文字内容一定会超过容器的
Demo
<div class="demo">
<div class="text">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
</div>
.demo {
height: 40px;
line-height: 20px;
overflow: hidden;
}
.demo .text {
float: right;
margin-left: -5px;
width: 100%;
word-break: break-all;
}
.demo::before {
float: left;
width: 5px;
content: "";
height: 40px;
}
.demo::after {
float: right;
content: "...";
height: 20px;
line-height: 20px;
padding-right: 5px;
text-align: right;
width: 3em;
margin-left: -3em;
position: relative;
left: 100%;
top: -20px;
padding-right: 5px;
/ 为了展示效果更好 /
background: -webkit-gradient(
linear,
left top,
right top,
from(rgba(255, 255, 255, 0)),
to(white),
color-stop(50%, white)
);
background: -moz-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: -o-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: -ms-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
}
蓝蓝设计的小编 http://www.lanlanwork.com