My Little World

learn and share


  • 首页

  • 分类

  • 标签

  • 归档

  • 关于
My Little World

Travish CI使用

发表于 2017-08-08

Travish CI使用

1、使用github 账号登陆https://www.travis-ci.org/
2、点击右上角自己的账户名,选择accounts,弹出在github上所有的仓库
ci1.png
点击这个按钮重新从github上获取所有仓库
ci2.png
3、点击对应仓库按钮,变为对勾,则开启对应仓库的集成化测试,每次提交代码到远程仓库都进行一次测试
4、点击仓库名,可进入到测试界面,
ci3.png
5、为项目添加.travis.yml文件
.travis.yml 文件编写的相关语法可参考https://docs.travis-ci.com/user/languages/javascript-with-nodejs/

.travis.yml 文件可以在https://lint.travis-ci.org/页面进行检查,是否编写正确

6、push代码,在Travish CI等待测试结果
页面图标因为有缓存所以可能出现不能及时更换状态的情况,这个注意看结果就好

My Little World

fork仓库

发表于 2017-08-08

fork

在页面点击Fork,将被人的仓库复制到自己的远程仓库
使用git clone 将远程仓库克隆到本地
切换分支到develop git checkout -b develop
修改完代码后
git add . && git commit -m ‘test new pull request’
git push origin develop
然后在github页面找到刚刚fork的仓库,切换branch到develop,
点击New pull request进行merge

保持与原仓库同步

git remote -v
查看当前的远程仓库地址,输出如下:

origin https://github.com/YooHannah/homework2.git (fetch)
origin https://github.com/YooHannah/homework2.git (push)
可以看到从自己帐号 clone 下来的仓库,远程仓库地址是与自己的远程仓库绑定的(这不是废话吗)

接下来运行

git remote add upstream https://github.com/FE-star/homework2.git
这条命令就算添加一个别名为 upstream(上游)的地址,指向之前 fork 的原仓库地址。git remote -v 输出如下:

origin https://github.com/YooHannah/homework2.git (fetch)
origin https://github.com/YooHannah/homework2.git (push)
upstream https://github.com/FE-star/homework2.git (fetch)
upstream https://github.com/FE-star/homework2.git (push)
之后运行下面几条命令,就可以保持本地仓库和上游仓库同步了

git fetch upstream
git checkout master 如果本来就在master上就不用切换
git merge upstream/master
接着就是熟悉的推送本地仓库到远程仓库

git push origin master

Git 合并两个不同的仓库

My Little World

事件冒泡和事件捕获

发表于 2017-08-06

addEventListener/attachEvent/element.onclick

辨别区分addEventListener、attachEvent和element.onclick

attachEvent事件

attachEvent是ie添加事件处理程序,接收两个参数,其中事件类型名称要加”on”,
可以添加多个事件处理程序,按照添加顺序相反的顺序触发

addEventListener事件

addEventListener是给非ie添加事件处理程序,接收三个参数,第一个是事件名,不需要加“on”,
第二个是绑定的函数,第三个参数是一个布尔值,如果是false,就使用传统的冒泡方式,
如果为true,就在捕获阶段调用事件处理程序
可以添加多个事件处理程序,按照添加顺序触发

onclick

el.onclick相当于在标签上写onclick

区别

1.上下文
attachEvent会在全局作用域中运行,this等于window对象
addEventLinstener在其依附的元素的作用域中运行,this等于绑定元素对象
使this关键字都指向元素处理方法

1
2
3
4
5
6
function bind(el, fn, type){
var _fn = function(){
fn.apply(el, arguments);
};
window.addEventListener ? el.addEventListener(type, _fn, false) : el.attachEvent("on" + type, _fn);
}

2.绑定
el.onclick通过标签的onclick属性输入到文档,然后由文档解析成事件
attachEvent和addEventLinstener要在文档解析完成以后,通过文档的dom接口去绑定的事件
资源加载和页面事件

3.取消绑定
el.onclick:el.onclick=null;
addEventListener:removeEventListener();
attachEvent():detachEvent()

4.获取event事件
非IE:

1
2
3
4
5
6
el.onclick=function(event){
  alert(event.type); //"click"
};
el.addEventListener("click",function(event){
  alert(event.type); //"click"
},false);

IE:
通过el.onclick绑定的事件处理程序中,event对象作为window对象的一个属性存在。
el.onclick=function(){
  var event=window.event;
  alert(event.type); //“click”
}
如果通过attachEvent()添加事件处理程序时,event对象作为参数被传入事件处理程序,
el.attachEvent(“onclick”,function(event){
  alert(event.type); //“click”
});

标签时一样

1
<input type="button" value="Click me" onclick="alert(event.type)"/>   //"click"

事件捕获、事件冒泡

二者是指当事件在某一DOM元素被触发时,该DOM元素的父级元素也绑定了触发事件,则触发事件的执行顺序

事件冒泡

事件自下而上依次执行,先执行子元素触发事件,再执行父元素触发事件,
addEventListener第三个参数设置为false,参数不设置默认是冒泡执行

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
<body>
<div id="parent">
  <div id="child" class="child">您好</div>
</div>
</body>

<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+this.id);
})
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+this.id)
})
document.getElementById("parent").onclick=function(e){
alert("parentonclik事件被触发,"+this.id);
}
document.getElementById("child").onclick=function(e){
alert("childonclik事件被触发,"+this.id);
}
</script>
//点击'您好',弹出顺序:child事件被触发->childonclik事件被触发->parent事件被触发->parentonclik事件被触发
<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+this.id);
},false)
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+this.id)
},true)
</script>
//点击'您好',先弹出child事件被触发,再弹出parent事件被触发

事件捕获

事件从上到下一次执行,先执行父元素触发事件,再执行子元素触发事件,
addEventListener第三个参数设置为true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<body>
<div id="parent">
  <div id="child" class="child">您好</div>
</div>
</body>

<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+this.id);
},true)
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+this.id)
},true)
document.getElementById("parent").onclick=function(e){
alert("parentonclik事件被触发,"+this.id);
}
document.getElementById("child").onclick=function(e){
alert("childonclik事件被触发,"+this.id);
}
</script>
//点击'您好',弹出顺序:parent事件被触发->child事件被触发->childonclik事件被触发->parentonclik事件被触发
<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
alert("parent事件被触发,"+this.id);
},true)
document.getElementById("child").addEventListener("click",function(e){
alert("child事件被触发,"+this.id)
},false)
</script>

//点击'您好',先弹出parent事件被触发,再弹出child事件被触发

应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//要求:鼠标放到li上对应的li背景变灰
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
</ul>
//实现一:利用事件冒泡实现,不用遍历所有li节点
$("ul").on("mouseover",function(e){
$(e.target).css("background-color","#ddd").siblings().css("background-color","white");
})
//实现二:给每个li绑定事件,缺点,动态的加载了一些元素,新增li后,还要再绑定一次事件
$("li").on("mouseover",function(){
$(this).css("background-color","#ddd").siblings().css("background-color","white");
})

禁止冒泡

1
2
3
4
5
6
7
8
9
function doSomething(e) {
if (!e) {//微软模型
var e = window.event;
e.cancelBubble = true;
}
if (e.stopPropagation) {//w3c事件模型
e.stopPropagation();
}
}

补充

事件委托是什么?有什么好处?

假设父元素有4个儿子,我不监听4个儿子,而是监听父元素,看触发事件的元素是哪个儿子,这就是事件委托。
可以监听还没有出生的儿子(动态生成的元素)。省监听器。

My Little World

关于Performance API

发表于 2017-08-03

load/unload事件

load事件

当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发window上面的load事件
使用方法

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
//方法一
var EventUtil = {
addHandler: function(element, type, handler){
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
}
}
EventUtil.addHandler(window,"load",function(event){
alert("loaded!");
});
//方法二
<!DOCTYPE html>
<html>
<head>
<title>load Event Example</title>
</head>
<body onload = "alert("Loaded!")">
</body>
</html>

document.ready 监控dom是否加载完毕,dom加载完毕时及资源加载之前触发
DOMContentLoaded 当页面的DOM树解析好并且需要等待js执行完才触发

unload事件

在文档被完全卸载后触发,只要用户切换到另一个页面,就会发生unload事件。
利用这个事件最多的情况是清除引用,以避免内存泄漏
使用方法

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
//方法一
var EventUtil = {
getEvent: function (event) {
return event ? event : window.event;
},
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
};
EventUtil.addHandler(window, "unload", function (event) {
alert("Unloaded");
})
//方法二
<html>
<head>
<tilte>卸载(unload)事件</tile>
</head>
<body onunload="alert('Unload')">
</body>
</html>

Performance API

Performance 接口会给出某个页面的与时间相关的性能信息
使用方法为 window.performance.属性/方法

Performance API用于精确度量、控制、增强浏览器的性能表现。这个API为测量网站性能,提供以前没有办法做到的精度
目前,所有主要浏览器都已经支持performance对象,包括Chrome 20+、Firefox 15+、IE 10+、Opera 15+。

performance.timing

包含各种与浏览器性能有关的时间数据,提供浏览器处理网页各个阶段的耗时

  • navigationStart:当前浏览器窗口的前一个网页关闭,发生unload事件时的Unix毫秒时间戳。如果没有前一个网页,则等于fetchStart属性。即浏览器处理当前网页的启动时间
  • unloadEventStart:如果前一个网页与当前网页属于同一个域名,则返回前一个网页的unload事件发生时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。
  • unloadEventEnd:如果前一个网页与当前网页属于同一个域名,则返回前一个网页unload事件的回调函数结束时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。
  • redirectStart:返回第一个HTTP跳转开始时的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
  • redirectEnd:返回最后一个HTTP跳转结束时(即跳转回应的最后一个字节接受完成时)的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
  • fetchStart:返回浏览器准备使用HTTP请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。
  • domainLookupStart:返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
  • domainLookupEnd:返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
  • connectStart:返回HTTP请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回值等同于fetchStart属性的值。
  • connectEnd:返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的是持久连接,则返回值等同于fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。
  • secureConnectionStart:返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。
  • requestStart:返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。
  • responseStart:返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。
  • responseEnd:返回浏览器从服务器收到(或从本地缓存读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的Unix毫秒时间戳。
  • domLoading:返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
  • domInteractive:返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
  • domContentLoadedEventStart:返回当前网页DOMContentLoaded事件发生时(即DOM结构解析完毕、所有脚本开始运行时)的Unix毫秒时间戳。
  • domContentLoadedEventEnd:返回当前网页所有需要执行的脚本执行完成时的Unix毫秒时间戳。
  • domComplete:返回当前网页DOM结构生成时(即Document.readyState属性变为“complete”,以及相应的readystatechange事件发生时)的Unix毫秒时间戳。
  • loadEventStart:返回当前网页load事件的回调函数开始时的Unix毫秒时间戳。如果该事件还没有发生,返回0。
  • loadEventEnd:返回当前网页load事件的回调函数运行结束时的Unix毫秒时间戳。如果该事件还没有发生,返回0。

unloadEventStart 不等于navigationStart,navigationStart比unloadEventStart早
domComplete 等于 loadEventStart

performance.now()

performance.now方法返回当前网页自从performance.timing.navigationStart到当前时间之间的微秒数(毫秒的千分之一)。

performance.mark()

mark方法用于为相应的视点做标记。
window.performance.mark(‘mark_fully_loaded’);
clearMarks方法用于清除标记,如果不加参数,就表示清除所有标记。
window.peformance.clearMarks(‘mark_fully_loaded’);
window.performance.clearMarks();

performance.getEntries()

浏览器获取网页时,会对网页中每一个对象(脚本文件、样式表、图片文件等等)发出一个HTTP请求。performance.getEntries方法以数组形式,返回这些请求的时间统计信息,有多少个请求,返回数组就会有多少个成员.
由于该方法与浏览器处理网页的过程相关,所以只能在浏览器中使用。
window.performance.getEntries()[0] //获取第一个HTTP请求(即网页的HTML源码)的时间统计信息

performance.navigation对象

1、performance.navigation.type
该属性返回一个整数值,表示网页的加载来源,可能有以下4种情况:

  • 0:网页通过点击链接、地址栏输入、表单提交、脚本操作等方式加载,相当于常数performance.navigation.TYPE_NAVIGATENEXT。
  • 1:网页通过“重新加载”按钮或者location.reload()方法加载,相当于常数performance.navigation.TYPE_RELOAD。
  • 2:网页通过“前进”或“后退”按钮加载,相当于常数performance.navigation.TYPE_BACK_FORWARD。
  • 255:任何其他来源的加载,相当于常数performance.navigation.TYPE_UNDEFINED。

2、performance.navigation.redirectCount
该属性表示当前网页经过了多少次重定向跳转.
参考资料

页面请求加载过程

var t = performance.timing;

1、首先,在浏览器地址栏中输入url

2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。
var dns = t.domainLookupEnd - t.domainLookupStart; //域名解析时间
4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。
var tcp = t.connectEnd - t.connectStart;//浏览器与服务器之间的连接建立时间
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
t.requestStart 浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的时间
6、服务器处理收到的请求,将数据返回至浏览器

7、浏览器收到HTTP响应
var ttfb = t.responseStart - t.navigationStart;//读取页面第一个字节之前的耗时
8、读取页面内容,浏览器渲染,解析html源码
var getdata = t.responseEnd-t.responseStart;//接收数据时间
9、生成Dom树、解析css样式、js交互
var dom = t.domInteractive-t.domLoading; //从构建DOM到页面与用户可以开始交互的时间
var script= t.domContentLoadedEventEnd-t.domContentLoadedEventStart;//脚本运行时间
var load = t.loadEventEnd-t.loadEventStart;//load事件处理时间

10、客户端和服务器交互

11、ajax查询

步骤二详细步骤

  • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
  • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
  • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
  • ISP缓存:若上述均失败,继续向ISP搜索。

浏览器渲染步骤

  • 解析html以构建dom树 分词器器、解析器
  • 构建render树
  • 布局render树
  • 绘制render树

渲染引擎开始解析html,并将标签转化为内容树中的dom节点。接着,它解析外部CSS文件及style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建另一棵树——render树。

Render树由一些包含有颜色和大小等属性的矩形组成,它们将被按照正确的顺序显示到屏幕上。

Render树构建好了之后,将会执行布局过程,它将确定每个节点在屏幕上的确切坐标。再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点

现代浏览器工作原理

Navigator 对象

包含有关浏览器的信息。
appCodeName 返回浏览器的代码名
appName 返回浏览器的名称
appVersion 返回浏览器的平台和版本信息
cookieEnabled 返回指明浏览器中是否启用 cookie 的布尔值
platform 返回运行浏览器的操作系统平台
userAgent 返回由客户机发送服务器的user-agent 头部的值

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
js 获取操作系统
function detectOS() {
var sUserAgent = navigator.userAgent;
var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel");
if (isMac) return "Mac";
var isUnix = (navigator.platform == "X11") && !isWin && !isMac;
if (isUnix) return "Unix";
var isLinux = (String(navigator.platform).indexOf("Linux") > -1);
if (isLinux) return "Linux";
if (isWin) {
var isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1;
if (isWin2K) return "Win2000";
var isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1;
if (isWinXP) return "WinXP";
var isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1;
if (isWin2003) return "Win2003";
var isWinVista= sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1;
if (isWinVista) return "WinVista";
var isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1;
if (isWin7) return "Win7";
}
return "other";
}

document.writeln("您的操作系统是:" + detectOS());

js判断浏览器

My Little World

关于CDN

发表于 2017-08-03

cdn 是一种从网络层面优化页面访问速度的手段
CDN服务商提供一项智能域名解析服务,这种智能DNS服务在浏览器发起域名查询时,会根据用户IP计算并返回离它最近的同网络CDN节点IP,引导浏览器与此节点建立连接以获取资源。
不同地区的用户访问同一个域名,依赖CDN服务商提供的智能域名解析服务得到不同CDN节点的IP地址
不同地区的用户会访问到离自己最近的相同网络线路上的CDN节点,当请求达到CDN节点后,节点会判断自己的内容缓存是否有效,如果有效,则立即响应缓存内容给用户,从而加快响应速度。如果CDN节点的缓存失效,它会根据服务配置去我们的内容源服务器获取最新的资源响应给用户,并将内容缓存下来以便响应给后续访问的用户。因此,一个地区内只要有一个用户先加载资源,在CDN中建立了缓存,该地区的其他后续用户都能因此而受益。
通过将静态资源缓存到离用户很近的相同网络运营商的CDN节点上,不但能提升用户的访问速度,还能节省服务器的带宽消耗,降低负载。
好的cdn服务到源服务器获取文件会通过专用的线路,这样就会比用户直接从源服务器获取资源快
cdn缓存技术原理

My Little World

常见页面布局小结

发表于 2017-08-03

圣杯布局

三栏布局,左右两栏宽度固定,中间一栏宽度随屏幕宽度自适应

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
<body>
<div id="header">#header</div>
<div id="container">
<div id="center" class="column">#center</div>
<div id="left" class="column">#left</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>
</body>

<style type="text/css">
body {
min-width: 550px; /* 2x LC width + RC width */
}
#container {
padding-left: 200px; /* LC width */
padding-right: 150px; /* RC width */
}
#container .column {
position: relative;/* 让左右两栏进行相对位移,位移到container的内边距位置 */
min-height: 200px;/* 高度自适应*/
float: left;
}
#center {
width: 100%;
background-color: #e9e9e9;
}
#left {
width: 200px; /* LC width */
right: 200px; /*LC width *//*相对于 container 的右边线向左偏移 200px 将自己位移到container内边距 */
margin-left: -100%;/*浮动到与中间平行 */
background-color: red;
}
#right {
width: 150px; /* RC width */
margin-right: -150px; /* RC width */
background-color: blue;
}
#footer {
clear: both;/*清除 footer 的上下环境,以免遭跟上面三栏一起浮动*/
}
#header,
#footer {
background-color: #c9c9c9;
}
</style>

圣杯1
圣杯2

flex 实现 圣杯布局

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
59
60
61
62
63
64
65
66
<!doctype html>
<html>
<head>
</head>
<body>
<header>header</header>
<section>
<nav>nav</nav>
<article>article</article>
<aside>aside</aside>
</section>
<footer>footer</footer>
</body>
<style>
body{
display: flex;
flex-flow: column wrap;
justify-content:flex-start;
}
header,section,nav,aside,footer{
display: block;
}
header{
order: 1;
width: 100%;
min-height: 100px;
padding: 10px 20px;
background-color: antiquewhite;
}
section{
flex: 1;
order: 2;
min-width: 100%;
margin: 20px 0;
display: flex;
}
footer{
order: 3;
min-height: 60px;
min-width: 100%;
padding: 1%;
background-color: burlywood;
}
nav{
order:1;
width: 220px;
padding: 1%;
background-color: aquamarine;
}
article{
flex: 1;/* 可伸缩 */
order:2;
padding: 1%;
margin:0 2%;
background-color: blue;
word-break: break-all;
}
aside{
order:3;
width:220px;
padding: 1%;
background-color: aqua;
}

</style>
</html>

双飞翼布局

效果同圣杯布局,只是写法上DOM在center里面新增加了div,css不再使用relative定位,只是用float和外边距

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
<div id="header">header</div>
<div id="container">
<div id="center" class="column">
<div id="innerCenter">center</div>
</div>
<div id="left" class="column">left</div>
<div id="right" class="column">right</div>
</div>
<div id="footer">footer</div>

<style type="text/css">
body {
min-width: 351px; /* LC width + RC width +1*/
}
#container .column {
min-height: 200px;
float: left;
}
#innerCenter { /*代替圣杯container的padding处理*/
margin-left: 200px;
margin-right: 150px;
}
#center {
width: 100%;
background-color: #e9e9e9;
}
#left {
width: 200px;
margin-left: -100%;
background-color: red;
}
#right {
width: 150px;
margin-left: -150px;
background-color: blue;
}
#footer {
clear: both;
}
#header, #footer {
background-color: #c9c9c9;
}

</style>

圣杯3
圣杯4

7种垂直居中

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
1.tabel自带
<body>
<table class="parent">
<tr>
<td class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</td>
</tr>
</table>
.parent{
border: 1px solid red;
height: 600px;
}

.child{
border: 1px solid green;
}
2.在水平居中部分的前后添加inline-block元素,高度100%,三个子元素,vertical-align:middle
<body>
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
</body>
.parent{
border: 3px solid red;
height: 600px;
text-align: center;
}

.child{
border: 3px solid black;
display: inline-block;
width: 300px;
vertical-align: middle;
}

.parent:before{
content:'';
outline: 3px solid red;
display: inline-block;
height: 100%;
vertical-align: middle;
}
.parent:after{
content:'';
outline: 3px solid red;
display: inline-block;
height: 100%;
vertical-align: middle;
}
如果用标签元素,则前后元素类设置为.parent .after{},.parent .before{}

3.父元素position设置为相对定位relative,子元素位置相对父元素,设置为absolute,通过设置top和left 50%决定距离父元素上边和左边的距离,
再通过margin-top,margin-left为子元素高和宽的一半将子元素和父元素中心重合
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
.parent{
height: 600px;
border: 1px solid red;
position: relative;
}
.child{
border: 1px solid green;
width: 300px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin:-50px 0 0 -150px;
}


4.父元素relative,子元素absolute,top和left均为 50%,transform:translate(-50%,-50%)
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
.parent{
height: 600px;
border: 1px solid red;
position: relative;
}
.child{
border: 1px solid green;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}

5.父元素relative,子元素absolute,子元素,上下左右都是0,margin:auto
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>
</div>
.parent{
height: 600px;
border: 1px solid red;
position: relative;
}
.child{
border: 1px solid green;
width: 300px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
6.felx布局,父元素display:flex,justify-content:center;align-items:center
<div class="parent">
<div class="child">
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
</div>

</div>
.parent{
height: 600px;
border: 3px solid red;

display: flex;
justify-content: center;
align-items: center;
}
.child{
border: 3px solid green;
width: 300px;
}

清除浮动

1.在父元素上添加样式overflow:hidden/auto
2.给父元素设置高度或者添加float属性(使之成为浮动元素)
3.在子元素结尾添加空div标签或者br标签,或者给父元素添加:after伪类,设置属性clear:both

1
2
3
4
5
6
.clearfix::after{
content: ''; display: block; clear:both;
}
.clearfix{
zoom: 1; /* IE 兼容 */
}

多列布局

column-width —— 列宽,不设置时由其他属性决定
column-count —— 列数,不设置时由其他属性决定
columns —— column-width column-count

column-gap —— 列间距
column-rule —— 间距线,位于列间距中间,介于background和content之间,宽度大于列间距时消失
宽度 样式 颜色

column-fill —— 各列宽度
auto 随内容自动调整 |balance 以内容最多一列统一高度
column-span —— 子元素是否合并列
none/all

静态布局:尺寸不变,布局不变
自适应布局:为不同尺寸屏幕设计不同静态布局
流式布局:通过更改模块大小,保证整体布局
响应式布局:针对不同尺寸屏幕,设计不同流式布局
弹性布局:可以设置模块大小放缩保证布局,也可以固定模块大小,更改布局
各种布局概念区分
react涉及布局
相关资料
CSS布局 ——从display,position, float属性谈起

My Little World

使用QRcode.js生成二维码

发表于 2017-08-01

在页面中引入QRcode.js文件,再js部分进行定义
var qrcode = new QRCode(document.getElementById(“qrcode0”), { //qrcode0放置二维码容器的id
width : 150,//二维码大小
height : 150
});
qrcode.makeCode(url);//url,生成二维码的依据

My Little World

Angularjs 利用图片更换emoji表情

发表于 2017-08-01

在某些浏览器中,emoji表情不能正常显示,只能显示原始状态如下
erroremoji
为使表情正常显示,这里利用转码方法将emoji符号用图片替换

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
59
60
61
//对数据$scope.data.remark做表情替换处理,$scope.data.remark是包含emoji符号的字符串
var str=$scope.data.remark;
str=str.replace(rep,function(code) { //code即匹配到的emoji符号,对该符号通过_escapeToUtf32(code)转码,得到对应图片名,然后图片替换
return '<img class="emoji" style="vertical-align:middle" src="assets/img/emoji/'+_escapeToUtf32(code) + '.png">';
})
$scope.data.remark = str;

//用emoji符号的unicode码匹配emoji符号,例如270c匹配 victory hand符号
var rep =/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]|\u270c|\u261d/g;

//emoji 表情转码
function _escapeToUtf32(str) {
var escaped = [],
unicodeCodes = _convertStringToUnicodeCodePoints(str),
i = 0,
l = unicodeCodes.length,
hex;

for (; i < l; i++) {
hex = unicodeCodes[i].toString(16);
escaped.push('0000'.substr(hex.length) + hex);
}
return escaped.join('-');
}

function _convertStringToUnicodeCodePoints(str) {
var surrogate1st = 0,
unicodeCodes = [],
i = 0,
l = str.length;

for (; i < l; i++) {
var utf16Code = str.charCodeAt(i);
if (surrogate1st != 0) {
if (utf16Code >= 0xDC00 && utf16Code <= 0xDFFF) {
var surrogate2nd = utf16Code,
unicodeCode = (surrogate1st - 0xD800) * (1 << 10) + (1 << 16) + (surrogate2nd - 0xDC00);
unicodeCodes.push(unicodeCode);
}
surrogate1st = 0;
} else if (utf16Code >= 0xD800 && utf16Code <= 0xDBFF) {
surrogate1st = utf16Code;
} else {
unicodeCodes.push(utf16Code);
}
}
return unicodeCodes;
}

//Angularjs对字符串里面的html标签不会按照HTML去解析,会当做字符串显示,
//所以这里需要对字符串进行过滤,使字符串里面的标签能按照html解析

//新建过滤器trust2Html,这里使用$sce方法
app.filter('trust2Html', ['$sce',function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
}])

//在页面里面显示经过图片替换的含emoji符号的字符串
<label ng-bind-html="data.remark|trust2Html"></label>

替换后结果
exactemoji
Emoji Unicode Tables

My Little World

探究jQuery.data

发表于 2017-07-30

jQuery.data用于处理标签数据绑定

使用方法

1.赋值

a.使用js
$(‘’).data(key,value); 一次赋值一个,value可以是任意js数据类型,包括Array 或者 Object
$(‘’).data(obj);一次赋值多个或者更新多个或者新增多个

b.使用HTML标签属性
利用H5 标签的’data-‘属性添加键值对

1
<div data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div>

2.取值
$(‘’).data(key);获取key对应的数据值
$(‘’).data(); 一次性获取绑定在$(‘’)上的所有数据对象

3.删除
$(‘’).removeData(key);

注意事项

a. <object>(除非是Flash插件),<applet> 或 <embed>> 三个标签不能使用.data方法

b. 通过”data-“属性建立的标签数据,获取时注意
data-last-value=”43” ==> $(‘div’).data(‘lastValue’)
data-options=’{“name”:”John”}’ ==> $(“div”).data(“options”).name ->John
取到的值会自动转化为js的数据类型

c. $(‘’).data()被赋值到js变量A后,之后对$(‘’)进行数据处理,A的内容会进行同步变动,
如果更改A的内容,$(‘’).data()也会同步更改
但如果$(‘’).data()的值被用到了html里面,HTML里面的值不会变动

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
<!DOCTYPE html>
<html>
<head>
<style>
div { color:blue; }
span { color:red; }
</style>
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<div>
The values stored were
<span></span>
and
<span></span>
</div>
<script>
$("div").data("test", { first: 16, last: "pizza!" });
$("span:first").text($("div").data("test").first);
$("span:last").text($("div").data("test").last);
//页面输出 The values stored were 16 and pizza!
var temp = $("div").data();
console.log(temp);
$("div").data({ first: 25, last: "pizza!" ,test:{last:'fruit'}});
// $("span:first").text($("div").data("first"));
// $("span:last").text($("div").data("test").last);
//如果没有以上两句页面不会发生任何变化,添加后
//页面输出 The values stored were 25 and fruit
console.log(temp);//temp与$("div").data()保持一致
console.log($("div").data())
temp.child = 'Jack';
console.log($("div").data()) //增加一项{child: "Jack"}
$("div").removeData("blah");//删除没有的属性不会报错
$("div").removeData("child");
console.log(temp);
</script>
</body>
</html>

JQuery.data源码解析

My Little World

angular样式绑定ng-class

发表于 2017-06-25

ng-class命令可用于绑定不同的样式
使用方法即先在js中,定义样式集合
$scope.STATUS_NAME = [
{‘labelClass’: ‘label1’},
{‘labelClass’: ‘label2’},
{‘labelClass’: ‘label3’},
{‘labelClass’: ‘label4’}
];
对绑定对象赋值
angular.forEach($scope.data, function(data){
//对数组中每一项,根据status属性赋给labelclass属性样式集合中的值
data.labelClass = $scope.STATUS_NAME[data.status].labelClass;
});
在html中定义不同的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style type="text/css">
.label1{
background-color:#87CEFA
}
.label2{
background-color:#90EE90
}
.label3{
background-color:#d2cd93
}
.label4{
background-color:#D3D3D3
}
</style>

在html中使用

1
2
3
<tr role="row" ng-repeat="item in data track by $index">
<td><span class="label" ng-class="item.labelClass">{{item.status_desc}}</span></td>
</tr>

1…171819…26
YooHannah

YooHannah

260 日志
1 分类
23 标签
RSS
© 2025 YooHannah
由 Hexo 强力驱动
主题 - NexT.Pisces