首页

px、em、rem、%、vw、vh、vm这些单位的区别

seo达人

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

1.背景介绍


我们为什么要选择合适的网页设计单位


随着Web的发展,对新的解决方案的需求也会继续增大,对网页的要求更高。


网页设计单位是涉及到我们布局的效果,使用不同的单位会对最终的demo,会有影响。


现在都是要求响应式设计,需要适配各种设备,电脑,手机,平板。如果单位不合适,可能在这个设备显示良好,那个设备就会打乱布局。


所以需要我们选择合适的单位来进行开发,设计。
2.知识剖析


1、px


px就是pixel的缩写,意为像素。px就是设备或者图片最小的一个点,比如常常听到的电脑像素是1024x768的,表示的是水平方向是1024个像素点,垂直方向是768个像素点。


是我们网页设计常用的单位,也是基本单位。通过px可以设置固定的布局或者元素大小,缺点是没有弹性。


特点是1. em的值并不是固定的; 2. em会继承父级元素的字体大小。




2、em


参考物是父元素的font-size,具有继承的特点。如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值。
特点是1. em的值并不是固定的; 2. em会继承父级元素的字体大小。
3、rem


rem是相对于根元素html,这样就意味着,我们只需要在根元素确定一个参考值,可以设计HTML为大小为10px,到时设置1.2rem就是12px.以此类推。


优点是,只需要设置根目录的大小就可以把整个页面的成比例的调好。


4、%


一般来说就是相对于父元素的,


1、对于普通定位元素就是我们理解的父元素 2、对于position: absolute;的元素是相对于已定位的父元素 3、对于position: fixed;的元素是相对于ViewPort(可视窗口),
5、vw


css3新单位,view width的简写,是指可视窗口的宽度。假如宽度是1200px的话。那10vw就是120px


举个例子:浏览器宽度1200px, 1 vw = 1200px/100 = 12 px。


6、vh


css3新单位,view height的简写,是指可视窗口的高度。假如高度是1200px的话。那10vh就是120px


举个例子:浏览器高度900px, 1 vh = 900px/100 = 9 px。


7、vm


css3新单位,相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vm 举个例子:浏览器高度900px,宽度1200px,取最小的浏览器高度,1 vm = 900px/100 = 9 px。


兼容性太差 ,现在基本上没人用,我试了一下Chrome就用不了。


3.常见问题


假如使用em来设置文字大小要注意什么?


4.解决方案


注意父元素的字体大小,因为em是根据父元素的大小来设置的。比如同样是1.5em,要是父元素是20,那1.5em就是30px.要是父元素是30px,1.5em就是45px.


特别是在多重div嵌套里面更要注意。


5.扩展思考


css还有哪些长度单位?


in:寸


cm:厘米


mm:毫米


t:point,大约1/72寸


pc:pica,大约6pt,1/6寸


6.更多问题
1.pc pt ch一般用在什么场景?
这些我们网页设计基本上用不到,在排版上会有用处。


2.如何使 1rem=10px
在设置HTML{font-size:62.5%;}即可


3.如果父元素没有指定高度,那么子元素的百分比的高度是多少?
会按照子元素的实际高度,设置百分比已经没有效果了。
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务


Java跨域问题的解决方案及axios的跨域请求方法封装

seo达人

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

原因

出于安全考虑,浏览器有一个同源策略。浏览器中,异步请求的地址与目标地址的协议、域名和端口号三者与当前有不同,就属于跨域请求。

限制跨域访问是浏览器的一个安全策略,因为如果没有这个策略,那么就有被跨站攻击的危险。比如,攻击者在自己的网站A放置一个表单,这个表单发起DELETE请求,删除某个用户在B网站上的个人资料。如果没有同源策略保护,那么在同一个浏览器内,如果用户已经登录了B网站,这个删除的请求就会被接受,导致在用户不知情的情况下自己在B网站中的资料被删除。

解决方式

浏览器的同源策略提升了安全性,但是给需要在不同域名下开发的开发者带来了跨域问题。

解决跨域的问题主要有: 
jsonp和cors。jsonp是利用 script 标签可以跨域加载的特性而创造出来的一种非正式的跨域解决方案。在实际开发中,推荐使用cors,即在服务端返回时加入允许跨域的请求头,允许指定域名的跨域访问。

千万要小心!这种直接加 * 号的做法是相当危险的,千万别这么做!

response.addHeader("Access-Control-Allow-Origin", "*"); 
  • 1

正确的做法:

1. 创建一个 Filter 类

/**
 * 使用Filter的方式解决跨域问题
 */ public class CorsFilter implements Filter { private static final List<String> ALLOW_ORIGINS = Config.getListString("allowOrigins", ","); private static final String REQUEST_OPTIONS = "OPTIONS"; @Override public void init(FilterConfig filterConfig) throws ServletException {
    } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String orgHeader = request.getHeader(HttpHeaders.ORIGIN); if (orgHeader != null && ALLOW_ORIGINS.contains(orgHeader)) { // 允许的跨域的域名 response.addHeader("Access-Control-Allow-Origin", orgHeader); // 允许携带 cookies 等认证信息 response.addHeader("Access-Control-Allow-Credentials", "true"); // 允许跨域的方法 response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT, HEAD"); // 允许跨域请求携带的请求头 response.addHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With"); // 返回结果可以用于缓存的最长时间,单位是秒。-1表示禁用 response.addHeader("Access-Control-Max-Age", "3600"); // 跨域预检请求,直接返回 if (REQUEST_OPTIONS.equalsIgnoreCase(request.getMethod())) { return;
            }
        }
        filterChain.doFilter(request, response);
    } @Override public void destroy() {

    }
} 
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2. 在 web.xml 的最前面注册这个 Filter

<filter> <filter-name>corsfilter</filter-name> <filter-class>com.bj58.crm.plus.filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>corsfilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

前端使用 axios 可以先进行封装

http-util.js

let axios = require("axios"); let qs = require("qs");
axios.defaults.withCredentials = true;
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; function post(url, param) { return axios.post(url, qs.stringify(param))
} function get(url, param) { axios.get(url, {params: param})
}

export default {
  get,
  post
};

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




echarts 实现关系图表

seo达人


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


1.效果如上,官方示例简化

2.force1.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="ECharts"> <meta name="author" content="kener.linfeng@gmail.com"> <title>ECharts · Example</title> <script src="./js/echarts.js"></script> </head> <body> <div id="main" class="main" style="width: 800px;height: 800px"></div> <script src="./echartsExample.js"></script> </body> </html> 
3.echartsExample.js
var myChart; var domMain = document.getElementById('main'); function requireCallback (ec) { echarts = ec; if (myChart && myChart.dispose) { myChart.dispose();
    } myChart = echarts.init(domMain); window.onresize = myChart.resize; myChart.setOption(option, true); window.onresize = myChart.resize;
} var option = { title : { text: '人物关系:乔布斯', subtext: '数据来自人立方', x:'right', y:'bottom'  }, tooltip : { trigger: 'item', formatter: '{a} : {b}'  }, toolbox: { show : true, feature : { restore : {show: true}, magicType: {show: true, type: ['force', 'chord']}, saveAsImage : {show: true}
        }
    }, legend: { x: 'left', data:['家人','朋友']
    }, series : [
        { type:'force', name : "人物关系", ribbonType: false, categories : [
                { name: '人物'  },
                { name: '家人'  },
                { name:'朋友'  }
            ], itemStyle: { normal: { label: { show: true, textStyle: { color: '#333'  }
                    }, nodeStyle : { brushType : 'both', borderColor : 'rgba(255,215,0,0.4)', borderWidth : 1  }, linkStyle: { type: 'curve'  }
                }, emphasis: { label: { show: false  // textStyle: null      // 默认使用全局文本样式,详见TEXTSTYLE  }, nodeStyle : { //r: 30  }, linkStyle : {}
                }
            }, useWorker: false, minRadius : 15, maxRadius : 25, gravity: 1.1, scaling: 1.1, roam: 'move', nodes:[
                {category:0, name: '乔布斯', value : 10, label: '乔布斯\n(主要)'},
                {category:1, name: '丽萨-乔布斯',value : 2},
                {category:1, name: '保罗-乔布斯',value : 3},
                {category:1, name: '克拉拉-乔布斯',value : 3},
                {category:1, name: '劳伦-鲍威尔',value : 7},
                {category:2, name: '史蒂夫-沃兹尼艾克',value : 5},
                {category:2, name: '奥巴马',value : 8},
                {category:2, name: '比尔-盖茨',value : 9},
                {category:2, name: '乔纳森-艾夫',value : 4},
                {category:2, name: '蒂姆-库克',value : 4},
                {category:2, name: '龙-韦恩',value : 1},
            ], links : [
                {source : '丽萨-乔布斯', target : '乔布斯', weight : 1, name: '女儿'},
                {source : '保罗-乔布斯', target : '乔布斯', weight : 2, name: '父亲'},
                {source : '克拉拉-乔布斯', target : '乔布斯', weight : 1, name: '母亲'},
                {source : '劳伦-鲍威尔', target : '乔布斯', weight : 2},
                {source : '史蒂夫-沃兹尼艾克', target : '乔布斯', weight : 3, name: '合伙人'},
                {source : '奥巴马', target : '乔布斯', weight : 1},
                {source : '比尔-盖茨', target : '乔布斯', weight : 6, name: '竞争对手'},
                {source : '乔纳森-艾夫', target : '乔布斯', weight : 1, name: '爱将'},
                {source : '蒂姆-库克', target : '乔布斯', weight : 1},
                {source : '龙-韦恩', target : '乔布斯', weight : 1},
                {source : '克拉拉-乔布斯', target : '保罗-乔布斯', weight : 1},
                {source : '奥巴马', target : '保罗-乔布斯', weight : 1},
                {source : '奥巴马', target : '克拉拉-乔布斯', weight : 1},
                {source : '奥巴马', target : '劳伦-鲍威尔', weight : 1},
                {source : '奥巴马', target : '史蒂夫-沃兹尼艾克', weight : 1},
                {source : '比尔-盖茨', target : '奥巴马', weight : 6},
                {source : '比尔-盖茨', target : '克拉拉-乔布斯', weight : 1},
                {source : '蒂姆-库克', target : '奥巴马', weight : 1}
            ]
        }
    ]
}; var echarts; require.config({ paths: { echarts: './js'  }
}); launchExample(); var isExampleLaunched; function launchExample() { if (isExampleLaunched) { return;
    } // 按需加载  isExampleLaunched = 1; require(
        [ 'echarts', 'echarts/chart/force', 'echarts/chart/chord',
        ], requireCallback  );
}

4.目录文件结构

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


ionic3学习之登录页

seo达人

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

准备工作

部分源码说明:

constructor(public modalCtrl: ModalController) {
}
  • 1
  • 2

我们使用的是:ModalController 不是 NavController

这两者的区别为: 
NavController 和 ModalController 都是打开新页面,但是NavController 是直接将页面放入到原有的页面堆栈中的,而ModalController 是创建一个新的页面堆栈(root nav stack),然后再放进去。

最直观的界面效果区别

  1. 使用Tabs 菜单,使用NavController 方法跳转的页面,并不会移除Tabs 
    菜单;但是使用ModalController 方法就会从底部弹出新的页面,并且没有了Tabs 菜单。
  2. 使用NavController 方法,新页面默认有返回按钮,使用 ModalController 
    方法新页面默认是没有返回按钮的。

文档连接: 
NavController :https://ionicframework.com/docs/api/navigation/NavController/ 
ModalController:https://ionicframework.com/docs/api/components/modal/ModalController/

新建 login 页面

// cd到项目目录,然后执行下面的代码 ionic g page login --no-module
  • 1
  • 2

命令的说明:

  • ionic g page login 生成的 page 上面带有 module 文件
  • ionic g page login –no-module 生成的 page 上面不带有 module 文件

执行完之后生成的文件,图示: 
login

添加到根模块

进入 src/app 下,修改 app.module.ts

// 导入 loginPage import {LoginPage} from "../pages/login/login"; // 在以下节点上面添加 LoginPage declarations:[
    LoginPage
],
entryComponents:[
    LoginPage
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

修改程序的首页

我们程序进入的第一个界面,一般都是登录界面,然后通过跳转才到首页。所以,我们需要修改下程序的逻辑。 
进入 src/app/ 下,修改 app.component.ts

// 导入 loginPage import {LoginPage} from "../pages/login/login"; // 将源码部分的 rootPage 指向到 LoginPage // rootPage:any = TabsPage; rootPage:any = LoginPage; // 这个地方就加载程序启动的页面
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

修改登录界面

修改login.html

打开login.html文件,写入以下代码

<ion-header> <ion-navbar> <ion-title text-center>登录</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-list inset> <ion-item> <ion-input type="text" value="admin" placeholder="用户名" #username></ion-input> <ion-icon ios="ios-person" md="md-person" item-end [ngStyle]="iconStyle"></ion-icon> </ion-item> <ion-item> <ion-input [type]="isShow ? 'text':'password'" value="88888" placeholder="密码" #password></ion-input> <ion-icon ios="ios-key" md="md-key" item-end [ngStyle]="iconStyle"></ion-icon> </ion-item> <ion-item no-lines> <ion-label> <!-- 控制字体图标的显示是由 ios 以及 md 两个属性控制的  --> <ion-icon [ios]="isShow ? 'ios-eye' : 'ios-eye-off'" [md]="isShow ? 'md-eye' : 'md-eye-off'"></ion-icon> </ion-label> <ion-toggle checked="false" [(ngModel)]="isShow"></ion-toggle> </ion-item> <ion-item no-lines> <label item-left>记住密码</label> <ion-toggle checked="false" [(ngModel)]="isRemember"></ion-toggle> </ion-item> </ion-list> <div padding> <button ion-button block color="primary" (click)="_login(username, password)">登录</button> </div> </ion-content> 
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

图示: 
这里写图片描述

部分样式说明:

// text-center 让文字居中 <ion-title text-center>登录</ion-title> // no-lines 去除底部的线条 <ion-item no-lines></ion-item> // item-left 让文字居左 <label item-left>记住密码</label>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

修改login.ts

import { Component } from '@angular/core';
import { ModalController, ToastController} from 'ionic-angular';
import { TabsPage} from "../tabs/tabs";
import {Storage} from "@ionic/storage";

@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage { public isRemember: boolean = false; public isShow: boolean = false;

  iconStyle: object = {'color':'#488aff','font-size':'1.4em'};

  constructor(public modalCtrl: ModalController, public toastCtrl: ToastController, public storage: Storage) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LoginPage');
  }

  _login(username: HTMLInputElement, password: HTMLInputElement){ if (username.value.length === 0){ this.showToast("bottom", "请输入"); return false;
    } if (password.value.length === 0){ this.showToast("bottom", "请输入密码"); return false;
    } let data = {username: username.value, password: password.value, isRemember: this.isRemember}; // 储存用户信息 this.storage.remove("USER_INFO"); this.storage.set("USER_INFO", JSON.stringify(data)); // 界面跳转 let modal = this.modalCtrl.create(TabsPage, data);
    modal.present();
  }

  showToast(position: string, message: string) { let toast = this.toastCtrl.create({
      message: message,
      duration: 2000,
      position: position
    });

    toast.present(toast);
  }
}
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

接下来的一篇介绍下:怎么实现记住密码之后直接进入到首页。

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


HTML条件注释用法诠释

seo达人

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

HTML条件注释用法诠释

注释内容以样式为例,如下:

1、支持所有IE浏览器

<!--[if IE]>
<link rel="stylesheet" href="all-ie-only.css" type="text/css"/>
<![endif]--> 
  • 1
  • 2
  • 3

2、支持非IE浏览器

<!--[if !IE]>
<link rel="stylesheet" href="not-ie.css" type="text/css"/>
<![endif]--> 
  • 1
  • 2
  • 3

上面是除了IE浏览器外所有浏览器都识别这个样式,另外CSS-TRICKS《How To Create an IE-Only Stylesheet》一文中提供了另一种写法:

<!--[if !IE]><!--> <link rel="stylesheet" type="text/css" href="not-ie.css" /> <!--<![endif]--> 
  • 1
  • 2
  • 3

3、仅仅支持IE10

<!--[if IE 10]>
<link rel="stylesheet" type="text/css" href="ie10.css">
<![endif]--> 
  • 1
  • 2
  • 3

4、支持IE10以下版本(IE9以及IE9以下版本)

这种方法是样式表使用在低于IE10的浏览器,换句话说除了IE10以外的所有IE版本都将被支持。

<!--[if lt IE 10]>
<link rel="stylesheet" type="text/css" href="ie9-and-down.css">
<![endif]--> 
  • 1
  • 2
  • 3

也可以写成

<!--[if lte IE 9]>
<link rel="stylesheet" type="text/css" href="ie9-and-down.css">
<![endif]--> 
  • 1
  • 2
  • 3

前面我们也说过了lt和lte的区别,lt表示小于版本号,不包括条件版本号本身;而lte是小于或等于版本号,包括了版本号自身

上面这几种方法,使用的是低于(lt)和低于或等于(lte)的方法来判断,我们也可以使用大于gt和大于或等于gte达到上面的效果:

5、高于IE9的版本(IE10以及IE10以上版本)

<!--[if gt IE 9]>
<link rel="stylesheet" type="text/css" href="ie10-and-up.css">
<![endif]--> 
  • 1
  • 2
  • 3

<!--[if gte IE 10]>
<link rel="stylesheet" type="text/css" href="ie10-and-up.css">
<![endif]--> 
  • 1
  • 2
  • 3

6、指定多种IE版本

<!--[if (IE 6)|(IE 7)|(IE 8)]>
<link rel="stylesheet" type="text/css" href="ie6-7-8.css">
<![endif]--> 
  • 1
  • 2
  • 3

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




javascript中数组和对象的深拷贝和浅拷贝

seo达人

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

1、首先理解一下“深拷贝”和“浅拷贝”的区别:

浅拷贝:a = b;//a和b中存的是相同的地址,该地址指向堆内存中相同的地方,即a和b就是一个东西,改变a的值b的值也会跟着改变,同理改变b的值a的值也会发生改变;

深拷贝:a和b中存的地址不同,但是地址对应的堆内存中的内容完全一致,即b是a的副本

2、

(1)数组和对象的浅拷贝一样  ,简单的赋值操作

var b = a;

如数组的浅拷贝:

[javascript] view plain copy
  1. var a = ['1','2','3'];  
  2. var b = a;  
  3. b[0] = '5';  
  4. console.log('a',a);  
  5. console.log('b',b);  

输出的值为:

对象的浅拷贝:

[html] view plain copy
  1. var a = {name:'1',age:'2',color:'3'};  
  2. var b = a;  
  3. b.name = '5';  
  4. console.log('a',a);  
  5. console.log('b',b);  

输出的值为:

(2)数组的深拷贝

ES5:var b = a.concat();

[javascript] view plain copy
  1. var a = ['1','2','3'];  
  2. var b = a.concat();  
  3. b[0] = '5';  
  4. console.log('a',a);  
  5. console.log('b',b);  

输出的结果为:

ES6 let [...b] = a;

(3)对象的深拷贝

ES5: 

[javascript] view plain copy
  1. var a = {name:'1',age:'2',color:'3'};  
  2. function copyObj(a) {  
  3. var b = {};  
  4. for(var key in a) {  
  5. b[key] = a[key];  
  6. }  
  7. return b;  
  8. }  
  9. var c = copyObj(a);  
  10. c.name = '5';  
  11. console.log('c',c);  
  12. console.log('a',a);  

输出的结果为:

ES6:

let {...b} = a;


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


jQuery选择器(二)基本选择器+层次选择器

seo达人

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

1:获取所有的<p>元素,对<p>元素继续循环,因为获取的是数组对象,给每个<p>元素添加行为事件

var items=document.getElementsByTagName("p"); for(var i=0;i<items.length;i++){
    items[i].onclick=function(){ //do something  }
}
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2:根据表格id获取表格,在表格内获取<tbody>元素,在<tbody>元素下获取<tr>元素,循环输出获取的<tr>元素,对元素的索引值除以2取模,然后根据奇偶设置不同的背景色。

var item=docuement.getElementById("tb"); var tbody=item.getElementsByTagName("tbody")[0]; var trs=tbody.getElementByTagName("tr"); for(var i=0;i<trs.length;i++){ if(i%2==0){
      trs[i].style.backgroundColor="#888";
   }
}
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3:新建一个空数组,获取所有name为”check”的多选框,循环判断多选框是否被选中,如果被选中则添加到数组里,获取输出按钮,然后为按钮添加onclick事件,输出数组长度即可。

var btn=document.getElementById("btn");
btn.onclick=function(){ var array=new Array(); var items=document.getElementsByName("check"); for(i=0;i<items.length;i++){ if(items[i].checked){ array.push(items[i].value);
     }
  }
  alert(array.length);  
}
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

基本选择器:

#id  $("#test")选取id为test的元素 .class $(".test")选取所有classtest的元素 element $("p")选取所有的<p>元素 $("div,span,p.myClass") 选取所有的<div>,<span>和拥有classmyClass<p>标签的一组元素
    
  • 1
  • 2
  • 3
  • 4
  • 5

层次选择器:

$("ancestor  descendant") $("div span")选取<div>里面所有的<span>元素 $("parent>child") $("div >span")选取<div>元素下元素名为<span>的子元素 $("prev+next") $(".one+div")选取classone的下一个<div>同辈元素 $("#two~div")选取id为two的元素后面的所有<div>同辈元素

后面两个用得少,因为在jQuery里可以用更加简单的方法代替 $(".one+div") $(".one").next("div"); $("prev~div") $("#prev").nextAll("div");
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务


HTML基础应用

seo达人

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

本篇文章基本介绍了学习HTML的一些基础的语法与标签,标签包括换行</br>,加粗<b>,下划线<hr/>斜体字<i>,字体<h1....6>,标题<title>......

<small>

<small> 标签呈现小号字体效果

。如果被包围的字体已经是字体模型所支持的最小字号,那么 <small> 标签将不起任何作用。

<small> 标签也可以嵌套,从而连续地把文字缩小。每个 <small> 标签都把文本的字体变小一号,直到达到下限的一号字。

<sub>表示下标<sup>表示上标。

<p>与<pre>有些类似

pre 元素可定义预格式化的文本。被包围在 pre 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。

<pre> 标签的一个常见应用就是用来表示计算机的源代码。

p 元素会自动在其前后创建一些空白。

<ul>与<ol>

两者都指列表,前者是无序的,后者是有序的。

[html] view plain copy
  1. <html>  
  2. <head>  
  3. <span style="color:#33ff33;"><title></span>HTML 5 Tag Reference</title>  
  4. </head>  
  5. <body>  
  6. <span style="color:#33ff33;"><h1></span>The content of the document......<span style="color:#33ff33;"><br/></span></h1>  
  7. <h2>The content of the document......<br/></h2>  
  8. <h3>The content of the document......<br/></h3>  
  9. <h4>The content of the document......<br/></h4>  
  10. <h5>The content of the document......</h5>  
  11.   
  12. <h1>The content of the document......<br/></h1>  
  13. <h1><span style="color:#33ff33;"><small></span>The content of the document......</small><br/></h1>  
  14.   
  15. <span style="color:#33ff33;"><pre></span>  
  16. HTML基础应用  
  17.   
  18. HTML基础应用学习和掌握HTML语言的基本语法,常用的标签的使用方法;学会使用HTML设计基本的简单  
  19.   
  20. 网页。  
  21.   
  22. </pre>  
  23. <span style="color:#33ff33;"><hr/></span>  
  24. <span style="color:#33ff33;"><p>  
  25. <i></span>This is some text in a very short paragraph</i>  
  26. </p>  
  27. <span style="color:#33ff33;"><b></span>The content of the document......</b></br>  
  28.   
  29. a<span style="color:#33ff33;"><sup>2</sup><sub>0</sub></span>+b<sup>2</sup><sub>0</sub>=c<sup>2</sup><sub>0</sub>  
  30.   
  31. <span style="color:#33ff33;"><ul></span>  
  32. <li>sports</li>  
  33. <li> food </li>  
  34. <li> drink </li>  
  35. <li> friends </li>  
  36. </ul>  
  37. <span style="color:#33ff33;"><ol></span>  
  38.     <li>sports</li>  
  39.     <li> drink</li>  
  40.     <li> friends</li>  
  41. </ol>  
  42.   
  43. <span style="color:#33ff33;"><dl> </span>  
  44. <dt>计算机</dt>   
  45.     <dd>用来计算的仪器 ... ...</dd>   
  46. <dt>显示器</dt>   
  47.     <dd>以视觉方式显示信息的装置 ... ...</dd>   
  48. </dl>   
  49.   
  50. </body>  
  51. </html>  

效果:

其中<title>体现在最上方的搜索栏中。

 


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

用Flow提升前端代码健壮性

seo达人

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

看一段常见代码:

//例1 function foo(x) { return x + 10 }
foo('Hello!') //例2 function main(params){ //fn1函数获取了一个数据 var object = fn1(params) //fn2根据获数据,产生一个结果 var result = fn2(object) return result
}
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

例2很明显,这个过程非常的‘黑’,如果你想知道object包含什么数据的话,可以:

  1. 打印一下 console.log(object)
  2. 查看fn1的注释,并且保佑它的注释是正确,全面的
  3. 或结合1,2,然后仔细查看fn1的源码,希望它不是很复杂

被上述步骤折磨完之后,终于能真正的写点代码了,但是依旧得非常小心,因为这里还有另一个函数:fn2

在修改代码的时候,得保证result这个结果没有被影响,那么如何保证呢?

很简单,重复上面的步骤,搞清楚result包含的数据,在测试的时候确保其数据跟原先的相同。 

动态类型一时爽,代码重构火葬场 
知乎传送门:为什么说“动态类型一时爽,代码重构火葬场”

是时候彻底优化这个烦人的问题了

引入类型系统

其实问题的根源就是因为javascript太灵活了,在代码运行期间几乎可以做任何的修改,

没有东西可以在代码层面保证 某个变量,某个函数 跟预期的一致

所以要加入类型系统来确保代码的可靠性,在后期维护的时候同样能够传达出有效的信息

Flow & TypeScript

Flow是个JavaScript的静态类型检查工具,由Facebook出品的开源码项目,问世只有两三年,是个相当年轻的项目。简单来说,它是对比TypeScript语言的解决方式。

会有这类解决方案,起因是JavaScript是一种弱(动态)数据类型的语言,弱(动态)数据类型代表在代码中,变量或常量会自动依照赋值变更数据类型,而且类型种类也很少,这是直译式脚本语言的常见特性,但有可能是优点也是很大的缺点。优点是容易学习与使用,缺点是像开发者经常会因为赋值或传值的类型错误,造成不如预期的结果。有些时候在使用框架或函数库时,如果没有仔细看文件,亦或是文件写得不清不楚,也容易造成误用的情况。

这个缺点在应用规模化时,会显得更加严重。我们在团队开发协同时,一般都是通过统一的代码规范,来降低这个问题的发生,但JS语言本身无法有效阻止这些问题TypeScript这样的强(静态)类型的JavaScript超集语言就开始流行,用严格的角度,以JavaScript语言为基底,来重新打造另一套具有强(静态)类型特性的语言,就如同Java或C#这些语言一样,这也是为什么TypeScript称自己是企业级的开发JavaScript解决方案。

TypeScript存在的问题

TypeScript自然有它的市场,但它有一些明显的问题:

  • 首先是JavaScript开发者需要再进一步学习,内容不少
  • 有一定陡峭的学习曲线
  • 已经在使用的应用代码,需要整个改用TypeScript代码语法,才能发挥完整的功用。这对很多已经有内部代码库的大型应用开发团队而言,将会是个重大的决定,因为如果不往全面重构的路走,将无法发挥强(静态)类型语言的最大效用eg:angular2

*所以许多现行的开源码函数库或框架,并不会直接使用TypeScript作为代码的语言,另一方面因为TypeScript并非是普及到一定程度的语言。 
当然TypeScript也是个活跃的开源码项目,发展到现在也有一段时间,它的背后有微软公司的支持,全新打造过的Angular2框架中(由Google主导),也采用了TypeScript作为基础的开发语言*

Flow你的新选择

现在,Flow提供了另一个新的选项,它是一种强(静态)类型的辅助检查工具Flow的功能是让现有的JavaScript语法可以事先作类型的声明(定义),在开发过程中进行自动检查,当然在最后编译时,一样可以用babel工具来移除这些标记

相较于TypeScript是另外重新制定一套语言,最后再经过编译为JavaScript代码来运行。Flow走的则是非强制与非侵入性的路线。

Flow的优点

  • 且易学易用 
    它的学习曲线没有TypeScript来得高,虽然内容也很多,但半天学个大概,就可以渐进式地开始使用
  • Flow从头到尾只是个检查工具 
    不是新的程序语言或超集语言,所以它可以与各种现有的JavaScript代码兼容,如果你哪天不想用了,就去除掉标记就是回到原来的代码,没什么负担

so

选择flow.js工具而不选择TypeScript强类型语言的原因显而易见? 
flow.js对工程的侵入性很小,无需大量的额外工作就能使用起来

从一个小例子演示

这种类型不符的情况在代码中非常容易发生,例如上面的例1:

function foo(x) { return x + 10 }

foo('Hello!')
    
  • 1
  • 2
  • 3
  • 4
  • 5

x这个传参,我们在函数声明时希望它是个数字类型,但最后使用调用函数时则用了字符串类型。最后的结果会是什么吗? “Hello!10”,这是因为加号(+)在JavaScript语言中,除了作为数字的加运算外,也可以当作字符串的连接运算。想当然这并不是我们想要的结果。

聪明如你应该会想要用类型来当传参的识别名,容易一眼看出传参要的是什么类型,像下面这样:

function foo(number) { return number + 10 }
    
  • 1
  • 2
  • 3
  • 如果在复合类型的情况,例如这个传参的类型可以是数字类型也可以是布尔类型,你又要如何写得清楚?
  • 如果是个复杂的对象类型时,结构又该如何先确定好?
  • 另外还有函数的返回类型又该如何来写?

利用Flow类型的定义方式,来解决这个小案例的问题,可以改写为像下面的代码:

// @flow function foo(x: number): number { return x + 10 }

foo('hi')
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

当使用非数字类型的值作为传入值时,就会出现由Flow工具发出的警告消息,像下面这样:

[flow] Cannot call foo with 'hi' bound to x because string 1 is incompatible with number 2. (a.getting-start.js:6:5)

如果是要允许多种类型也是很容易可以加标记的,假使这个函数可以使用布尔与数字类型,但返回可以是数字或字符串,就像下面这样修改过:

// @flow function foo(x: number | boolean): number | string { if (typeof x === 'number') { return x + 10 } return 'x is boolean' }

foo(1)
foo(true)
foo(null) // 这一行有类型错误消息
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在多人协同开发某个有规模的JavaScript应用时,这种类型的输出输入问题就会很常遇见。如果利用Flow工具的检查,可以避免掉许多不必要的类型问题

真实案例

可能你会认为Flow工具只能运用在小型代码中,其实不然,Vue源码中大量使用flowjs中类型检测: 
此处输入图片的描述

Flow使用

此处输入图片的描述 
1. flow init 
2. // @flow 或 /* @flow */ 
3. IDE插件 或 flow check 
在Visual Studio Code中因为它内建TypeScript与JavaScript的检查功能,如果要使用Flow工具来作类型检查,需要在用户设置中,加上下面这行设置值以免冲突:

“javascript.validate.enable”: false

4 . babel插件在编译时就会一并转换Flow标记

{
  "plugins": [ "transform-flow-strip-types" ] }
    
  • 1
  • 2
  • 3
  • 4
  • 5

Flow支持的数据类型

Flow支持原始数据类型,如下面的列表:

  • boolean
  • number
  • string
  • null
  • void

类型别名&常见语法

// @flow export type Test = {
  titleOne?: string,
  titleTwo: ?string
} var a: Test = {titleOne:"3",titleTwo:4} var b:string = "" //any export type NavigationGestureDirection = 'horizontal' | 'vertical';

type T = Array<string> var x: T = []
x["Hi"] = 2 //有Flow警告 type TT = Array<Test> var xx:TT = []
xx = [{titleOne: '1',
  titleTwo: false}]

type MyObject = {
  foo: number,
  bar: boolean,
  baz: string,
};

let val:MyObject = {foo:2,bar:false,baz:'444'}; var val1: MyObject = {foo:2,bar:false,baz:null}; var val2: MyObject = {foo:2,bar:false}; function method(val: MyObject):MyObject { return {foo:2,bar:false,baz:'2'}} class Foo { constructor(val: MyObject) { /* ... */ } }
    
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31

React中的应用

如果你在React class里面使用了React.PropTypes规范,你可以对JSX上的attributes做静态类型检查:

var Hello = React.createClass ({
  propTypes: {
    name: React.PropTypes.string.isRequired
  } ... });
//<Hello/> //Flow就会发现 缺少属性的错误
//<Hello name={42}/>//属性类型的错误
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
import * as React from 'react'; type Props = {
  foo: number,
  bar?: string,
}; function MyComponent(props: Props) {
  props.doesNotExist; // Error! You did not define a `doesNotExist` prop. return <div>{props.bar}</div>;
}

<MyComponent foo={42} />
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

更多关于支持React的细节 请移步 https://flow.org/en/docs/react/components/

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

如何看待CSS中BEM的命名方式?

seo达人

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

BEM的意识就是块(block)、元素(element)、修饰符(modifier),是由yandex团队提出的一种CSS Class命名方法。

任何一个东西的存在都有其存在的道理,如果他毫无价值,那么肯定会被淘汰,后人可能都不了解,甚至都不会出现在后人的世界里。

如何看待CSS中BEM的命名方式?

关于BEM命名其最大的争议就是其命名风格,它鼓励一级一级的写的非常具体,但是会很长。如此常的命名会影响书写效率,名称过长代码量就会增多,文件体积就会变大(在gzip下这个不算是个问题),从而会影响传输速度,用户体验度就低,但是作为一个职业人我们都不能单纯把个人喜好和习惯作为借口来拒绝或否定其用途。

风格对于使用者来说并不是很重要,关键的是看其效果。正所谓人们常说的“不看疗程,看疗效”。

从扩展性上来看,嵌套过多阅读性差,超过3层就很难阅读了;嵌套越多,选择器的层级也会随之增多,那么性能不知不觉就会变差;如此长的名字,书写上想冲突都难。

从编程原则上来说,这种命名方式不会暴露抽象类。假如样式变了需要继承另一个抽象类,不需要改HTML,只需要改css即可。

团队开发中,风格无非是一种形式,可以约束人们达到一定程度上的统一。内部沟通会极大降低沟通成本。

BEM命名的方法虽然有自身的不足之处,但至少他可以使我们命名的时候达到一定的统一,我们可以学习其优秀的方面将其纳为己用。在实际项目开发中将其巧妙而又灵活的运用起来也未尝不是一件坏事。

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

日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档