微信小程序学习资源汇总 /2018/03/24/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90%E6%B1%87%E6%80%BB/ 微信小程序开发资源汇总

在github上看了justjavac的一篇关于小程序资源的汇总,觉得挺不错的就并转发至

个人博客

目录

置顶

官方文档

工具

插件

文档

讨论

教程

视频教程

文章

代码

轮子

原文链接

]]>
小程序 小程序
从url到页面渲染浏览器经历了什么? /2018/03/18/%E4%BB%8Eurl%E5%88%B0%E9%A1%B5%E9%9D%A2%E6%B8%B2%E6%9F%93%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BB%8F%E5%8E%86%E4%BA%86%E4%BB%80%E4%B9%88%EF%BC%9F/

面对这个问题?我想了想,看了看,参考了一下别人的文章,并自己梳理了一下知识,其中有好多东西没有涉及到比如web安全、性能优化、绘话技术、存储技术、负载均衡、集群等,日后有空再慢慢补充,此文也只是简单的记录一下自己对此的理解。以便形成自己前端知识体系,如若有错,欢迎指出!,哈哈哈哈哈,不瞎扯了,看文章了
!

浏览器的组成

  1. 用户界面:包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分
  2. 浏览器引擎:用来查询及操作渲染引擎的接口
  3. 渲染引擎:用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来
  4. 网络:用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
  5. UI 后端:用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口
  6. JS解释器-用来解释执行JS代码
  7. 数据存储:属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术

这里写图片描述

浏览器从请求到渲染经历的过程

  1. DNS域名解析
  2. TCP/IP连接
  3. HTTP 请求即响应
  4. 服务器响应
  5. 客户端渲染

DNS 查询

DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库

dns解析成IP的大致流程

  • 如果浏览器有缓存直接使用浏览器缓存,否则使用本机缓存,再没有的话就是用host
  • 如果本地没有,就向dns域名服务器查询(当然,中间可能还会经过路由,也有缓存等),查询到对应的IP

注意,域名查询时有可能是经过了CDN调度器的(如果有cdn存储功能的话)。而且,需要知道dns解析是很耗时的,因此如果解析域名过多,会让首屏加载变得过慢,可以考虑 dns-prefetch优化。

关于DNS缓存

  • 查看Chome浏览器的DNS缓存:在地址栏输入chrome://dns

这里写图片描述

  • 清除Chrome浏览器的DNS缓存

    这里写图片描述

  • 清除本机DNS缓存,此截图以win系统为例, cmd输入命令ipconfig /flushdns

    这里写图片描述

TCP/IP

tcp/ip请求

http的本质就是 tcp/ip请求。

需要了解3次握手规则建立连接以及断开连接时的四次挥手。

tcp将http长报文划分为短报文,通过三次握手与服务端建立连接,进行可靠传输。

三次握手的步骤(抽象派)

  • 客户端:hello,你是server么?
  • 服务端:hello,我是server,你是client么
  • 客户端:yes,我是client

建立连接成功后,接下来就正式传输数据。

然后,待到断开连接时,需要进行四次挥手(因为是全双工的,所以需要四次挥手)。

四次挥手的步骤(抽象派)

  • 主动方:我已经关闭了向你那边的主动通道了,只能被动接收了
  • 被动方:收到通道关闭的信息
  • 被动方:那我也告诉你,我这边向你的主动通道也关闭了
  • 主动方:最后收到数据,之后双方无法通信

tcp/ip的并发限制

浏览器对同一域名下并发的tcp连接是有限制的(2-10个不等)。

而且在http1.0中往往一个资源下载就需要对应一个tcp/ip请求。

所以针对这个瓶颈,又出现了很多的资源优化方案。

get和post的区别

get和post虽然本质都是tcp/ip,但两者除了在http层面外,在tcp/ip层面也有区别。

get会产生一个tcp数据包,post两个。

具体就是:

  • get请求时,浏览器会把 headersdata一起发送出去,服务器响应200(返回数据),
  • post请求时,浏览器先发送 headers,服务器响应 100continue,浏览器再发送 data,服务器响应200(返回数据)。

再说一点,这里的区别是 specification(规范)层面,而不是 implementation(对规范的实现)

五层因特网协议栈

其实这个概念挺难记全的,记不全没关系,但是要有一个整体概念。

其实就是一个概念:从客户端发出http请求到服务器接收,中间会经过一系列的流程。

简括就是:从应用层的发送http请求,到传输层通过三次握手建立tcp/ip连接,再到网络层的ip寻址,再到数据链路层的封装成帧,最后到物理层的利用物理介质传输。

当然,服务端的接收就是反过来的步骤。

五层因特尔协议栈其实就是: 1.应用层(dns,http) DNS解析成IP并发送http请求 2.传输层(tcp,udp) 建立tcp连接(三次握手) 3.网络层(IP,ARP) IP寻址 4.数据链路层(PPP) 封装成帧 5.物理层(利用物理介质传输比特流) 物理传输(然后传输的时候通过双绞线,电磁波等各种介质)

当然,其实也有一个完整的OSI七层框架,与之相比,多了会话层、表示层。

OSI七层框架: 物理层数据链路层网络层传输层会话层表示层应用层

  • 表示层:主要处理两个通信系统中交换信息的表示方式,包括数据格式交换,数据加密与解密,数据压缩与终端类型转换等
  • 会话层:它具体管理不同用户和进程之间的对话,如控制登陆和注销过程

这里写图片描述

HTTP状态码对照表

这里写图片描述

http常见的状态码

这里面最常用到的就是状态码,很多时候都是通过状态码来判断,如(列举几个最常见的):

  • 200——表明该请求被成功地完成,所请求的资源发送回客户端
  • 304——自从上次请求后,请求的网页未修改过,请客户端使用本地缓存
  • 400——客户端请求有错(譬如可以是安全模块拦截)
  • 401——请求未经授权
  • 403——禁止访问(譬如可以是未登录时禁止)
  • 404——资源未找到
  • 500——服务器内部错误
  • 503——服务不可用

请求报文结构

这里写图片描述

渲染引擎基本流程

渲染引擎首先通过网络获得所请求文档的内容后进行如下渲染流程

渲染基本流程:

解析html以构建dom树->构建render树->布局render树->绘制render树

这里写图片描述

具体渲染流程图如下

这里写图片描述
​ webkit渲染引擎的主流程

这里写图片描述
​ Mozilla的Geoko 渲染引擎主流程

从图可以看出,尽管webkit和Gecko使用的术语稍有不同,他们的主要流程基本相同。Gecko称可见的格式化元素组成的树为frame树,每个元素都是一个frame,webkit则使用render树这个名词来命名由渲染对象组成的树。Webkit中元素的定位称为布局,而Gecko中称为回流。Webkit称利用dom节点及样式信息去构建render树的过程为attachment,Gecko在html和dom树之间附加了一层,这层称为内容接收器,相当制造dom元素的工厂。下面将讨论流程中的各个阶段。

参考资料:

https://www.kafan.cn/edu/620091.html

http://mp.weixin.qq.com/s/qMsf4DcMhn2cf0fXC-PLVA

]]>
浏览器渲染原理 浏览器渲染原理
美团开源用mpvue,可以用vue开发小程序了! /2018/03/15/%E5%8F%AF%E4%BB%A5%E7%94%A8mpVue%E5%BC%80%E5%8F%91%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BA%86%EF%BC%81%E7%BE%8E%E5%9B%A2%E5%BC%80%E6%BA%90%E7%94%A8%20Vue.js%20%E5%BC%80%E5%8F%91%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6%20mpvue/ 传送门:官方文档说明

如何看待美团开源的 mpvue ?

先来看一下,知乎的大佬们对mpvue的看法………….

mpvue 简介

mpvuegithub 地址请参见)是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.jsruntimecompiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。

mpvue 特性

主要特性

使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力:

  • 彻底的组件化开发能力:提高代码复用性
  • 完整的 Vue.js 开发体验
  • 方便的 Vuex 数据管理方案:方便构建复杂应用
  • 快捷的 webpack 构建机制:自定义构建策略、开发阶段 hotReload
  • 支持使用 npm 外部依赖
  • 使用 Vue.js 命令行工具 vue-cli 快速初始化项目
  • H5 代码转换编译成小程序目标代码的能力

其它特性正在等着你去探索,详细文档

配套设施

mpvue 作为小程序版本的 Vue.js,在框架 SDK 之外,完整的技术体系还包括如下设施。

mpvue实现原理

img

● 将小程序页面编写为 Vue.js 实现

● 以 Vue.js 开发规范实现父子组件关联

小程序代码

● 以小程序开发规范编写视图层模板

● 配置生命周期函数,关联数据更新调用

● 将 Vue.js 数据映射为小程序数据模型

并在此基础上,附加如下机制

● Vue.js 实例与小程序 Page 实例建立关联

● 小程序和 Vue.js 生命周期建立映射关系,能在小程序生命周期中触发 Vue.js 生命周期

● 小程序事件建立代理机制,在事件代理函数中触发与之对应的 Vue.js 组件事件响应

快速上手

本文假设你既不会 vue 也不会小程序,如嫌拖沓,请直接快进跳读。

1. 初始化一个 mpvue 项目

现代前端开发框架和环境都是需要 Node.js 的,如果没有的话,请先下载 nodejs 并安装。

然后打开命令行工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. 先检查下 Node.js 是否安装成功
$ node -v
v8.9.0

$ npm -v
5.6.0

# 2. 由于众所周知的原因,可以考虑切换源为 taobao 源
$ npm set registry https://registry.npm.taobao.org/

# 3. 全局安装 vue-cli
# 一般是要 sudo 权限的
$ npm install --global vue-cli

# 4. 创建一个基于 mpvue-quickstart 模板的新项目
# 新手一路回车选择默认就可以了
$ vue init mpvue/mpvue-quickstart my-project

# 5. 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev

随着运行成功的回显之后,可以看到本地多了个 dist 目录,这个目录里就是生成的小程序相关代码。

2. 搭建小程序的开发环境

小程序自己有一个专门的微信开发者工具最新版本下载地址

这一步比较简单,按照提示一步步安装好就行,然后用微信扫描二维码登陆。 至此小程序的开发环境差不多完成。

3. 调试开发 mpvue

选择 小程序项目 并依次填好需要的信息:

  • 项目目录:就是刚刚创建的项目目录(非 dist 目录)
  • AppID:没有的话可以点选体验“小程序”,只影响是否可以真机调试。
  • 项目名称。

如图:

小程序项目配置

点击“确定”按钮后会跳到正式的开发页面,点击“编辑器”按钮,关闭自带的小程序编辑器。然后如图:

mpvue-start

此时,整个 mpvue 项目已经跑起来了。

用自己趁手的编辑器(或者IDE)打开 my-project 中的 src 目录下的代码试试,如示例:

到此,上手完毕。

注意事项

  1. 新增的页面需要重新 npm run dev 来进行编译
]]>
框架 mpvue vue
2017前端技术发展回顾 /2018/03/10/2017%E5%89%8D%E7%AB%AF%E6%8A%80%E6%9C%AF%E5%8F%91%E5%B1%95%E5%9B%9E%E9%A1%BE/ 2017 前端技术发展回顾

更多精彩内容请关注:前端开发者指南 2018



掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

]]>
转载 前端技术发展史
工作中数组常用方法 /2018/03/04/%E5%B7%A5%E4%BD%9C%E4%B8%AD%E6%95%B0%E7%BB%84%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95/ 工作中数组常用的方法:forEach、map、filter、every的对比

代码如下:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// ES5新增的常用数组方法
let arr = [1, 2, 3, 2, 1];

// 一 forEach => 遍历数组
arr.forEach((v, i) => {
console.log(v, i);
});

// 二 map => 使用一个数组, 利用某规则映射得到一个新数组
let mapArr = arr.map((v, i) => {
return v * v;
});
arr.map((v, i) => v * v); // 如果只有一句话, 可以省略大括号和return
console.log(mapArr); // [1, 4, 9, 4, 1]

// 三 filter => 找出符合条件的元素

// 3.1 找出数组中的偶数
let filterArr1 = arr.filter((v, i) => v % 2 == 0);
console.log(filterArr1);

// 3.2 删除数组中的偶数
let filterArr2 = arr.filter((v, i) => v % 2 != 0); // 找出数组中的奇数留下来即可
console.log(filterArr2);

// 四 every => 判断数组中的所有元素是否都符合某种条件

// 4.1 数组中的数字是否都是偶数
let result1 = arr.every((v, i) => v % 2 == 0) // 所有的结果都为true, 结果为true, 有一个false, 结果为false
console.log(result1)

// 4.2 数组中的数字是否都大于0
let result2 = arr.every(v => v > 0)
console.log(result2)

// 五 some => 判断数组中是否含有符合条件的元素

// 5.1 数组中是否有大于2的数
let result3 = arr.some(v => v > 2) // 只要有一个true, 结果为true
console.log(result3)

// 5.2 数组中是否有小于1的数
let result4 = arr.some(v => v < 1)
console.log(result4)
</script>
</body>
</html>
]]>
js数组 js数组
javascript中的数组和字符串方法总结 /2017/10/09/javascript%E4%B8%AD%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%96%B9%E6%B3%95%E6%80%BB%E7%BB%93/

在学习js的数组和字符串方法的时候会发现彼此之间好多方法是类似的,为了方便记忆及发现两者之间的关联,之后就自己总结了一个xmind的思维导构,总结可能有瑕疵,哪里有错误的话,希望各位大牛多指出!ThankYou!!!

javascript数组和字符串中的方法总结

###注意:
由于考虑到该思维导构图为png格式,所以图片里面的备注是没办法看到的,所以如果需要源文件的话可以点击下面百度云链接下载,辛苦编写,如果觉得对您有用的话,不吝点个赞哈!谢谢。


链接http://pan.baidu.com/s/1hr5IZZY 密码:5alp

]]>
js数组 js数组
vscode编辑器的常用快捷键 /2017/09/08/vscode%E7%BC%96%E8%BE%91%E5%99%A8%E7%9A%84%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/

typora-copy-images-to: medias


vs code 的使用技巧

[TOC]

在线下载地址

vs code 官网

在线安装插件

插件建议在线安装,因为离线安装 容易出现问题

插件截图

这里写图片描述

常用快捷键

常用 General

按 Press功能 Function
Ctrl + Shift + P,F1显示命令面板 Show Command Palette
Ctrl + P快速打开 Quick Open
Ctrl + Shift + N新窗口/实例 New window/instance
Ctrl + Shift + W关闭窗口/实例 Close window/instance

基础编辑 Basic editing

按 Press功能 Function
Ctrl+X剪切行(空选定) Cut line (empty selection)
Ctrl+C复制行(空选定)Copy line (empty selection)
Alt+ ↑ / ↓向上/向下移动行 Move line up/down
Shift+Alt + ↓ / ↑向上/向下复制行 Copy line up/down
Ctrl+Shift+K删除行 Delete line
Ctrl+Enter在下面插入行 Insert line below
Ctrl+Shift+Enter在上面插入行 Insert line above
Ctrl+Shift+\跳到匹配的括号 Jump to matching bracket
Ctrl+] / [缩进/缩进行 Indent/outdent line
Home转到行首 Go to beginning of line
End转到行尾 Go to end of line
Ctrl+Home转到文件开头 Go to beginning of file
Ctrl+End转到文件末尾 Go to end of file
Ctrl+↑ / ↓向上/向下滚动行 Scroll line up/down
Alt+PgUp / PgDown向上/向下滚动页面 Scroll page up/down
Ctrl+Shift+[折叠(折叠)区域 Fold (collapse) region
Ctrl+Shift+]展开(未折叠)区域 Unfold (uncollapse) region
Ctrl+K Ctrl+[折叠(未折叠)所有子区域 Fold (collapse) all subregions
Ctrl+K Ctrl+]展开(未折叠)所有子区域 Unfold (uncollapse) all subregions
Ctrl+K Ctrl+0折叠(折叠)所有区域 Fold (collapse) all regions
Ctrl+K Ctrl+J展开(未折叠)所有区域 Unfold (uncollapse) all regions
Ctrl+K Ctrl+C添加行注释 Add line comment
Ctrl+K Ctrl+U删除行注释 Remove line comment
Ctrl+/切换行注释 Toggle line comment
Shift+Alt+A切换块注释 Toggle block comment
Alt+Z切换换行 Toggle word wrap

导航 Navigation

按 Press功能 Function
Ctrl + T显示所有符号 Show all Symbols
Ctrl + G转到行… Go to Line…
Ctrl + P转到文件… Go to File…
Ctrl + Shift + O转到符号… Go to Symbol…
Ctrl + Shift + M显示问题面板 Show Problems panel
F8转到下一个错误或警告 Go to next error or warning
Shift + F8转到上一个错误或警告 Go to previous error or warning
Ctrl + Shift + Tab导航编辑器组历史记录 Navigate editor group history
Alt + ←/→返回/前进 Go back / forward
Ctrl + M切换选项卡移动焦点 Toggle Tab moves focus

搜索和替换 Search and replace

按 Press功能 Function
Ctrl + F查找 Find
Ctrl + H替换 Replace
F3 / Shift + F3查找下一个/上一个 Find next/previous
Alt + Enter选择查找匹配的所有出现 Select all occurences of Find match
Ctrl + D将选择添加到下一个查找匹配 Add selection to next Find match
Ctrl + K Ctrl + D将最后一个选择移至下一个查找匹配项 Move last selection to next Find match
Alt + C / R / W切换区分大小写/正则表达式/整个词 Toggle case-sensitive / regex / whole word

多光标和选择 Multi-cursor and selection

按 Press功能 Function
Alt +单击插入光标 Insert cursor
Ctrl + Alt +↑/↓在上/下插入光标 Insert cursor above / below
Ctrl + U撤消上一个光标操作 Undo last cursor operation
Shift + Alt + I在选定的每一行的末尾插入光标 Insert cursor at end of each line selected
Ctrl + I选择当前行 Select current line
Ctrl + Shift + L选择当前选择的所有出现 Select all occurrences of current selection
Ctrl + F2选择当前字的所有出现 Select all occurrences of current word
Shift + Alt + →展开选择 Expand selection
Shift + Alt + ←缩小选择 Shrink selection
Shift + Alt + (拖动鼠标)列(框)选择 Column (box) selection
Ctrl + Shift + Alt +(箭头键)列(框)选择 Column (box) selection
Ctrl + Shift + Alt + PgUp / PgDown列(框)选择页上/下 Column (box) selection page up/down

丰富的语言编辑 Rich languages editing

按 Press功能 Function
Ctrl + 空格触发建议 Trigger suggestion
Ctrl + Shift + Space触发器参数提示 Trigger parameter hints
TabEmmet 展开缩写 Emmet expand abbreviation
Shift + Alt + F格式化文档 Format document
Ctrl + K Ctrl + F格式选定区域 Format selection
F12转到定义 Go to Definition
Alt + F12Peek定义 Peek Definition
Ctrl + K F12打开定义到边 Open Definition to the side
Ctrl + .快速解决 Quick Fix
Shift + F12显示引用 Show References
F2重命名符号 Rename Symbol
Ctrl + Shift + . /,替换为下一个/上一个值 Replace with next/previous value
Ctrl + K Ctrl + X修剪尾随空格 Trim trailing whitespace
Ctrl + K M更改文件语言 Change file language

编辑器管理 Editor management

按 Press功能 Function
Ctrl+F4, Ctrl+W关闭编辑器 Close editor
Ctrl+K F关闭文件夹 Close folder
Ctrl+\拆分编辑器 Split editor
Ctrl+ 1 / 2 / 3聚焦到第1,第2或第3编辑器组 Focus into 1st, 2nd or 3rd editor group
Ctrl+K Ctrl+ ←/→聚焦到上一个/下一个编辑器组 Focus into previous/next editor group
Ctrl+Shift+PgUp / PgDown向左/向右移动编辑器 Move editor left/right
Ctrl+K ← / →移动活动编辑器组 Move active editor group

文件管理 File management

按 Press功能 Function
Ctrl+N新文件 New File
Ctrl+O打开文件… Open File…
Ctrl+S保存 Save
Ctrl+Shift+S另存为… Save As…
Ctrl+K S全部保存 Save All
Ctrl+F4关闭 Close
Ctrl+K Ctrl+W关闭所有 Close All
Ctrl+Shift+T重新打开关闭的编辑器 Reopen closed editor
Ctrl+K输入保持打开 Enter Keep Open
Ctrl+Tab打开下一个 Open next
Ctrl+Shift+Tab打开上一个 Open previous
Ctrl+K P复制活动文件的路径 Copy path of active file
Ctrl+K R显示资源管理器中的活动文件 Reveal active file in Explorer
Ctrl+K O显示新窗口/实例中的活动文件 Show active file in new window/instance

显示 Display

按 Press功能 Function
F11切换全屏 Toggle full screen
Shift+Alt+1切换编辑器布局 Toggle editor layout
Ctrl+ = / -放大/缩小 Zoom in/out
Ctrl+B切换侧栏可见性 Toggle Sidebar visibility
Ctrl+Shift+E显示浏览器/切换焦点 Show Explorer / Toggle focus
Ctrl+Shift+F显示搜索 Show Search
Ctrl+Shift+G显示Git Show Git
Ctrl+Shift+D显示调试 Show Debug
Ctrl+Shift+X显示扩展 Show Extensions
Ctrl+Shift+H替换文件 Replace in files
Ctrl+Shift+J切换搜索详细信息 Toggle Search details
Ctrl+Shift+C打开新命令提示符/终端 Open new command prompt/terminal
Ctrl+Shift+U显示输出面板 Show Output panel
Ctrl+Shift+V切换Markdown预览 Toggle Markdown preview
Ctrl+K V从旁边打开Markdown预览 Open Markdown preview to the side

调试 Debug

按 Press功能 Function
F9切换断点 Toggle breakpoint
F5开始/继续 Start/Continue
Shift+F5停止 Stop
F11 / Shift+F11下一步/上一步 Step into/out
F10跳过 Step over
Ctrl+K Ctrl+I显示悬停 Show hover

集成终端 Integrated terminal

按 Press功能 Function
Ctrl+`显示集成终端 Show integrated terminal
Ctrl+Shift+`创建新终端 Create new terminal
Ctrl+Shift+C复制选定 Copy selection
Ctrl+Shift+V粘贴到活动端子 Paste into active terminal
Ctrl+↑ / ↓向上/向下滚动 Scroll up/down
Shift+PgUp / PgDown向上/向下滚动页面 Scroll page up/down
Ctrl+Home / End滚动到顶部/底部 Scroll to top/bottom
]]>
编辑器 编辑器
浅谈Ajax /2017/09/04/%E6%B5%85%E8%B0%88Ajax/ 文章目录

[TOC]

Ajax概述

  • 术语ajax最早产生于2005年,Ajax表示Asynchronous JavaScript and XML(异步JavaScript和XML),但是它不是像HTML、JavaScript或CSS这样的一种“正式的”技术,它是表示一些技术的混合交互的一个术语(JavaScript、Web浏览器和Web服务器),它使我们可以获取和显示新的内容而不必载入一个新的Web页面。增强用户体验,更有桌面程序的感觉。

同步和异步概念分析

  • 生活中同步与异步
    • 买水例子:
      • 同步:
        • 上课—->暂停—–>买水—–>继续
      • 异步:
        • 我上课—->我继续上课
        • 找一个人去买 ,买完以后送来
  • 浏览器与服务器交互的同步与异步
    • 异步:指某段程序执行时不会阻塞其它程序执行,其表现形式为程序的执行顺序不依赖程序本身的书写顺序,相反则为同步。
    • XMLHttpRequest可以以异步方式的处理程序

XMLHttpRequest

  • 浏览器内建对象,用于在后台与服务器通信(交换数据) ,由此我们便可实现对网页的部分更新,而不是刷新整个页面。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 1、创建XMLHttpRequest对象
    var xhr = new XMLHttpRequest();
    // 2、设置参数
    xhr.open('get','./index.php',true);
    // 3、指定回调函数
    xhr.onreadystatechange = function(){
    //5、判断响应
    if(xhr.readyState == 4){
    if(xhr.status == 200){
    // 获取响应数据
    var data = xhr.responseText;
    var info = document.getElementById('info');
    if(data == '1'){
    info.innerHTML = '成功';
    }else if(data == '2'){
    info.innerHTML = '失败';
    }
    }
    }
    }
    // 4、发送请求
    xhr.send(null);
  • 步骤:

    • 1.0 创建对象

      1
      var xhr = new XMLHttpRequest();
    • 2.0 设置参数

      1
      2
      3
      4
      //get 请求
      xhr.open('get','./index.php',true);
      //post 请求
      xhr.open('post','./index.php',true);
      • 参数传递:
        • get:直接放在url后面即可
        • post:通过send方法来传递
    • 3.0 设置回调函数

      1
      xhr.onreadystatechange = function(){}
      • onreadystatechange为 readstate 属性状态改变时执行
      • readstate 属性有五个状态:
        • xhr.readyState = 0时,(未初始化)还没有调用send()方法
        • xhr.readyState = 1时,(载入)已调用send()方法,正在发送请求
        • xhr.readyState = 2时,(载入完成)send()方法执行完成,已经接收到全部响应内容
        • xhr.readyState = 3时,(交互)正在解析响应内容
        • xhr.readyState = 4时,(完成)响应内容解析完成,可以在客户端调用了
        • 了解即可
    • 4.0 发送请求

      1
      xhr.send(null);
      • post方式时,可以在send后面带参数

      • 参数形式:key1=value1&key2=value2;

      • 如果要后台接收到,还必须加上:

        1
        2
        //post请求时如果要传递参数需要带上
        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    • 5.0 判断响应

      • 当响应状态为200时,才需要执行回调函数

案例

  • 登录验证功能

JSON

  • 即 JavaScript Object Notation,另一种轻量级的文本数据交换格式,独立于语言。

  • 它是javascript对象的一种字符串的表现形式

    1
    2
    3
    4
    //表示对象
    {"name":"jack","age":"18","gender":"男"}
    //表示数组
    [{"name":"jack","age":"18","gender":"男"},{"name":"rose","age":"18","gender":"女"}]
  • 语法规则

    • 1、数据在键/值对中
    • 2、数据由逗号分隔(最后一个健/值对不能带逗号)
    • 3、花括号保存对象方括号保存数组
    • 4、使用双引号
    • 5、在json里面不能写注释
  • JSON解析

    • JSON数据在不同语言进行传输时,类型为字符串,不同的语言各自也都对应有解析方法,需要解析完成后才能读取

    • Javascript 解析方法

      • eval()

        • 如果转换JSON数组的字符串可以直接转换

          1
          2
          var a  = "[1,2,3,4,5]";
          eval(a)

        • 如果将JSON对象的字符串转为对象,注意,需要将对象首尾加上“()”,才能转换成功,否则eval会将大括号识别为JavaScript代码块的开始和结束标记

          1
          2
          var json='{"name":"CJ","age":18}';
          eval("("+json+")")//即可将json对象的字符串转为对象
        • eval可以解析并执行js代码:

          1
          eval('alert("abc");');
      • JSON对象

        • JSON.parse():将JSON格式的字符串转为JSON对象
        • JSON.stringify():将JSON对象转为JSON格式的字符串
    • PHP解析方法

      • json_encode():将对象转为JSON格式的字符串
      • json_decode():将JSON格式的字符串转为对象
        • 转为对象的类型是 stdClass,这类似于一个没有名字的类型,将来将字符串转换以后会得到这个类型的对象,可以通过这个对象最出其中的属性。
  • 总结:JSON体积小、解析方便且高效,在实际开发成为首选。

函数封装

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
function ajax(url,type,param,dataType,callback){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');//兼容IE6以下版本
}
if(type == 'get'){
url += "?" + param;
}
xhr.open(type,url,true);

var data = null;
if(type == 'post'){
data = param;
//如果请求方式为post则需要给其设置一个请求头部
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
}
xhr.send(data);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var data = xhr.responseText;
if(dataType == 'json'){
data = JSON.parse(data);
}
callback(data);
}
}
}

jQuery的Ajax相关api

  • $.ajax()
  • $.get()
  • $.post()
  • $.load()
  • $.serialize()

同源与跨域

  • 基本概念
    • 同源策略是浏览器的一种安全策略,所谓同源指的是请求URL地址中的协议、域名和端口都相同,只要其中之一不相同就是跨域
    • 同源策略主要为了保证浏览器的安全性
    • 在同源策略下,浏览器不允许Ajax跨域获取服务器数据
  • 下列地址是否与该地址同源http://www.example.com/detail.html
URL描述
http://api.example.com/detail.html域名不同
https://www.example.com/detail.html协议不同
http://www.example.com:8080/detail.html端口不同
http://api.example.com:8080/detail.html域名、端口不同
https://api.example.com/detail.html协议、域名不同
https://www.example.com:8080/detail.html端口、协议不同
  • 跨域访问会受到限制:
    • 不允许XMLHttpRequest(Ajax)请求

跨域解决方案

  • 解决方案概述
  • jsonp原理分析
1
2
3
4
5
6
7
function hello(data){
console.log(data);
}
var script = document.createElement('script');
script.src = 'http://tom.com/data.php?_cb=hello&username=zhangsan&password=123';
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
  • 实现jsonp后台接口
    • 回调函数名称获取
    • 返回数据格式分析

JSONP

  • JSON with Padding

原理剖析

  • 其本质是利用了标签具有可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成。

    • 文件后缀并不能代表什么,关建我们要看服务器返回的内容,比如css.php

      • 这时返回的内容为 echo ‘body {background:color}’我们可以通过content-type:text/css来指定浏览器该如何解析,返回的内容

        1
        2
        3
        4
        5
        <?php
        header('Content-Type: text/css; charset=utf-8');
        $color = $_GET['color'];
        echo 'body {background: ' . $color . '}';
        ?>
  • 同样我们也可以js文件以.php结尾,比如js.php 这时我们可以指定Content-Type: text/javascript可告知浏览器要以javascript来执行我们返回的内容,如果返回的是一个javascript的一个函数调用,那么在这个函数调用过程中可以将跨域请求来的数据以“实参”的传递过来,并且这个实参一般是JSON格式的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    $arr = array(
    "name"=>"itcast",
    "age"=>10
    );
    $json = json_encode($arr);
    $callback = $_GET['callback']; // jsonp
    echo $callback . '(' . $json . ')';
    ?>

  • 结合html标签src具有跨域访问的特性和Content-Type指定文档类型两个方面,可以实现跨域的数据访问。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    header('Content-Type: text/javascript; charset=utf-8');
    $callback = $_GET['callback'];
    $arr = array(
    "name"=>"itcast",
    "age"=>10
    );
    $json = json_encode($arr);
    echo $callback . '(' . $json . ')'; // fn({"name": "itcast", "age": 10})
    ?>

  • JSONP其本质就是服务端返回了一个Javascript的一个函数调用,而这个函数已经提前被定义了。

]]>
Ajax
网站favicon图标查看、制作及使用方法总结 /2017/07/08/%E7%BD%91%E7%AB%99favicon%E5%9B%BE%E6%A0%87%E6%9F%A5%E7%9C%8B%E3%80%81%E5%88%B6%E4%BD%9C%E5%8F%8A%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E6%80%BB%E7%BB%93/ #目录
[TOC]

###favicon图标介绍:

收藏夹图标就是出现在浏览器地址栏左侧的那个小图标。收藏夹图标,也作网站头像。当然,这不仅仅是收藏夹图标的全部,根据浏览器的不同,收藏夹图标显示也有所区别:在大多数主流浏览器如FireFox和Internet Explorer (5.5及以上版本)中,收藏夹图标不仅在收藏夹中显示,还会同时出现在地址栏上,这时用户可以拖曳收藏夹图标到桌面以建立到网站的快捷方式;除此之外,标签式浏览器甚至还有不少扩展的功能,如FireFox甚至支持动画格式的收藏夹图标等

###favicon查看方法
已知网站的地址的时候,一般favicon都是放在网站的根目录,所以直接在网站的根目录下输入 网址/favicon.ico 即可查看该网站的favicon图标,如下图:
favicon的查看方法

###网站 favicon icon制作方法

关于网站icon图标制作,个人比较喜欢在线的favicon icon图标制作网站—-比特虫,使用方法里面写的很详细,如下图:
比特虫官网

###favicon icon图标使用方法
当成功生成favicon.ico图像文件后,浏览器会自动弹出一个zip的压缩文件将压缩文件中的favicon.ico图像放在根目录下(也可以是其他目录)
在页面源文件的标签之间引入,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/index.css" />
<link rel="shortcut icon" href="/favicon.ico" />
<!-- Shortcut Icon 就是在网址列/标题前面出现的Icon -->
</head>
<body>

</body>
</html>

]]>
PHP基础语法之文件操作 /2017/06/12/PHP%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95%E4%B9%8B%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/ PHP文件操作
  • fopen: 打开文件或者 URL

    1
    resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )

  • fclose: 关闭一个已打开的文件指针

    1
    bool fclose ( resource $handle )
  • fread: 读取文件(可安全用于二进制文件)

    1
    string fread ( resource $handle , int $length )
  • fwrite: 写入文件(可安全用于二进制文件)

    1
    int fwrite ( resource $handle , string $string [, int $length ] )
  • file: 把整个文件读入一个数组中

    1
    array file ( string $filename [, int $flags = 0 [, resource $context ]] )
  • file_get_contents: 将整个文件读入一个字符串

    1
    string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )
  • file_put_contents: 将一个字符串写入文件

    1
    int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
]]>
php
PHP进阶 /2017/06/10/PHP%E8%BF%9B%E9%98%B6/ [TOC]

变量作用域

  • 分类
    • 全局作用域:全局变量的作用范围。在函数外部定义的变量,都是全局变量。网页执行完毕,全局变量就消失了。
    • 局部作用域:局部变量的作用范围。在函数内部定义的变量,就是局部变量。函数执行完毕,局部变量就消失了。
    • 超全局变量:在网页的任何地方(函数内、函数外),都能使用的变量
  • 与JS的区别
    • 在JS中,全局变量可以直接在函数内部来使用;但是,在PHP中,全局变量不能直接在函数内部使用。
    • 在PHP中,函数内和函数外是不通的。

在局部作用域中访问全局变量

  • global 关键字

    • PHP中全局变量,不能直接在函数中使用;

    • 使用global关键字,来实现:将全局变量引入到函数中来用。

    • global在声明为全局变量,不能直接赋值,需要在下一行来赋值;

    • global关键字只能在函数内部来使用。

    • global关键字与JS中的全局变量的功能不一样,可以理解为”引用传值地址”

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      <?php
      header("content-type:text/html;charset=utf-8");
      $name = "jack";
      $age = 18;
      function showInfo(){
      global $name;
      global $age;
      $age = 30;
      echo "我的名字叫做{$name},今年{$age}岁了---函数内";
      }
      showInfo();

      function show2() {
      global $name;
      global $age;
      echo "我的名字叫做{$name},今年{$age}岁了---函数内";
      }
      echo "<hr/>";
      show2();

      echo "<hr/>";
      echo "我的名字叫做{$name},今年{$age}岁了---函数外";
      ?>

$GLOBALS超全局数组变量

  • 超全局数组变量:\$_GET、\$_POST、\$_SERVER、\$_REQUEST、\$_FILES、$_COOKIE、\$_SESSION、\$GLOBALS

  • 超全局数组变量,可以在网页的任何地方都能使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    header("content-type:text/html;charset=utf-8");
    $name = "jack";
    $age = 18;

    function showInfo(){
    $name1 = $GLOBALS['name'];
    $age1 = $GLOBALS['age'];
    echo "我的名字叫做{$name1},今年{$age1}岁了---函数内";
    }
    showInfo();

PHP中的构造函数—–类(class)

概念:

  • 在编程中有一种思想:万物皆对象(实实在在存在一个事物)
  • 在编程中描述事物的一种方式:
    • 比如说:要得到一个鼠标类—>先创建一个鼠标类—>再向类中添加鼠标的特征—>
      • 重量
      • 价格
      • 颜色
      • 型号
      • 大小
      • ….
  • php中为了方便管理对象,会将对象抽象成为一个类似于JS中构造函数的结构—>类

定义与使用

  • 关键字:class
1
2
3
4
5
6
7
<?php
class P {
public $id;
public $name;
public $age;
}
?>
  • 创建类的对象
1
$p = new P();
  • 给对象中的属性赋值
1
2
3
$p->id = 12;
$p->name = "jack";
$p->age = 19;
  • 取值
1
echo $p->age;

PHP服务器端包含

  • include:包含文件,当包含的文件不存在,会报警告,脚本会继承执行;
  • require:包含文件,当包含的文件不存在,会报错误,脚本立即停止执行;
  • include_once:包含文件一次,如果第2次包含不再执行,相当于if判断。其它情况与include一样。
  • require_once:包含文件一次,如果第2次包含不再执行,其它情况下require一样。

HTTP协议

B/S网络结构

  • B/S,Brower/Server(浏览器/服务器),是当前最流行的网络模式,将所有的功能放在服务器上,客户端只需要一个浏览器软件即可。
  • C/S,Client/Server(客户端/服务器),在这种模式下,客户端电脑必须要安装相应的客户端软件。如:QQ聊天、MySQL客户端/MySQL服务器。
  • 静态网页和动态网页:文件代码中,是否含有服务器端的脚本语言。如:PHP、Java、ASP、JSP、C#。

HTTP协议

  • HTTP,HyperText Transfer Protocol,超文本传输协议,是一种网络数据的传递标准。
  • HTTP也是请求和响应的一种标准

HTTP协议之URL

  • URL概念:
    • Uniform Resource Locator统一资源定位符,
    • 统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
    • 互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
  • URL的构成
  • 报文

    • 请求报文

      • 请求报文头

        • 请求方式 请求的url 协议版本
        1
        GET http://www.a.com/ HTTP/1.1
      • 请求报文行

        1
        2
        3
        4
        5
        6
        7
        Host: www.a.com
        Connection: keep-alive
        Upgrade-Insecure-Requests: 1
        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
        Accept-Encoding: gzip, deflate
        Accept-Language: zh-CN,zh;q=0.8
      • 固定换行

        • 换行 中没有内容,只是用来隔开请求报文行与请求报文体的
      • 请求报文体

        • 一般为空
    • 响应报文

      • 响应报文头

        1
        HTTP/1.1 200 OK
      • 响应报文行

        1
        2
        3
        4
        5
        6
        Date: Mon, 18 Sep 2017 20:34:21 GMT
        Server: Apache/2.2.22 (Win32) PHP/5.3.13
        Content-Length: 427
        Keep-Alive: timeout=5, max=100
        Connection: Keep-Alive
        Content-Type: text/html;charset=UTF-8
      • 固定换行

        • 隔开响应报文行和响应报文体
      • 响应报文体

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
        <head>
        <title>Index of /</title>
        </head>
        <body>
        <h1>Index of /</h1>
        <ul><li><a href="01array.php"> 01array.php</a></li>
        <li><a href="02abc.php"> 02abc.php</a></li>
        <li><a href="03.php"> 03.php</a></li>
        <li><a href="1122.php"> 1122.php</a></li>
        <li><a href="a.php"> a.php</a></li>
        <li><a href="%e5%89%af%e6%9c%ac.php"> 副本.php</a></li>
        </ul>
        </body></html>
  • 报文查看工具:fiddler

HTTP请求方式及PHP中参数的接收方式:

请求方式

  • get

    • 特点:

      • 将参数放到URL中传递到服务器,
      • 一般用来从服务器中得到数据
      • 数据量有限
      • 数据不安全
    • 方式:

      • 在URL中直接输出参数
      • 通过a链接请求传递参数
      • 通过js方式传递参数
      • 通过表单的get提交参数
      • ajax的get请求方式
    • PHP中的接收方式:

      1
      2
      3
      $name = $_GET['name'];
      $age = $_GET['age'];
      echo "{$name},{$age}";
  • post

    • 特点:

      • 将参数放到请求报文体中传递到服务器,
      • 一般用来提交数据到服务器中
      • 传递数据量相比get要大
      • 数据相对get而言安全
    • 方式:

      • 表单的POST提交
      • ajax的post请求方式
    • PHP中的接收方式

      1
      2
      3
      $name = $_POST['name'];
      $age = $_POST['age'];
      echo "{$name},{$age}";
  • $_REQUEST:

    • 作用:既可以接收GET传递的参数,又可以接收POST传递的参数
    1
    2
    3
    $name = $_REQUEST['name'];
    $age = $_REQUEST['age'];
    echo "{$name},{$age}";
]]>
php
JavaScript中清空数组的三种方式 /2017/06/08/JavaScript%E4%B8%AD%E6%B8%85%E7%A9%BA%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E5%BC%8F/ 方式1、splice

详细说明:http://www.w3school.com.cn/jsref/jsref_splice.asp

方式2、length赋值为0

这种方式很有意思,其它语言如Java,其数组的length是只读的,不能被赋值。如

Java中会报错,编译通不过。而JS中则可以,且将数组清空了,

目前 Prototype中数组的 clear 和mootools库中数组的 empty 使用这种方式清空数组。

方式3、赋值为[]

这里其实并不能说是严格意义的清空数组,只是将ary重新赋值为空数组,之前的数组如果没有引用在指向它将等待垃圾回收。

Ext库Ext.CompositeElementLite类的 clear 使用这种方式清空。
方式2 保留了数组其它属性,方式3 则未保留。很多人认为方式2的效率很高些,因为仅仅是给length重新赋值了,而方式3则重新建立个对象。经 测试 恰恰是方式3的效率高。测试代码:

测试结果:

img

以上结果可看到:方式3更快,效率更高。因此如果不保留原数组的其它属性Ext采用的方式更值得推荐。

原文:http://www.cnblogs.com/snandy/archive/2011/04/04/2005156.html

原文链接:https://www.cnblogs.com/xcsn/p/4938519.html

]]>
转载
PHP基础语法 /2017/06/02/PHP%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95/ [TOC]

前瞻知识点

  • B/S结构的处理流程
  • 网络基本概念
    • IP
    • 域名
    • DNS
      • 网络DNS
      • 本地DNS
    • 端口
  • 安装WAMP环境
    • W – web, A – Apache , M – MySql ,P – PHP

hello world

  • 所有PHP代码都放在标记: <?php …… ?>

  • PHP输出方式:echo

    1
    echo 'hello world'
  • 注释

    • / 多行注释 /
      • 多行注释不要嵌套
    • // 单行注释
  • 语句分隔符 “;”

  • PHP文件访问方式

PHP简介

  • PHP Hypertext Preprocessor 超文本预处理器,是嵌入到HTML文件中的服务器端的脚本语言;
  • 一个PHP文件中,可以包含多种代码:HTML、CSS、JS、Jquery、PHP、MySQL等
  • PHP的语法,与C、Java、Python、JS语法比较相似;
  • PHP是服务器端的脚本语言,脚本语言相对编程语言来说,要简单的多。
  • PHP程序只能运行在服务器端,在客户端看不见PHP任何代码;
  • PHP文件的扩展名是以.php为后缀的。

语言基础

  • PHP与ASP、JSP一样,都是嵌入到HTML文件中的服务器端的脚本语言;
  • PHP文件的后缀是.php
  • PHP代码的标记:<?php …… ?>
  • PHP中每行程序代码,必须以英文下的分号结束;

输出时间

1
echo date('Y-m-d H:i:s');
  • 默认情况下PHP输出的时间是格林威治时间,比中国时区晚8个小时

  • 解决方案:

    • 1.0 找到PHP的配置文件 php.ini

    • 2.0 定位到 date.timezone

    • 3.0 设置中国时区

      1
      2
      ; PRC为中华人民共和国
      date.timezone = PRC

变量

特点

  • 变量是临时存储数据的容器;
  • 变量是存储在内存当中;
  • 网页执行完毕后,网页中相关的变量全部消失。

变量命名规则

  • 变量名称只能包含:字母、数字、下划线
  • PHP中的变量名必须以 “\$” 符号开头,但是”\$”符号不属于变量的一部分,将来不管是赋值还是取值,都必须加上”\$”
  • 变量名区分大小写
  • PHP中的变量使用不需要声明,直接赋值使用
  • 常用的两种命名方法:
    • 驼峰命名法
      • 第一个单词的首字母小写,其余单词的首字母全部大写
      • 如:userName,userId
    • 帕斯卡命名法:
      • 与驼峰命名法很像
      • 唯一区别是它的首字母是大写
      • 如:UserName,UserId
    • 下划线命名法
      • 所以的单词首字都小写,由下划线连接
      • 如:user_name,user_id

变量的声明与赋值

  • 声明
    • PHP中变量不需要声明,但是每个变量必须以$开
  • 赋值:
    • 直接给带有$的变量赋值
    • 使用“=”,赋值运算符给变量赋值,“=”读作赋值运算符
    • 赋值运算符的左边只能是一个变量名
    • 如:$userName = “张三”;

变量值的读取

  • 变量的数据类型由其中的内容决定

  • 直接以 “$+变量名”的方式 取得可以取得变量的值

    1
    $userName = "admin";
  • 可以使用“.”来连接将变量与字符串一起输出

    1
    echo "我的名字叫".$userName
  • 也可以在字符串的内部直接使用变量

    • 在PHP中“.”点表示相连
    • 在PHP中“+”加表示相加(是一种算术运算符)
    1
    2
    3
    4
    5
    6
    echo "我的名字叫做$userName"
    但是,如果用引号时,变量后面还有其它的有文字,就不能解析了如
    echo "我的名字叫做$userName很高兴见到大家"
    这里就无法解析,需要在变量后面添加一个非空特殊字符,如:
    echo "我的名字叫做{$userNmae}很高兴见到大家"
    如果输出字符是单引号,则无法解析字符串

变量相关函数

  • header():设置服务器返回到浏览器的数据的类型

    1
    header('content-type:text/html;charset=utf-8');
  • isset() 判断变量是否存在

    • 可以用来判断变量是否定义,或者是否为null
  • empty() 判断变量是否为空

    • 如果 var 是非空或非零的值,则 empty() 返回 FALSE
    • “”0“0”NULLFALSEarray()var $var; 以及没有任何属性的对象都将被认为是空的,也就意味着,如果上述的数据用empty来判断返回的结果都为true
  • unset() 删除变量

    • 可以通过这个函数删除一个已经存在的变量,删除之后变量为null

    • 可以同步删除多个变量

    • 如果在函数中 unset() 一个全局变量,则只是局部变量被销毁,而在调用环境中的变量将保持调用 unset() 之前一样的值。(这个当我们学了全局变量与局部变量以后再说)

      1
      unset($a,$b,$c)
  • var_dump() 显示变量的类型和值

    • 可以同时打印多个变量
  • print_r() 显示数组的元素信息

    • 如果是字符串,数字,boolean值,会原样输出
    • 如果是数组,会详细打印数组信息

可变变量

  • 指一个变量的名称,由另一个变量的值来充当

    1
    2
    3
    4
    $a = "b";
    $b = "c";
    echo $b;//输出 c
    echo $$a;//输出 c
  • 如果使用可变变量,一定要加上给可变变量的变量名加上{}作为定界符

变量的值传递和引用传递

  • JS中的基本数据类型(只有一个值):字符串型、数值型、布尔型、undefined、null

  • JS中的复合数据类型(多个值):数组(Array)、对象(Object)、函数(Function)

  • 值传递:

    • 传递的是变量中保存的值
  • 引用传递

    • 传递的是变量保存的引用地址
  • 在PHP中可以使用 & 符号将值传递的变量改变为引用传递:如

    1
    2
    3
    4
    $a = "abc";
    $b = &$a;
    $a = "123";
    echo "$a<br/>$b"

常量

概念

  • 常量就是值永远不变的量,即:一旦赋值无法删除,修改。
  • 由于变量在使用时还需要去它存储的地址中去找到对应的数据,相比变量来说,常量的速度要快。

命名规则

  • 与变量基本一致
    • 变量名称只能包含:字母、数字、下划线,常量也是
    • PHP中的常量不需要使用$符号开头
    • 常量名区分大小写,一般建议使用时尽量用大写,为了与变量区分开
    • 常用的两种命名方法:
      • 驼峰命名法
        • 第一个单词的首字母小写,其余单词的首字母全部大写
        • 如:uerName,userId
      • 下划线命名法
        • 所以的单词首字都小写,由下划线连接
        • 如:user_name,user_id

常量定义define()

  • 语法: bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

  • 案子:通过define关键来定义

    1
    2
    3
    define('TITLE',"中华人民共和国");//定义常量TITLE
    define('TITLE',"中华人民共和国",true);//加上true,使用时既可以使用TITLE,又可以使用小写title,来使用常量
    define('TITLE',"中华人民共和国",false);//加上false,使用时必须使用TITLE

判断是否是常量:defined()

  • 语法: bool defined ( string $name )

  • defined()可以判断常量

    1
    defined(“TITLE”);//通过defined判断常量时,常量一定要加上引号

魔术常量

  • 量的值在程序运行过程中不会改变。但是,魔术常量的值,会随着所在位置的不同而改变。
  • 魔术常量都由系统定义好的,我们直接使用就好了,常用的有:
    • __LINE__:得到当前代码的行号
    • __FILE__:得到当前文件的路径
    • __DIR__:得到当前文件所在目录
    • __FUNCTION__:得到所在函数

数据类型

  • 数据类型分类

    1
    2
    3
    4
    5
    js中的数据类型:
    简单数据类型:
    Number,string,bool,undefined
    复杂数据类型
    数组,对象,null
    • 基本数据类型:字符串型(string)、整型(int)、浮点型(float:小数)、布尔型(bool)
    • 复合数据类型:数组、对象
    • 特殊数据类型:资源、NULL
  • 数据类型判断

    • is_bool(),判断变量是不是布尔型

    • is_int(),判断变量是不是整型

    • is_string() 判断变量是不是字符串型

    • is_float() 判断变量是不是浮点型

    • is_numeric() 判断变量不是数值型或数字字符串。

    • is_array() 判断变量是不是数组

    • is_null() 判断变量是否为NULL

    • is_resource() 判断变量是不是资源型

      1
      2
      3
      4
      5
      6
      7
      8
      9
      //判断用户是否大于18岁,如果大于18岁,显示网页内容,如果没有,则不显示
      $age = 20;
      if(isset($age) && is_numeric($age)) {
      if($age >18) {
      echo('显示网页');
      } else {
      echo ('不显示');
      }
      }

整型

  • 关键字:int
  • 在js中所有的数字都用number来表示,但是在PHP,数字有不同的划分,其中整数(正整数,0,负整数)用整型来表示

    • 整型包含正整数、负整数、零0

    • 可以用10进制、八进制、16进制表示

      1
      2
      3
      echo 100;//十进制
      echo 011;//八进制,以0开头的整数,结果为9
      echo 0x9a;//十六进制,以0x开头,结果为154
    • PHP中最大整数:PHP_INT_MAX,(2^31)-1

  • 如果数字超出来了整数据范围,则类型会变为float

浮点型

  • 关键字:float
  • PHP中除了整数还有浮点型,一般浮点数会包含小数,比整型更加精确

  • 浮点型的范围:1.8E-308~1.8E+308

  • 注意点:

    • 如果要对浮点数进行操作,就好先将浮点数转为整数再处理

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      //以下做法不可取
      if(2.1/0.7 == 3) {
      echo '相等';
      } else {
      echo '不相等';
      }
      //以下是正确做法
      $a = 2.1 * 10;
      $b = 0.7 * 10;
      if($a/$b == 3) {
      echo '相等';
      } else {
      echo '不相等';
      }

字符串

  • 字符串定义的四种方式

    • 用单引号可以定义一个字符串;如:$a = ‘abc’;

      • 单引号内无法解析变量
      • 转义符号有:\’
    • 用双引号来定义一个字符串;如:$a = “abc”;

      • 双引号内可以解析变量
      • 转义符号有:\\、\’、\”、\$、\r、\n、\t
    • 定义长字符串:heredoc

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <?php
      header('content-type:text/html;charset=utf-8');
      $a = 'abc';
      $aa = <<<heredoc
      <html>
      123$a
      </html>
      heredoc;
      echo $aa;
      ?>
      • 使用注意:
        • 1)字符串放在两个heredoc标签之间
        • 2)以“<<<heredoc”作为开始,不用带分号
        • 3)以“heredoc;”作为结束,要带分号
        • 4)标签名称可以自定义
        • 5)结束标签必须放单独一行
    • 定义长字符串:nowdoc

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <?php
      header('content-type:text/html;charset=utf-8');
      $a = 'abc';
      $aa = <<<'nowdoc'
      <html>
      123$a
      </html>
      nowdoc;
      echo $aa;
      ?>
      • 使用注意:
        • 与上述一样,但是开始的标签名必须加单引
        • 不能解析变量

布尔型

  • 关键字:bool
  • 概念
    • true表示真,flase表示假
  • 转换:
    • 0,””,NULL,0.0,”0”,arry() 空数组会转为false
    • 其它的数据都会转为true

空型

  • 用null表示,表示没有
  • 以下情况会出现NULL
    • 可以直接给一个变量,赋一个NULL值;
    • 未定义的变量的值,也是NULL;
    • unset()删除一个变量后,该变量的值为NULL。

数据类型转换

  • 概念

    • 数据有不同的类型,有时间操作数据时需要转换类型以后才能完成操作,比如计算
    • 类型的转换分为两种:自动转换(隐式转换)、手动转换(强制转换)
    • 大部分情况下数据是自动转换,少数情况下强制转换。
  • 强制转换

    • 通过关键字进行转换

      1
      2
      3
      4
      5
      6
      7
      8
      (bool)$a//强制转换为bool
      //除了0,0.0,”“,”0“,NULL,array(),转为false,其余都为true
      (int)$a//强制转换为int
      //转换会将小数去尾
      (string)$a//强制转换为string
      //null也可以转为‘’;
      (array)$a//强制转换为array
      (object)$a//强制转换为object
  • 进制转换

    • 进制就进位制,X进制,就是逢X进一。同理:十进制就是逢十进一,二进制逢二进一等等。
    • 8进制:有8个基本数,分别为0、1、2、3、4、5、6、7,运算规则”逢8进1”;
    • 16进制:有16个基本数,分别为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,运算规则”逢16进1”。
    • 2进制:有2个基本数,分别是0、1,运算规则”逢2进1”。
    • 转换方法:
      • decbin()将十进制转换为2进制
      • bindec()将2进制转换为十进制
      • decoct()将十进制转换为8进制
      • octdec()将八进制转换为10进制
      • dechex()将十进制转换为16进制
      • hexdec()将16进制转换为十进制

运算符

  • 算数运算符+、-、*、/、%、++、–

  • 赋值运算符=、+=、-=、*=、/=、%=

  • 字符串运算符. 和 .=

    • 案例:隔行变色

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      <?php
      header('content-type:text/html;charset=utf-8');

      $str = "<table width='500' border='1' align='center'>";
      $str .= "<tr bgColor='#f0f0f'>";
      $str .= " <th>编号</th>";
      $str .= " <th>新闻编号</th>";
      $str .= " <th>发布时间</th>";
      $str .= "</tr>";
      for($i = 0 ; $i < 10 ; $i ++) {
      if($i % 2 == 0) {
      $str .= "<tr bgColor='#f0f0f'>";
      } else {
      $str .= "<tr>";
      }
      $str .= "<td>$i</td>";
      $str .= "<td>&nbsp;</td>";
      $str .= "<td>&nbsp;</td>";
      $str .= "</tr>";
      }
      $str .= "</table>";
      echo $str;
      ?>
  • 比较运算符>、<、>=、<=、\=\=、!=、\=\=\=、!==

    • 案例:字符串比较

    • ASCII码表:如果两个字符进行比较,比较的本质是它们对应的ASCII码

      1
      echo ("a" > 120);
  • 逻辑运算符&&、||、!

    • 实例:闰年判断

      1
      2
      3
      4
      5
      6
      7
      8
      9
      //条件:
      //1)能够被4整除,且不能被100整除
      //2)能被400整除
      $year = 2000;
      if ($year%4 == 0 && $year % 100 !=0 || $year % 400 ==0) {
      echo "{$year}是闰年";
      } else {
      echo "{$year}不是闰年";
      }
  • 运算符优先级

  • 三元运算符

    • 案例:比较两个数的大小

      1
      2
      3
      $a = 123;
      $b = 456;
      $max = $a > $b ? $a : $b;
  • 错误控制运算符(@)

    • 作用:主要用来屏蔽表达式的错误:

    • 可以用在变量、常量、函数调用之前,但是不能用在函数定义、类定义之前。

      1
      2
      3
      $a = 100;
      $b = 0;
      echo @($a / $b);

流程控制

  • 顺序结构

    • 赋值语句

      1
      $a = 123;
  • 分支结构

    • 分支结构(if)
    • 多条件判断(if else if else)
      • 案例:根据分数给评语。
    • 多分支结构(switch)
      • 案例:完成今天星期几
  • 循环结构

    • while
    • do while
    • for
    • break和continue
    • 案例:
      • 1)得到1~100的所有整数相加之和
      • 2)输出100~1000以内所有水仙花数
      • 3)输出九九乘法表

数组

概念

  • 数组是一组数的集合。如:$arr = array(1,2,3,4,5,6);

PHP中数组的分类

  • 枚举数组
    • 数组元素的下标(索引),是从0开始的正整数,如:$arr = array(1,2,3,4,5,6);
  • 关联数组:
    • 数组元素的下标,是一个字符串。如:$arr[‘edu’] = ‘大专’
    • 关联数组无法通过数字下标取得对应的元素
  • 混合数组:
    • 两种下标都有的数组,就是混合数组。如:$arr = array(100, ‘edu’=>’大专’ , ‘tel’ => ‘130110’)
  • 多维数组:
    • 数组元素的值,是一个数组,还可以理解为:数组嵌套数组。如:$arr[5][2] = 100

数组的创建

  • 使用 array() 函数来创建数组

    • 创建枚举数组:

      • 下标是从0 开始的正整数

      • 1
        $arr = array($value1,$value2,$value3,....);
  • 创建关联数组

    • $key是重新给数组元素指定一个下标

    • 下标和元素的值之间连接号是”=>”,又称”重载元素下标”

      1
      $arr = array([$key=>]$value,[$key=>]$value,[$key=>]$value,....)
  • 创建混合数组

    • 有字符串下标的元素,就没有整型下标

    • 如果$key省略了,就用默认下标

    • 下标只能是整型以及字符串

    • 如果元素没有指定下标,会在最大整数下标的基础上加1.

      1
      $arr[] = $value
      • 如果$arr数组不存在的话,会先创建数组,并添加第1个数组元素,第1个元素的下标为0
      • 如果$arr已经存在 的话,添加新的数组元素,新的数组元素的下标,是最大整数下标+1
    • 创建混合数组:

      • 由语法1,2混合创建数组

        1
        2
        3
        4
        5
        6
        $arr[] = 12;
        $arr[] = 13;
        $arr["a"] =14;
        $arr[] = 15;
        $arr[20] = 16;
        $arr[] = 19;

多维数组

  • 多维数组,即数组中的元素又是一个数组

    1
    2
    3
    4
    5
    6
    $arr = array(
    array(1,2,3,4),
    array(10,20,30,40),
    array('a','b','c'),
    "abc"
    );

数组中的函数

  • count()
    • 计算数组中的单元数目或对象中的属性个数
    • 语法:int count ( mixed $var [,\$mode = COUNT_NORMAL ] )
    • 参数:
      • $var 是对象或者数组
      • $model: 如果可选的 mode 参数设为 COUNT_RECURSIVE(或 1),count() 将递归地对数组计数。对计算多维数组的所有单元尤其有用。mode 的默认值是 0。count()识别不了无限递归
  • unset()
    • 删除变量或数组元素
    • 语法:void unset ( mixed $var [, mixed $… ] )
    • 删除元素后,仅仅只是相当于将数据从数组中移除掉了,对数组的下标没有影响

数组的遍历

  • 使用for加next()遍历数组
1
2
3
4
for($i = 0; $i < count($arr); $i++) {
echo key($arr).current($arr)."<br/>"
next($arr);
}
  • key():当前指针处元素的键名(下标),不会移动指针
  • current():返回当前指针处元素的值,不会移动指针
  • next(): 返回下一个元素的值,指针移动到下一个元素的开头

PHP中的数组传值时为值传递

1
2
3
4
$arr = array(1,2,3,4);
$arr1 = $arr;
$arr1[0] = 100;
echo $arr[0];//1

函数

概念

  • 函数是一段命名的代码段
  • 封装一代码,将来要执行时可以直接调用

定义函数的方式

1
2
3
4
5
6
7
8
9
10
11
/*
function 定义函数的关键字
functionName 函数的名称
arguments 形参列表
retValue 返回值
fnCode 功能代码
*/
function functionName(arguments){
// fnCode
return retValue;
}
  • function: 定义函数的关键字,不区分大小写
  • functionName:函数名称,命名规则与变量一样,只是不需要加$符号
  • 小括号():主要用来接受传递过来的参数
  • arguments:定义函数时的参数,形参
  • return 函数的返回值。

函数的调用:

  • 实参:调用函数时,传递的参数就是实参,含有真正数据的
  • 形参:定义函数时的参数
  • 案例:得到数组中所有数组的和

函数参数的传递:

  • 值传递
    • 函数参数的值传递,就是将参数的值,复制一份,传到函数中
    • 值传递速度比较慢,但修改其中一个不会影响到另一个;
  • 引用传递
    • 引用传递速度比较快,但修改其中一个,另一个也会改变。
    • 引用传递,是将一个变量的地址,复制一份,传到函数中
  • 默认参数
    • 函数中有些参数可能是固定不变的,为了操作方便,可以用默认参数来代替
    • 默认参数必须放在非默认参数的右边
    • 默认参数的值,只能是:字符串、整型、浮点型、布尔型、NULL、数组
1
2
3
function showSelf($name,$age=19,$gender="男") {
echo "我叫{$name},今天{$age},性别{$ender}";
}

函数可变数量参数

  • func_get_args( void ):返回一个参数列表的枚举数组,参数数组的下标是从0开始的整数

  • func_get_arg( $index ):返回参数数组中,指定下标的参数的值;

  • func_num_args( void ):返回实参的个数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function getSum() {
    $arr = func_get_args();
    $len = func_num_args();
    $sum = 0;
    print_r($arr);
    echo "<br/>";
    print_r($len);
    echo "<br/>";
    for($i = 0; $i < $len; $i++) {
    $sum += func_get_arg($i);
    }
    echo "$sum";
    }
    getSum(1,2,3,4,5);

函数的返回值

  • 函数的返回值,通过return语句来实现;
  • 将函数的执行结果,返给了函数调用者;
  • return语句一旦执行,函数立即结束,函数剩余的代码不再执行了。
  • return语句有”中断”函数、”退出”函数;
  • return不能同时返回多个值,只能返回一个值。如果想返回多个值,可以放入数组

常用系统函数

字符串

  • 定义字符串基本语法
    • 单引号字符串
    • 双引号字符串
    • nowdoc字符串
    • heredoc字符串
  • 字符串常用api
    • strlen() 获取字符串长度
    • substr() 返回字符串的子串
    • strtoupper() 将字符串转化为大写
    • strtolower() 将字符串转化为小写
    • ucfirst() 将字符串的首字母转换为大写
    • trim() 去除字符串首尾处的空白字符
    • ltrim() 删除字符串开头的空白字符
    • rtrim() 删除字符串末端的空白字符
    • strrev() 反转字符串
    • strpos() 查找字符串首次出现的位置,从左往右查找
    • strrpos() 计算指定字符串在目标字符串中最后一次出现的位置,从右往左查找
    • strchr()和strstr() 两者一样,用于查找字符串的首次出现
    • str_replace() 子字符串替换
    • str_repeat() 重复一个字符串

数学

  • 常用函数
    • max() 求最大值
    • min() 求最小值
    • rand() 产生一个随机整数
    • mt_rand() 更高效的随机数
    • ceil() 进一法取整
    • floor() 舍去法取整
    • round() 对浮点数进行四舍五入
    • pow() 次方运算
    • abs() 求绝对值
    • sqrt() 开方运算

日期

  • 常用函数
    • time() 返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数
    • date() 格式化一个本地时间/日期
    • microtime() 返回当前 Unix 时间戳和微秒数
    • strtotime() 将任何英文文本的日期时间描述解析为 Unix 时间戳
]]>
php
关于php的大文件上传POST超过最大限制报错问题 /2017/05/08/%E5%85%B3%E4%BA%8Ephp%E7%9A%84%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0POST%E8%B6%85%E8%BF%87%E6%9C%80%E5%A4%A7%E9%99%90%E5%88%B6%E6%8A%A5%E9%94%99%E9%97%AE%E9%A2%98/ 在学php的时候,做了一个简单的上传文件的demo,在上传大文件的时候发现报如下的错:
这里写图片描述

大概的意思就是:你所上传的文件大小超过了POST的最大限制大小(8M),
以下是有道翻译的结果警告:POST content -
length为2110919154字节,超过了第0行未知的8388608字节的限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

####**这是demo的代码**
```js
<?php

if(!empty($_FILES)){
$file = $_FILES["img-file"];
move_uploaded_file($file["tmp_name"],"./res/".$file["name"]);//将文件流从临时存储的位置移到指定的路径
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="./file_upload.php" method="post" enctype="multipart/form-data" >
<input type="file" name="img-file" id=""><br>
<input type="submit" value="上传">
</form>
</body>
</html>

###以上代码就是实现一个简单的上传功能,图片如下:
文件上传

###解决方法:

  • php.ini配置文件中的默认文件上传大小为2M, 默认upload_max_filesize =
    2M,即文件上传的大小为2M,如果你想上传超过8M的文件,比如20M,你必须设定upload_max_filesize =
    20M。但是光设置upload_max_filesize =
    20M还是无法实现大文件的上传功能,你必须修改php.ini配置文件中的post_max_size选项,其代表允许POST的数据最大字节长度,默认为8M。如果POST数据超出限制,那么$_POST和$_FILES将会为空。要上传大文件,你必须设定该选项值大于upload_max_filesize指令的值,我一般设定upload_max_filesize和post_max_size值相等。另外如果启用了内存限制,那么该值应当小于memory_limit选项的值。

 文件上传的其他注意事项

  • 在上传大文件时,你会有上传速度慢的感觉,当超过一定的时间,会报脚本执行超过30秒的错误,这是因为在php.ini配置文件中max_execution_time配置选项在作怪,其表示每个脚本最大允许执行时间(秒),0
    表示没有限制。你可以适当调整max_execution_time的值,不推荐设定为0。
]]>
php
浅谈测量javascript脚本程序执行消耗的时间 /2017/05/08/%E6%B5%85%E8%B0%88%E6%B5%8B%E9%87%8Fjavascript%E8%84%9A%E6%9C%AC%E7%A8%8B%E5%BA%8F%E6%89%A7%E8%A1%8C%E6%B6%88%E8%80%97%E7%9A%84%E6%97%B6%E9%97%B4/ 随着WEB应用越来越重要,JavaScript的执行性能也日益受到重视,WEB开发人员知道一些性能测试机器是必须的。接下来就简单介绍一下两种方法:

  • 方法一

console.time方法是开始计算时间,console.timeEnd是停止计时,输出脚本执行的时间,代码如下

1
2
3
4
5
6
7
8
9
// 启动计时器
console.time('testTime');//testTime为计时器的名称

// (写一些测试用代码)
for(i=0;i<1000;i++){
console.log("bobo"+i);
}
// 停止计时,输出时间
console.timeEnd('testTime');

输出结果如下图:
控制台输出结果

这两个方法中都可以传人一个参数,作为计时器的名称,它的作用是在代码并行运行时分清楚各个计时器。对console.timeEnd的调用会立即输出执行总共消耗的时间,单位是毫秒。

  • 方法二:

由于,js脚本是自上而下执行解析的,所以可以通过+new Date()或new
Date().getTime()来计算中间代码的执行时间,还是上代码来的直接:

这里写图片描述

代码执行结果如下图:

方法二执行结果图

或直接将其封装为函数如下:

测试js运行时间的函数

运行结果为同上
测试JavaScript性能的方法有很多,但console.time/timeEnd两个方法是最基本、最直接的技巧。

]]>
javascript javascript
回话技术之session与cookie /2017/04/18/%E4%BC%9A%E8%AF%9D%E6%8A%80%E6%9C%AF%E4%B9%8B%E4%B8%8Ecookie/ 会话技术
  • http无状态概述
  • 状态保持方式概述

cookie原理分析

  • 一个cookie的设置以及发送过程分为以下四步
    1. 客户端发送一个http请求到服务器端
    2. 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
    3. 客户端发送一个http请求到服务器端,其中包含Cookie头部
    4. 服务器端发送一个http响应到客户端

语法:

1
setcookie(name[, value, expire, path, domain]);

cookie常用属性

  • expires 有效期

    • 临时COOKIE(缓存cookie)

      1
      setcookie("uName","admin");
    • 硬盘COOKIE

      1
      2
      3
      4
      //一小时过期
      setcookie("uName","admin",time()+ 3600)
      //永久性COOKIE
      setcookie("password","123",PHP_INT_MAX);
  • path有效 路径

    1
    2
    //只有在upload文件夹下才能被访问到
    setcookie("uName","admin",time()+ 3600,"/upload")
  • domain 域名

    • 域名:
      • 顶级:baidu.com
      • 二级域名
    1
    2
    //只有在a.com以及它下面的子域名中才能被访问
    setcookie("uName","admin",time()+ 3600,"/","a.com")

删除cookie

  • 设置有效时间为过去时间

    1
    setcookie("uName","admin",time()-1);
  • 将cookie中的值设置为false或者空字符串

    1
    2
    3
    setcookie("uName",false);
    //或者
    setcookie("uName","");
  • 不设置值

    1
    setcookie("uName");
  • 在浏览器中清除缓存

服务器操作cookie

1
2
3
4
5
6
7
8
// 设置cookie
//
// 设置1小时后过期
setcookie("user", "lisi", time()+3600);
// 获取单个cookie
echo $_COOKIE["user"];
// 查看所有cookie
print_r($_COOKIE);

js对cookie基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 设置cookie
function setCookie(key,value,param){
document.cookie = key + '=' + value + '; expires=' + param.expires + '; path=' + param.path;
}
// 获取cookie
function getCookie(key){
var cookies = document.cookie;
var arr = cookies.split('; ');
if(arr){
for (var i = 0; i < arr.length; i++) {
var kv = arr[i].split('=');
if(kv[0] == key){
return kv[1];
}
}
}
}

cookie的缺点:

  • COOKIE数据不太安全;
  • COOKIE存储的数据类型,只能是字符串;
  • COOKIE文件是有容量限制(大约4KB)。4*1024b–> 1个文字大概是2~3b

session

session的优点:

  • SESSION也是一种会话技术;
  • SESSION数据存在服务器端,相对于比较安全;
  • SESSION技术是基于COOKIE的,没有COOKIE也就没有SESSION了。
  • 服务器将SESSION数据保存在服务器上,而将SESSION的用户id存储在客户端电脑上。
  • SESSION存储的数据类型,除了资源外的数据类型都可以;
  • SESSION文件没有大小限制;

session原理分析

  • 客户端第一次请求服务器时,服务器开启一个session,生成一个唯一标识(sessionid:存储的数据与此sessionid关联),并以响应头的Set-Cookie属性响应到客户端
  • 客户端的后续请求会一直通过请求头的Cookie属性携带sessionid(客户端与服务器通过此id维持状态)

session基本操作

  • 设置session
1
2
session_start();
$_SESSION['user'] = array('username'=>'lisi','age'=>'12');
  • 读取session
1
2
session_start();
$user = $_SESSION['user'];
  • 删除一个session信息
1
2
session_start();
unset($_SESSION['user']);
  • 删除所有session信息
1
2
session_start();
unset($_SESSION);
  • 销毁session
1
session_destroy();

session与cookie的关系

  • session可以借助cookie实现状态维持,也可以不依赖cookie(URL重写)
区别cookiesession
存储位置浏览器服务器
浏览器携带的数据量少(只携带session-id)
存储的数据类型只能是字符串任意类型
安全性较低较高
默认的有效路径当前路径及其子路径整站有效
数据的传输量有限制4K,不能超过20个无限制

session的回收时间:

  • session.gc_maxlifetime
1
session.gc_maxlifetime = 1440
]]>
session&cookie
为什么给html标签定义了id,就可以在js中(浏览器环境)直接通过id引用这个dom元素? /2017/04/16/%E4%B8%BA%E4%BB%80%E4%B9%88%E7%BB%99html%E6%A0%87%E7%AD%BE%E5%AE%9A%E4%B9%89%E4%BA%86id%EF%BC%8C%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%9C%A8js%E4%B8%AD%EF%BC%88%E6%B5%8F%E8%A7%88%E5%99%A8%E7%8E%AF%E5%A2%83%EF%BC%89%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87id%E5%BC%95%E7%94%A8%E8%BF%99%E4%B8%AAdom%E5%85%83%E7%B4%A0%EF%BC%9F/ ###问题

只要标签有id这个属性,不使用getElementById方法,也可以直接用id获取dom元素。

###解惑

经过一波搜索及查资料,原因大概是如果dom元素的id名称不和js内置属性或全局变量重名的话,该名称自动成为window对象的属性,所以可以直接用来操作dom。看网上的说法是,这个是IE首先支持,火狐谷歌后面才支持的。不过现在还未形成标准,为了保险,还是不用的好。不过看各大浏览器都支持,觉得也许以后这个有可能直接成标准也说不定哈,到时候又可以省几个代码0.

在各大浏览器中的测试结果如下:

  • chorme浏览器中
    这里写图片描述

    -firefox浏览器中
    这里写图片描述

  • ie浏览器中(仿真ie5版)
    这里写图片描述
]]>
i5ting/tocmd.npm将MD转换为HTML简单使用 /2017/03/08/i5ting-tocmd-npm%E5%B0%86MD%E8%BD%AC%E6%8D%A2%E4%B8%BAHTML%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8/ 模块链接

i5ting_toc

npm version

i5ting_toc a node npm wrapper of i5ting_ztree_toc https://github.com/i5ting/i5ting_ztree_toc

Preview

img

##全局安装

1
npm install -g i5ting_toc

##使用方法

全局安装完毕之后,直接在此处打开命令行,切换到你想要转换的md文件根目录下,使用以下命令,这个版本的命令比较简单,只有一个-f参数,如果没有填写,默认使用README.md

1
i5ting_toc -f sample.md -o

常见的命令参数如下:

-h, –help output usage information
-V, –version output the version number
-f, –file [filename] default is README.md
-o, –open open in browser
-v, –verbose 打印详细日志

运行成功之后则在当前目录下生成一个preview文件夹,里面就是我们想要的东东了
运行结果

注意: 如果md文件包含有图片资源的话,需要将图片资源的路径手动 copy进toc文件夹内

]]>
工具 模块工具
javascript中自执行(自调用)函数的两种写法 /2017/02/10/javascript%E4%B8%AD%E8%87%AA%E6%89%A7%E8%A1%8C%EF%BC%88%E8%87%AA%E8%B0%83%E7%94%A8%EF%BC%89%E5%87%BD%E6%95%B0%E7%9A%84%E4%B8%A4%E7%A7%8D%E5%86%99%E6%B3%95/
  • 自执行函数定义:
  • 自执行函数或是自调用函数 声明完了,马上进行调用,只能使用一次,,有两种写法,举个栗子如下:

    写法一:

    • 格式:(函数)(实参)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    (function (n1,n2){
    console.log("这是匿名函数的自执行的第一种写法,结果为:"+(n1+n2))
    })(10,100)//110

    (function start(n1,n2){
    console.log("这是函数声明方式的自执行的第一种写法,结果为:"+(n1+n2))
    })(10,100)//110
    </script>

    写法二:

    • 格式:(函数(实参))如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    (function (n1,n2){
    console.log("这是匿名函数的自执行的第二种写法,结果为:"+(n1+n2))
    }(10,100))//110

    (function start(n1,n2){
    console.log("这是函数声明方式的自执行的第二种写法,结果为:"+(n1+n2))
    }(10,100))//110
    </script>
    ]]>
    javascript Javascript
    javascript数据类型转换总结 /2017/01/20/javascript%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E6%80%BB%E7%BB%93/ ####数据类型分类

    • 复杂数据类型:对象类型
    • 简单(基本)数据类型:number string boolean null undefined

    ####数据类型转换分类

    • 隐式转换
    • 显式(强制)转换

    ####一.其他数据类型转number类型

    • 隐式转换
    1.0 . 隐式转换:只要是参与数学运算都会进行一个隐式类型转换  +   -   *  /  %1.1.  null对应number类型中的0,1.2. NaN 是属于number类型,表示数字的一种不正常状态,也就是说本来应该进行数学运算的值没有转换成number, js中特别的安排了一个这么一个NaN的值,有了这个值程序就不报错了1.3、NaN是属于number类型的一个值,代表数字的一种不正常状态,是非常特殊的,特殊到和任何值都不相等,即使自己也不相等,所以任何与NaN的数学运算,最最终的结果都是NaN

    • 显式转换:通过Number( )、ParseInt( )、ParseFloat( )
      Number( )

      特点:

      a.如果转换的内容可以转成数字,那么就直接返回这个内容对应的数字。b.如果不可以转换那么返回NaN.c.如果在内容中出现小数,那么小数会保留。d.如果内容为空,那么转换成0;
    1
    2
    3
    4
    5
    6
    7
    8
    如:
    var num1 = Number(true); //true返回1 false返回0
    var num2 = Number(undefined); //返回NaN
    var num3 = Number("hello"); //返回NaN
    var num4 = Number(" "); //如果是空字符串或是真空的字符串返回0
    var num5 = Number(123); //返回123,如果是数字,简单返回
    var num6 = Number("123abc"); //返回NaN
    var num7 = Number("abc123"); //返回NaN

    ParseInt()

    特点:
    a.如果转换的内容可以转成数字,那么就直接返回这个内容对应的数字。
    b.如果不可以转换那么返回NaN.
    c.如果带有小数,那么会去掉小数,而不是四舍五入。
    d.如果第一个字符是数字,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    例子:
    var num1 = parseInt(false); //无论true或是false都是NaN
    var num2 = parseInt(undefined); //NaN
    var num3 = parseInt("hello"); //返回N
    var num4 = parseInt(""); //如果是空字符串或是真空的字符串返回NaN
    var num5 = parseInt(123); //返回123,如果是数字,简单返回
    var num6 = parseInt("123a89bc"); //返回123
    var num7 = parseInt("abc123"); //返回NaN
    var num8 = parseInt('123.456'); //只能转换整数部分,小数部分直接舍掉
    var num9 = parseInt("80.56ab");

    ParseFloat()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    例子:
    var num1 = parseFloat(false); //无论true或是false都是NaN
    var num2 = parseFloat(undefined); //NaN
    var num3 = parseFloat("hello"); //返回N
    var num4 = parseFloat(""); //如果是空字符串或是真空的字符串返回NaN
    var num5 = parseFloat(123); //返回123,如果是数字,简单返回
    var num6 = parseFloat("123a89bc"); //返回123
    var num7 = parseFloat("abc123"); //返回NaN
    var num8 = parseFloat('123.456'); //返回123.456
    var num9 = parseFloat("80.56ab");//返回80.56

    ####二.其他类型转换为String类型
    隐式转换:当两个操作数做”+”运算时,如果表达式中任意一边有字符串,”+”,为字符串连接符

    1
    2
    3
    4
    5
    例子:
    var n = 200;
    n = n + "";
    console.log(n);//"200"
    console.log(typeof n);//string

    显式(强制)转换: toString( ) 和 String()

    1.toString() : 除了null undefined这两个类型不能调用 .toString() ,其他任何数据都可以调用.toString();

    2.String() : 任何数据都可以调用此函数;

    1
    2
    3
    4
    5
    6
    例子:

    var a = undefined;
    a = String(a);
    console.log(a);//"undefined"
    console.log(typeof a);//string

    ####三.其他类型转换为Boolean类型:
    其它数据类型转换为boolean类型值为false只有这几种情况:0 NaN “” null undefined false
    隐式转换: 在数据类型之前加“!!”即可

    1
    2
    3
    4
    5
    例子:
    var n = -200;
    var b = !!n;
    console.log(b);
    console.log(typeof b);

    显式转换:调用Boolean():

    1
    2
    3
    4
    5
    6
    例子
    console.log(Boolean(NaN));//false
    console.log(Boolean(0));//false
    console.log(Boolean(null));//false
    console.log(Boolean(undefined));//false
    console.log(Boolean("abc"));//false
    **如若有错,请多多指教,谢谢广大网友**
    ]]>
    javascript
    事件绑定、事件监听、事件委托 /2017/01/06/%E4%BA%8B%E4%BB%B6%E7%BB%91%E5%AE%9A%E3%80%81%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC%E3%80%81%E4%BA%8B%E4%BB%B6%E5%A7%94%E6%89%98/ 在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定、事件监听、事件委托(事件代理)等。这些名词是什么意思呢,有什么作用呢?

    ###事件绑定

    要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数。所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称。

    在JavaScript中,有三种常用的绑定事件的方法:

    • 在DOM元素中直接绑定;

      • 在JavaScript代码中绑定;
      • 绑定事件监听函数。

      在DOM中直接绑定事件

      我们可以在DOM元素上绑定onclick、onmouseover、onmouseout、onmousedown、onmouseup、ondblclick、onkeydown、onkeypress、onkeyup等。好多不一一列出了。如果想知道更多事件类型请查看,DOM事件

      1
      2
      3
      4
      5
      6
      7
      <input type="button" value="click me" onclick="hello()">

      <script>
      function hello(){
      alert("hello world!");
      }
      </script>

      在JavaScript代码中绑定事件

      在JavaScript代码中(即script标签内)绑定事件可以使JavaScript代码与HTML标签分离,文档结构清晰,便于管理和开发。

      1
      2
      3
      4
      5
      6
      7
      <input type="button" value="click me" id="btn">

      <script>
      document.getElementById("btn").onclick = function(){
      alert("hello world!");
      }
      </script>

      使用事件监听绑定事件

      绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数。下面详细介绍,事件监听。

      事件监听

      关于事件监听,W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。

      起初Netscape制定了JavaScript的一套事件驱动机制(即事件捕获)。随即IE也推出了自己的一套事件驱动机制(即事件冒泡)。最后W3C规范了两种事件机制,分为捕获阶段、目标阶段、冒泡阶段。IE8以前IE一直坚持自己的事件机制(前端人员一直头痛的兼容性问题),IE9以后IE也支持了W3C规范。

      W3C规范

      语法:

      1
      element.addEventListener(event, function, useCapture)

      event : (必需)事件名,支持所有DOM事件
      function:(必需)指定要事件触发时执行的函数。
      useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。

      注:IE8以下不支持。

      1
      2
      3
      4
      5
      6
      7
      8
      <input type="button" value="click me" id="btn1">

      <script>
      document.getElementById("btn1").addEventListener("click",hello);
      function hello(){
      alert("hello world!");
      }
      </script>

      IE标准

      语法:

      1
      element.attachEvent(event, function)

      event:(必需)事件类型。需加“on“,例如:onclick。
      function:(必需)指定要事件触发时执行的函数。

      1
      2
      3
      4
      5
      6
      7
      8
      <input type="button" value="click me" id="btn2">

      <script>
      document.getElementById("btn2").attachEvent("onclick",hello);
      function hello(){
      alert("hello world!");
      }
      </script>

      事件监听的优点

      1、可以绑定多个事件。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <input type="button" value="click me" id="btn3">

      <script>
      var btn3 = document.getElementById("btn3");
      btn3.onclick = function(){
      alert("hello 1"); //不执行
      }
      btn3.onclick = function(){
      alert("hello 2"); //执行
      }
      </script>

      常规的事件绑定只执行最后绑定的事件。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <input type="button" value="click me" id="btn4">

      <script>
      var btn4 = document.getElementById("btn4");
      btn4.addEventListener("click",hello1);
      btn4.addEventListener("click",hello2);

      function hello1(){
      alert("hello 1");
      }
      function hello2(){
      alert("hello 2");
      }
      </script>

      两个事件都执行了。

      2、可以解除相应的绑定

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      <input type="button" value="click me" id="btn5">

      <script>
      var btn5 = document.getElementById("btn5");
      btn5.addEventListener("click",hello1);//执行了
      btn5.addEventListener("click",hello2);//不执行
      btn5.removeEventListener("click",hello2);

      function hello1(){
      alert("hello 1");
      }
      function hello2(){
      alert("hello 2");
      }
      </script>

      封装事件监听

      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
      <input type="button" value="click me" id="btn5">

      //绑定监听事件
      function addEventHandler(target,type,fn){
      if(target.addEventListener){
      target.addEventListener(type,fn);
      }else{
      target.attachEvent("on"+type,fn);
      }
      }

      //移除监听事件
      function removeEventHandler(target,type,fn){
      if(target.removeEventListener){
      target.removeEventListener(type,fn);
      }else{
      target.detachEvent("on"+type,fn);
      }
      }

      //测试
      var btn5 = document.getElementById("btn5");
      addEventHandler(btn5,"click",hello1);//添加事件hello1
      addEventHandler(btn5,"click",hello2);//添加事件hello2
      removeEventHandler(btn5,"click",hello1);//移除事件hello1

      事件委托

      事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <input type="button" value="click me" id="btn6">

      var btn6 = document.getElementById("btn6");
      document.onclick = function(event){
      event = event || window.event;
      var target = event.target || event.srcElement;
      if(target == btn6){
      alert(btn5.value);
      }
      }

      上面只是个例子,代码尽可能的简化了。在实际的代码中 我们可能用到jQuery的live()、delegate()、bind()、on()等。

      事件委托优点

      1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。实例分析JavaScript中的事件委托和事件绑定,这篇文章写得还不错。

      传统写法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
      </ul>

      <script>
      var item1 = document.getElementById("item1");
      var item2 = document.getElementById("item2");
      var item3 = document.getElementById("item3");

      item1.onclick = function(){
      alert("hello item1");
      }
      item2.onclick = function(){
      alert("hello item2");
      }
      item3.onclick = function(){
      alert("hello item3");
      }
      </script>

      事件委托

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
      </ul>

      <script>
      var item1 = document.getElementById("item1");
      var item2 = document.getElementById("item2");
      var item3 = document.getElementById("item3");

      document.addEventListener("click",function(event){
      var target = event.target;
      if(target == item1){
      alert("hello item1");
      }else if(target == item2){
      alert("hello item2");
      }else if(target == item3){
      alert("hello item3");
      }
      })
      </script>

      2、动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。

      传统写法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
      </ul>

      <script>
      var list = document.getElementById("list");

      var item = list.getElementsByTagName("li");
      for(var i=0;i<item.length;i++){
      (function(i){
      item[i].onclick = function(){
      alert(item[i].innerHTML);
      }
      })(i)
      }

      var node=document.createElement("li");
      var textnode=document.createTextNode("item4");
      node.appendChild(textnode);
      list.appendChild(node);

      </script>

      点击item1到item3都有事件响应,但是点击item4时,没有事件响应。说明传统的事件绑定无法对动态添加的元素而动态的添加事件。

      事件委托

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      <ul id="list">
      <li id="item1" >item1</li>
      <li id="item2" >item2</li>
      <li id="item3" >item3</li>
      </ul>

      <script>
      var list = document.getElementById("list");

      document.addEventListener("click",function(event){
      var target = event.target;
      if(target.nodeName == "LI"){
      alert(target.innerHTML);
      }
      })

      var node=document.createElement("li");
      var textnode=document.createTextNode("item4");
      node.appendChild(textnode);
      list.appendChild(node);

      </script>

      当点击item4时,item4有事件响应。说明事件委托可以为新添加的DOM元素动态的添加事件。

    本文标题:事件绑定、事件监听、事件委托
    文章作者:Tsrot
    发布时间:2016年08月12日 - 13时37分
    最后更新:2017年10月01日 - 15时04分
    原始链接:http://blog.xieliqun.com/2016/08/12/event-delegate/
    许可协议: “署名-非商用-相同方式共享 3.0” 转载请保留原文链接及作者。

    ]]>
    事件
    解决inline、inline—block之间空隙问题 /2017/01/01/%E8%A7%A3%E5%86%B3inline%E3%80%81inline%E2%80%94block%E4%B9%8B%E9%97%B4%E7%A9%BA%E9%9A%99%E9%97%AE%E9%A2%98/ 发现问题

    ​ 代码如下:

    img

    ​ 效果如下:

    img

    解决问题:

    ​ 原因:由于换行字符会被浏览器解析成一个空格符,所以就会产生一个间隙

    ​ 解决方法:

    ​ 方法1:将行内或行内块元素写在一行,不过不建议这么写,这样编排不够简洁优雅。

    ​ 方法2:给父元素设置font-size:0;因为空格符也是字符,设置font-size:0 即可消除空隙。

    ​ 方法3:可以通过margin来调整位置

    ​ 方法4:将img设为块元素,即display为block

    ]]>
    css