梁光静


  • Home

  • Archives

JS数据类型的转换

Posted on 2018-08-07

1. 转换成number

官方:

1
2
3
4
5
6
7
8
9
Number('1')       //     1

parseInt('1') // 1
parseInt是面试重点 parseInt('011') === 11,这是十进制
要在后面加8才是八进制 parseInt('011',8) === 9
parseInt('s') === NaN
parseInt('1s') === 1

parseFloat('1.23')// 1.23

老司机:

1
2
3
4
5
6
7
8
9
'1' - 0 === 1              //最常见
'1.23' - 0 === 1.23 //最常见

+'1' === 1
+'1.23' === 1.23
+'.2' === 0.2
+'-1' === -1

-'-1' === 1

2. 转换成string

官方:

  1. number、boolean类型可通过toString方法转换成字符串
  2. symbol不能用toString方法
  3. undefined、null不能用toString方法,会报错
  4. object类型用toString只能转换出'[object Object]'
  5. 把上述toString()改成String()也一样,但String()能转换null和undefined
    1
    2
    3
    4
    (1).toString();        //     '1'
    true.toString(); // 'true'
    null.toString(); // error:Cannot read property 'toString' of null
    undefined.toString(); // error:Cannot read property 'toString' of undefined

老司机:

1
2
3
4
5
6
7
8
9
1 + ''       // '1'
true + '' // 'true'
null + '' // 'null'
undefined + '' // 'undefined'

var obj = {};
obj + '' // '[object Object]'

1 + '1' 等于 (1).toString + '1' // '11'

3. 转换成boolean

官方:

总共只有6个falsy值,0、NaN、’’、null、undefined,除了这6个,其它值都是true。所有对象都是true,包括var n = new Boolean(false),n也是true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Boolean(1)          //        true
Boolean(2) // true
Boolean(0) // false
Boolean(NaN) // false

Boolean('') // 空字符串false
Boolean(' ') // 空格字符串true

Boolean(null) // false

Boolean(undefined) // false

Boolean({}) // 空对象true
Boolean([]) // 空数组true

老司机:

取反两次,总共只有6个falsy值,0、NaN、’’、null、undefined,除了这6个,其它值都是true。所有对象都是true,包括var n = new Boolean(false),n也是true

1
2
3
4
5
6
7
8
9
10
11
12
!!1          //        true
!!0 // false
!!NaN // false

!!'' // false
!!' ' // true

!!{} // true

!!null // false

!!undefined // false

数据结构入门

Posted on 2018-08-06

1.哈希(Hash)

计数排序中的桶就是hash,hash的意思就是一个key对应一个value,如:
数组也是hash:a[0]=1,a[1]=2,……
对象也是hash

2.队列

先进先出,和排队一样

1
2
3
4
5
6
7
8
let q = []; 

q.push('第一');
q.push('第二');
q.push('第三');
q.shift(); //第一
q.shift(); //第二
q.shift(); //第三

基数排序里的桶就是队列,因为是先进先出

3.栈

先进后出,和队列相反

1
2
3
4
5
6
7
8
let stack = []; 

stack.push('第一');
stack.push('第二');
stack.push('第三');
stack.pop(); //第三
stack.pop(); //第二
stack.pop(); //第一

4.链表

1
2
3
4
5
6
7
8
9
let a = {
value:1,
next:{
value:2,
next:{
value:3
}
}
}

a.next.value=2;
a.next.value=3;
比数组好在删除中间的数据很方便,比如删除第二项,直接:

1
a.next = a.next.next

5.树

  1. html就是一种树。
  2. 二叉树每个节点最多有两个分支,被称为左子树和右子树
  3. 二叉树的第i层最多有 2^i^个节点,定义根节点为第0层,总共最多有2^i+1^-1个节点
  4. 完全二叉树和满二叉树可以用数组来存
  5. 定义二叉树根节点为第0层,完全二叉树或满二叉树每一层的第一个数在数组中为a[2^i^-1],每一层的最后一个数为a[2^i+1^-1-1]

几种常见算法

Posted on 2018-08-05

1. 冒泡排序Bubble Sort(体育委员摸头杀)

时间复杂度:O(n^2^)
有个数组a=[5,4,1,3,2,6],从小到大排序,总共进行a.length-1轮,首先将a[0]和a[1]比较,谁大就把谁放在后面,交换完后再将a[1]和a[2]比较,谁大就把谁放在后面,交换完后再将a[2]和a[3]比较…..一直到a[4]和a[5]比较,进行完第一轮后,最大的那个就已经放在最后一位了,接下来再重新从a[0]开始……直到进行到a[3]和a[4]比较(a[5]上一轮已经确定了最大的,不用再动了),直到a[2],a[3],a[4],a[5]都确定了,最后再比较一次a[0],a[1],排完a[0],a[1]的顺序,a数组的顺序就排好了~
点BUB是冒泡排序的动画演示

2. 选择排序Selection Sort(体育老师点人法)

时间复杂度:O(n^2^)
选出最小的和第一位交换位置,第一位就被确定了,接下来找倒数第二小的和第二位换位置,接着再找倒数第三小的和第三位换位置……一直找到最后一位
点SEL是冒泡排序的动画演示

3. 插入排序Insertion Sort(起扑克牌法)

时间复杂度:O(n^2^)
从数组的第二个开始,和第一个比较并排顺序,接着拿第三个和第二个比,若比第二个大则直接不动,若比第二个小则和第一个比,若比二小比一大则插在它们中间,若比第一个小则放在第一个,接着再拿第四个分别和三、二、一
比…….直到最后。
这就像打扑克牌时你摸牌的方法
点INS是冒泡排序的动画演示

4. 随机快排

优点:
效率高,时间复杂度:O(n*log2n)
缺点:
有时候比计数排序慢
简介:
随机选一个数,例:36,#将这个数和第一个数交换位置,于是36到了第一位,接着将36和其他所有数依次比较大小,把所有比36小的放左边,比36大的放右边,比完其他所有数后把36同比它小的数里的最右边的那个交换位置,这样36就定位了。
接着以同样的方式随机选择一个36左边的数,然后回到上面#的位置继续进行,在36的左边再次快排,这样左边排序时完全不用管右边,大大提高了效率,把左边排完再排右边。
演示:点R-Q是随机快排

5. 计数排序(Hash)

优点:
效率高,时间复杂度:O(n+max)
缺点:
1.需要一个hash来作为工具
2.无法对小数和负数进行排序,只能排正整数
3.可能需要很多桶,不像桶排序可控制桶数量
用途:
数字相差不大的时候可以用计数排序,如年龄排序
简介:
和基数排序差不多,比快排更快,需要一个额外数组(Hash)辅助,例:a=[3,2,4,5,1,3,34]
a[0]=3于是将Hash数组中的hash[3]=1
a[1]=2于是将hash[2]=1
a[2]=4于是将hash[4]=1
a[3]=5于是将hash[5]=1
a[4]=1于是将hash[1]=1
a[5]=3于是将hash[3]=hash[3]+1=2
a[6]=34于是将hash[34]=1
这样hash=[ ,1,1,2,1,1, , , , ,……, , , , ,1]
最后将hash中的数据按顺序取出来存放在另外一个数组里则排序完成。

6. 桶排序(Hash)

优点:
和计数排序不同的是一个桶里可放多个数字,效率高,计数排序的改良版,时间复杂度:O(N+C)
缺点:
需要hash工具,和计数排序不同的是每个桶里都是无序的,还要再排一次序
用途:
高考总分排序,每100分放在一个桶里,数字很分散的时候不好用,可用基数排序(比如从几十到几千)
简介:
a=[0,2,1,56,32,67,32],存入hash里

1
2
3
4
5
6
7
8
9
hash = {
'0':[0,2,1],
'1':[],
'2':[],
'3':[32,32],
'4':[],
'5':[56],
'6':[67],
}

还要把每个桶里的数字排序一下,再依次拿出来

7. 基数排序Radix Sort(Hash)

优点:
效率高
桶数量是确定的,时间复杂度:O(nlog(r)m)
缺点:
需要一个hash当工具,要多次排序
简介:
和桶排序类似,数字很分散的时候,可以用基数排序,首先用个位排,每次出桶的时候要按照进桶的顺序出!再到百位,再到千位,具体看下面演示

演示:点RAD是基数排序

8. 堆排序

时间复杂度:nlogn
用数组表示一个堆,每次都做最大堆排序,每做完一次就把最大的数和最后一位交换位置,并定下来,于是每做一次最大堆排序就能确定一个最大的数并把它放到最后一位,一直重复到排完所有的数,这样一个从小到大的数组就排出来了
演示:堆排序

9. 归并排序

移动端适配

Posted on 2018-08-02

移动端适配

meta viewport

<meta name="viewport" content="width=device-width, initial-scale=1" />
viewport是网页默认的宽度和高度,上面这行代码的意思是,网页宽度默认等于屏幕宽度(width=device-width),原始缩放比例(initial-scale=1)为1.0,即网页初始大小占屏幕面积的100%。
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
目前主流浏览器使用
initial-scale属性控制页面最初加载时的缩放等级。maximum-scale、minimum-scale及user-scalable属性控制允许用户以怎样的方式放大或缩小页面。

媒体查询

响应式

  • 我的理解就是用来辨别屏幕大小从而来使用不同的css样式达到大小屏幕的自适应
  • 例如 iphone5/5s 屏幕宽度为 320 iphone6/7/8 屏幕宽度为 375

    1
    2
    3
    <!-- link元素中的CSS媒体查询 -->
    <link rel="stylesheet" media="(max-width: 320px)" href="iphone5.css" />
    <link rel="stylesheet" media="(min-width: 321px) and (max-width: 375px)" href="iphone678.css" />

    以上例子就是当屏幕最大为320px时 使用iphone.css
    以上例子就是当屏幕最小321px最大为375px时 使用iphone678.css

    也可以在css中给某些元素设置

    1
    2
    3
    4
    5
    6
    7
    8
     <!-- 样式表中的CSS媒体查询 -->
    <style>
    @media (max-width: 320px) {
    .nav {
    display: none;
    }
    }
    </style>
  • 而有些公司对于移动端的适配 都是后台开发人员根据屏幕的尺寸来使用 不同的html , 如写代码啦
  • 还有比如淘宝的适配就是不同的设备访问的网站不同 比如电脑访问淘宝就是taobao.com ,手机访问就是m.taobao.com

动态REM

  • 为了在不同的手机页面显示的内容及布局都是一样的 , 比如说 iphone5 宽度是320px

    iphone6 宽度是375px

    整体的显示效果是一样的,苹果6会显示的大一点。 网页会随着不同的手机而进行等比的放大与缩小,那么动态rem就是用来解决这个 问题的

单位

常用的有  
  • px 就是像素点的意思
  • em 一个M的大小 ,或者不是很正确的一个汉字大小 ,相对于当前元素的font-size
  • vh 视口高度的1/100,其次,它不像rem那样被广泛支持。
  • vw 视口宽度的1/100,其次,它不像rem那样被广泛支持。
  • rem root em 根的em ,一个文档的根是html ,也就是1rem === html的font-size

计算rem

  • 利用js获取页面宽度, 设置根元素的font-size

    1
    2
    3
    4
    <script>
    var pageWidth = window.innerWidth;
    document.write('<style>html{font-size:'+ pageWidth/10 +'px;}</style>')
    </script>
  • 这样的话 1rem 就相当与 页面宽度的 10% , 就能知道具体设置的宽高是多少

  • 但是rem 如果根据设计师的设计搞来写 , 算rem 会很麻烦 , 于是就用到了sass 的 px2rem 函数计算

  • windows安装sass 方法
    i 安装ruby
    下载ruby 下载最新版本
    在命令行中输入ruby -v命令来确认是否安装成功:
    ii 安装sass
    Sass是Ruby语言写的,安装Sass必须先安装Ruby。假定你已经安装好了Ruby,接着在命令行输入下面的命令:
    gem install sass ,安装完成后,通过sass -v命令来判断是否安装成功

    装好后 可以在scss 文件中写入

    1
    2
    3
    4
    5
    6
    7
    8
    $rem: 640;    // 设计稿的宽度
    @function px2rem($px) {
    @return ($px / $rem) * 10 + rem;
    }

    div {
    width: px2rem(320px); // 算出来的 width: 5rem;
    }

Flex布局

Posted on 2018-07-29

Flex布局

阮一峰-Flex布局
阮一峰-Flex布局实例教程

Flex布局

块级元素

1
2
3
.box{
display: flex;
}

行内元素

1
2
3
.box{
display: inline-flex;
}
  • 注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效

Flex布局属性

  • 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称”项目”。
  • 主轴:水平线
  • 交叉轴:垂直线

flex-direction属性

  • 决定主轴的方向 或 交叉轴的方向
    1
    2
    3
    4
    5
    6
    .box{
    // flex-direction: row; 从左至右
    // flex-direction: row-reverse; 从右至左
    // flex-direction: column; 从上至下
    // flex-direction: column-reverse; 从下至上
    }

flex-wrap属性

  • 决定如何换行
    1
    2
    3
    4
    5
    .box{
    //flex-wrap: nowrap; 不换行
    //flex-wrap: wrap; 换行,第一行在上方(从上往下)
    //flex-wrap: wrap-reverse; 换行,第一行在下方(从下往上)
    }

flex-flow属性

  • flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
    1
    2
    3
    4
    .box {
    // flex-flow: <flex-direction> || <flex-wrap>;
    // flex-flow: row nowrap;
    }

justify-content属性

  • 决定了项目的水平对齐方式
  • 与 主轴的方向有关,以下假设为flex-direction: row;
    1
    2
    3
    4
    5
    6
    7
    .box {
    // justify-content: flex-start; 左对齐
    // justify-content: flex-end; 右对齐
    // justify-content: center; 居中对齐
    // justify-content: space-between; 两端对齐,项目之间的间隔都相等。
    // justify-content: space-around; 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
    }

align-items属性

  • 决定了项目的垂直对齐方式
  • 与交叉轴的方向有关,以下假设为flex-direction: column;
    1
    2
    3
    4
    5
    // align-items: flex-start 上对齐
    // align-items: flex-end:下对齐
    // align-items: center:居中对齐
    // align-items: baseline: 项目的第一行文字的基线对齐。
    // align-items: stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content属性

  • align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
    1
    2
    3
    4
    5
    6
    7
    8
    .box {
    // align-content: flex-start; 与交叉轴的起点对齐。
    // align-content: flex-end; 与交叉轴的终点对齐。
    // align-content: center; 与交叉轴的中点对齐。
    // align-content: space-between; 与交叉轴两端对齐,轴线之间的间隔平均分布。
    // align-content: space-around; 每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
    // align-content: stretch; 轴线占满整个交叉轴。
    }

项目的属性

1
2
3
4
5
6
7
order : 0123...(优先级设置) 项目的排列顺序
flex-grow:0123...(默认为0,不放大) 项目的放大比例,自动按比列分配容器空间
flex-shrink:0123...(默认为1,默认空间不足时可等比缩放,为0不缩)
flex-basis:length | auto 设置项目的主轴空间(main size) ,auto 为项目的本来大小
flex: 前三个的省略写法属性 ,两个快捷值 auto(1 1 auto) none (0 0 auto)
align-self:auto | flex-start | flex-end | center | baseline | stretch;
允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

Javascript 中 apply、call、bind的理解

Posted on 2018-07-28

1.apply、call

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

1
2
3
4
5
6
7
8
9
10
11
function fruits() {}

fruits.prototype = {
color: "red",
say: function() {
console.log("My color is " + this.color);
}
}

var apple = new fruits;
apple.say(); //My color is red

但是如果我们有一个对象banana= {color : “yellow”} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:

1
2
3
4
5
6
7
8
9
10
11
banana = {
color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow

banana = {
color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow

所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。

2.apply、call 的区别

对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:

1
2
3
var func = function(arg1, arg2) {

};

就可以通过如下方式来调用:

1
2
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。
而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。
为了巩固加深记忆,下面列举一些常用用法:

  1. 数组之间追加

    1
    2
    3
    4
    var array1 = [12 , "foo" , {name "Joe"} , -2458]; 
    var array2 = ["Doe" , 555 , 100];
    Array.prototype.push.apply(array1, array2);
    /* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
  2. 获取数组中的最大值和最小值

    1
    2
    3
    var  numbers = [5, 458 , 120 , -215 ]; 
    var maxInNumbers = Math.max.apply(Math, numbers), //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。

  1. 验证是否是数组(前提是toString()方法没有被重写过)

    1
    2
    3
    functionisArray(obj){ 
    returnObject.prototype.toString.call(obj) === '[object Array]' ;
    }
  2. 类(伪)数组使用数组方法

    1
    var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。

3.深入理解运用apply、call

定义一个 log 方法,让它可以代理 console.log 方法,常见的解决方法是:

1
2
3
4
5
function log(msg) {
console.log(msg);
}
log(1); //1
log(1,2); //1

上面方法可以解决最基本的需求,但是当传入参数的个数是不确定的时候,上面的方法就失效了,这个时候就可以考虑使用 apply 或者 call,注意这里传入多少个参数是不确定的,所以使用apply是最好的,方法如下:

1
2
3
4
5
function log(){
console.log.apply(console, arguments);
};
log(1); //1
log(1,2);

接下来的要求是给每一个 log 消息添加一个”(app)”的前辍,比如:

1
log("hello world");    //(app)hello world

该怎么做比较优雅呢?这个时候需要想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为标准数组,再使用数组方法unshift,像这样:

1
2
3
4
5
6
function log(){
var args = Array.prototype.slice.call(arguments);
args.unshift('(app)');

console.log.apply(console, args);
};

4.bind

说完了 apply 和 call ,再来说说bind。bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

直接来看看具体如何使用,在常见的单体模式中,通常我们会使用 _this , that , self 等保存 this ,这样我们可以在改变了上下文之后继续引用到它。 像这样:

1
2
3
4
5
6
7
8
9
10
var foo = {
bar : 1,
eventBind: function(){
var _this = this;
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(_this.bar); //1
});
}
}

由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $(‘.someClass’).on(‘click’,function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:

1
2
3
4
5
6
7
8
9
var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(this.bar); //1
}.bind(this));
}
}

在上述代码里,bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。然后,当回调函数被执行的时候, this 便指向 foo 对象。再来一个简单的栗子:

1
2
3
4
5
6
var bar = function(){
console.log(this.x);
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3

这里我们创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

有个有趣的问题,如果连续 bind() 两次,亦或者是连续 bind() 三次那么输出的值是什么呢?像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
var sed = {
x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?

var fiv = {
x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

答案是,两次都仍将输出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

5.apply、call、bind比较

  1. bind、call和apply方法的相同之处
    前面我们已经说了call和apply的作用相同,区别就在参数的形式不同。bind方法的作用也是改变this的指向。bind方法的参数要求和call方法一样,第一个参数是函数执行上下文的对象,后面的参数可以是多个。
      但bind又有自己的特别之处,下面来说说bind的用法上的区别:
  2. bind方法的用法上的区别
  • 区别一: bind()方法是会创建一个新函数,当调用这个新函数时,会以创建新函数时传入 bind()方法的第一个参数作为 this。
    看栗子来体会:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var name='xxx'; 
    var obj = {
    name: 'yyy'
    }
    function func() {
    console.log(this.name);
    }
    var func1 = func.bind(obj);
    func1(); //yyy
    func(); //xxx

func1等于通过bind方法创建的和func函数相同的新函数。func1的this对象为传入的obj,所以this.name就只等于obj对象的name值‘yyy’。
  因为是新生成的函数,所以原来函数func()并不受影响,所以直接执行func(),this指向全局window,所以this.name为’xxx’。

  • 区别二: 参数的使用上,call方法是将第二个及之后的参数,作为实参传递到函数中。
      而 bind() 方法的第二个以及以后的参数,再加上新函数运行时的参数,按照顺序作为实参传递到新函数中。
      这样看文字解释,真的太绕了,直接看栗子,就很好理解:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function func(a, b, c) {
    console.log(a, b, c);
    }
    var func1 = func.bind(null,'aaa');

    func('A', 'B', 'C'); // A B C
    func1('A', 'B', 'C'); // aaa A B
    func1('B', 'C'); // aaa B C
    func.call(null, 'aaa'); // aaa undefined undefined
  • 区别三:写法上,bind函数需要再加个()
    最后一个不同,就是bind函数不是立即调用的,实现生成新的处理函数,然后再执行。而call和apply方法都是立即执行。
      还是看栗子吧,改写下前面的例子:(一样的实现效果,不一样的执行写法)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var name='xxx'; 
    var obj = {
    name: 'yyy'
    }
    function func() {
    console.log(this.name);
    }
    console.log(func.bind(obj()); //yyy
    console.log(func.call(obj)); //yyy
    console.log(func.apply(obj)); //yyy
  1. bind方法常见的应用写法
  • 例子1:改变setTimeout()方法的this指向
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <body>
    <button class="bindtest">dianwo</button>
    <script>
    /*bind的用法--和使用var _this=this达到同样的目的*/
    bindtest=document.querySelector('.bindtest')
    bindtest.addEventListener('click',function(){
    console.log(this) //<button class="domtest">dianwo</button>
    setTimeout(function(){
    console.log(this) //<button class="domtest">dianwo</button>
    }.bind(this),300)
    })
    </script>
    </body>

前面说了,bind的作用是得到一个新的函数,而新函数的this就是bind传递的第一个参数。这里bind方法是和setTimeout方法同级的,属于bindtest对象下的点击事件下的,所以this是 bindtest对象。

  • 例子2:字符串拼接的bind方法实现
      前面call方法的使用例子中实现的字符串拼接,现在换成用bind方法来实现:
      常见的是,比如我需要一个join操作,但是我没有这个方法,那么我就需要借助数组Array原型的join方法来借位使用。
    1
    2
    3
    4
    5
    function joinStr(){
    var joins=Array.prototype.join.bind(arguments);
    console.log(joins('-'))
    }
    joinStr('a','b','c')

例子中的写法等同于[‘a’,’b’,’c’].join(‘-‘)

CSS的position值

Posted on 2018-07-27

css的position值

CSS position属性用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置。

文档流

  • 正常的文档流会根据元素的类型来流动
  • 内联元素会从左至右流动,显示不下去之后会换行继续从左向右
  • 块级元素从上往下流动
  • 脱离文档流的方法有浮动,绝对定位,固定定位

position5个取值

static 相对定位

该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。

relative

该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。
相对定位的元素是在文档中的正常位置偏移给定的值,但是不影响其他元素的偏移。相对定位的元素并未脱离文档流

absolute 绝对定位

不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
绝对定位元素相对于最近的非 static 祖先元素定位。当这样的祖先元素不存在时,则相对于ICB(inital container block, 初始包含块),视窗。绝对定位的元素脱离了文档流

fixed 固定定位

不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform 属性非 none 时,容器由视口改为该祖先。
固定定位会固定显示在设置的位置,脱离了文档流

sticky 粘性定位

盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。在所有情况下(即便被定位元素为 table 时),该元素定位均不对后续元素造成影响。当元素 B 被粘性定位时,后续元素的位置仍按照 B 未定位时的位置来确定。position: sticky 对 table 元素的效果与 position: relative 相同。
粘性定位是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。例如:

CSS-元素宽高是由什么决定的

Posted on 2018-07-23

CSS-元素宽高是由什么决定的

任何元素都可以是块级元素 或 行内元素
因为每个元素都可以设置成行内元素或块级元素

行内元素表现形式


代码

1
2
3
4
5
6
7
8
9
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>
<span>hello! </span>

  • 行内元素就是在一行中显示,如果后面跟着的还是行内元素,就继续跟在后面显示,当一行不够显示时自动换行

块级元素表现形式


代码

1
2
3
<div style="border: 1px solid red;">123</div>
<div style="border: 1px solid red;">123</div>
<div style="border: 1px solid red;">123</div>

  • 块级元素不管后面跟着的是什么元素,都会另起一行。也就是说块级元素会独占一行。

    元素的高度由什么决定的

    span 行内元素高度由什么决定的

    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
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>JS Bin</title>
    <style>
    div{
    border: 1px solid blue;
    }
    span{
    border: 1px solid red;
    font-size: 72px;
    }
    .s1{
    font-family: sans-serif;
    }
    .s2{
    font-family: monospace;
    }
    .s3{
    font-family:serif ;
    }
    </style>
    </head>
    <body>
    <div>
    <span class="s1">ABC</span>
    <span class="s2">ABC</span>
    <span class="s3">ABC</span>
    </div>
    </body>
    </html>

  • 可以看到, 我给每个span 都设置了一个字体, 而中间字体的高度明显高于两边的字体 。
  • 每一种字体的设计师不一样, 每一种字体的设计师都会对自己设置出来的字体的默认行高不一样
  • 所以,行内元素内容为字的元素的行高是由 字体的默认行高决定的。
  • 比较详细的解说可以看看这篇知乎文章字号与行高

div 块级元素高度由什么决定的

  • 从上面的程序代码可以看到, span是由一个div包裹的 。 div的告诉是中间最高的span的高度。
  • 也就是说块级元素的高度是由它的内容决定的,而且是所有内容中最高的内容决定的。

元素的宽度是由什么决定的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
div{
border: 1px solid blue;
font-size: 72px;
}
span{
border: 1px solid red;
font-size: 72px;
}
</style>
</head>
<body>
<span>12345678</span>
<div>12345678</div>
</body>
</html>

  • 行内元素的宽度是由它的内容决定的,行内元素不能设置宽高
  • 块级元素当没有设置宽度是默认100%宽 ,所以才会到最右边。当设置了宽度是就是固定的宽度 , 下面我们把宽度设置为200px;

  • 看div的蓝色边框 , 宽度就是固定的200px;

  • 如果把div设置成行内元素, 它的宽度是怎样的呢,设置属性display:inline

  • div的宽度会收缩

CSS

Posted on 2018-07-20

CSS

引入css的4种方法

  1. style 属性
    1
    <div style="height:100px;background-color: red;"></div>
  1. style 标签
    在head标签内容中添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>JS Bin</title>
    <style>
    div{
    height: 100px;
    background-color: red;
    }
    </style>
    </head>
    <body>
    <div></div>
    </body>
    </html>
  1. link 标签引入
    i 创建一个a.css文件 ,并添加内容

    1
    2
    3
    4
    div{
    height: 100px;
    background-color: red;
    }

    ii 在head中添加

    1
    <link rel="stylesheet" type="text/css" href="a.css">
  1. import
    该方法是在一个css文件中引入另一个css文件,语法为
    1
    @import url("b.css")
(以下观点属个人理解)

水平布局

导航栏

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
a{
text-decoration:none;
}
ul{
list-style-type: none;
}
ul>li{
float:left;
margin:20px;
}
</style>
</head>
<body>
<nav>
<ul>
<li><a href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">CONTACT</a></li>
</ul>
</nav>
</body>
</html>

导航栏.png

在导航条下面加一个div

1
2
3
4
5
div{
width: 100px;
height: 100px;
background-color: grey;
}

未清除浮动效果

未清楚浮动.png

清楚浮动效果

2018-04-10 10-24-12 的屏幕截图.png

  • 所以在给元素添加float后都有可能带来一些问题 ,所以我们需要清除浮动带来的影响。
  • 清除浮动的办法有很多种,我们只用以下一种方法
    i 给浮动元素的父元素的类 加 clearfix
    ii clearfix 的css代码具体实现
    1
    2
    3
    4
    5
    .clearfix::after{
    content:'';
    display:block;
    clear:both;
    }

垂直布局

个人理解

整个网页就是在做一个垂直布局 , 而水平布局就是在整体的纵向垂直布局上做一块内容的横向水平布局

各块的垂直布局

2018-04-10 10-45-56 的屏幕截图.png

  • 可以看到导航栏部分和所有div做整体的垂直布局
  • 而导航栏这一块里面又做了水平布局
  • 所以 我觉得浏览器的布局就是整体在做垂直布局,但是又有水平布局组合的复杂布局

实用且好用的工具推荐

工具推荐

HTML语义化

Posted on 2018-07-17

HTML-语义化-(iframe-a-form的使用)

语义化

参考资料:
semantic-html
关于语义化 HTML 以及前端架构的一点思考
如何理解 web 语义化

语义化的含义就是用正确的标签做正确的事情,html语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;在没有样式CCS情况下也以一种文档格式显示,并且是容易阅读的。搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利于 SEO。使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。

列举几个常见的标签:
标题从大到小: h1 , h2 , h3 , h4 , h5 , h6
超链接: a
段落: p
无序列表: ul>li
有序列表: ol>li
自定义列表: dl>{dt , dd}
<header>
<main>
<section>
<footer>
<article>

a标签

作用

跳转页面。 发起 HTTP GET 请求

target 属性

  • _blank 在新页面打开网页
  • _self 在当前页面打开网页
  • _parent 在父页面打开网页 , 这种要在当前页面被嵌套在一个iframe网页中容易体现出来
  • _top 在最外围页面打开网页 , 这种要在当前页面被嵌套在多个iframe网页中容易体现出来

download

  • 表示下载href所对应的网页

iframe标签

默认宽高为300 * 150大小

作用

  • 可以在一个网页嵌套一个网页
    例如:

与 a标签

看图:

1
2
3
<iframe name=xxx src="http://baidu.com" frameborder="0"></iframe>
<a href="http://qq.com" target="xxx">QQ</a>
<p>我是iframe外面的P标签</p>

QQ为 a 标签链接 ,它的target 属性等于 xxx,点击QQ 就会在iframe 中打开qq.com的网页
iframe 标签中本来打开的网页时baidu.com ,iframe 有一个属性时name ,name属性等于 a标签的target属性的值,所以点击a标签的时候就会在iframe中打开a标签中的URL。

form标签

跳转页面。 发起 HTTP POST 请求
常用属性

  • action : 规定当提交表单时向何处发送表单数据。值为:URL
  • method : 规定用于发送表单数据的 HTTP 方法。值只能是: GET 或 POST请求
  • target : 规定在何处打开 action URL。值为:
    i. _blank
    ii. _self
    iii. _parent
    iv. _top
    和 标签是一样的。
  • <form> 元素包含一个或多个如下的表单元素: <input> <textarea> <button> <select> <option> <optgroup> <fieldset> <label>

input标签

type属性:

  1. text: 简单文本输入
  2. password: 加密文本输入
  3. radio: 单选框 ,相同的name ,为一组单选框
  4. chekbox: 复选框 , 相同的name ,为一组复选框
  5. reset: 重置按钮 ,value为按钮名字,重置之前所有的输入
  6. submit:提交按钮 ,value为按钮名字 ,将输入的内容提交至 form 标签的 action属性对应的URL中
  7. button: 普通按钮 ,value为按钮名字
    • 注意: 要想输入的内容能提交 , 需要加一个name属性

require属性: 加了这个属性就表示,输入框中必须有输入

lable : lable for id , lable标签for 中值 ,对应lable想关联的标签的id 值。

textarea: 文本输入框

select : 下拉菜单 , option为选项

1234

梁光静

36 posts
10 tags
© 2019 梁光静
Powered by Hexo
|
Theme — NexT.Muse v5.1.4