Code Monkey home page Code Monkey logo

front-end-knowledge's People

Contributors

iwalking11 avatar walking11 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

front-end-knowledge's Issues

encodeURI、encodeURIComponent、escape -- javascript 编码和解码函数

1. encodeURI():

  • 主要用于整个URI
  • 对空格进行编码
  • 不会对本身属于URI的特殊字符进行编码,例如":","/","?","#"

2. encodeURIComponent():

  • 主要用于URI中的某一段
  • 会对发现的任何非标准字符进行编码

3. escape():

  • 不会对 ASCII 字母和数字进行编码,
  • 不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . /
  • 其他所有的字符都会被转义序列替换。
  • ECMAScript v3 反对使用该方法,应用使用 decodeURI() 和 decodeURIComponent() 替代它。

参考:https://blog.csdn.net/cuew1987/article/details/10952509

Git基础功能之tag

git的基础功能中有个打标签的功能。这功能其实非常有用,往往在线上发布时会用到。

tag作用

像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等)。
当你在线上发布最新的代码时,最好每次都打上一个tag,因为当这次发布的代码失败,有bug的时候,你可以快速checkout上次的稳定tag,
以实现代码的快速回滚,待你修复好新代码后,再重新发布,打上一个稳定的标记tag。
另外在一些场景也会用到打tag来实现持久化构建的功能。

列出标签

$ git tag
v0.1
v1.3
**列出特定的标签:**
$ git tag -l 'v1.8.5*'
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5

创建标签

  • 轻量标签(lightweight),无标记信息:
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number
  • 附注标签(annotated)。
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag
v0.1
v1.3
v1.4

$ git show v1.4
tag v1.4
Tagger: Ben Straub <[email protected]>
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <[email protected]>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number
  • webstorm中创建tag
    VCS-git-tag打开new tag 弹窗:
    image

在commit列表中也可以选择任意一个commit new tag
image

提交标签

默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样 - 你可以运行 git push origin [tagname]。

//提交单个tag
$ git push origin v1.5
//提交全部tag
$ git push origin --tags

webstorm push时,左下角Push Tags同样要打勾
image

checkout标签

在 Git 中你并不能真的检出一个标签,因为它们并不能像分支一样来回移动。 如果你想要工作目录与仓库中特定的标签版本完全一样,可以使用 git checkout -b [branchname] [tagname] 在特定的标签上创建一个新分支:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

image
image

在线上执行回滚的时候,用一个可用稳定的tag,创建一个新的临时分支,让该分支在线上先跑。然后再去修复master的代码,等待修复完,再重新把线上分支切回master,以实现快速代码回滚。

参考:
Git基础之tag功能
2.6 Git Basics - Tagging

前端代码自动化部署

1.纯手工方式

  • 通过webpack打包需要发布的代码
  • 通过sftp工具上传打包后的文件

缺点:
每次都要手动去删除服务器端的文件,再上传,比较繁琐,而且容易误操作

2.利用nodejs ssh2-sftp-client上传到服务器

const upload = (localPath, remotePath) => {
		return new Promise((resolve, reject) => {
			const sftp = new Client();
			sftp.on('keyboard-interactive', (name, instructions, instructionsLang, prompts, finish) => {
				finish([config.password]);
			});
			sftp.connect(options).then(() => {
				return sftp.put(localPath, remotePath);
			}).then(() => {
				console.log('\033[42;30m DONE \033[40;32m' + localPath + '\033[0m');
				sftp.end();
				resolve(localPath);
			}).catch((err) => {
				console.log(err, 'catch error');
				reject(err);
			});
		});
	};

打包后自动执行上传的脚本文件即可

3.通过WebStorm自带的Deployment工具

配置好后,通过可视化的deploy按钮操作就能上传
也可以设置监听文件改变自动更新服务器文件

4.jenkins自动化部署

只看过相关介绍,暂时还没有尝试过。主要是通过触发git等版本控制工具webhook,推送信息到jenkins

参考:
利用nodejs监控文件变化并使用sftp上传到服务器
真▪一行代码完成从前端代码build到部署线上
前端自动化部署系统

关于overflow

CSS属性 overflow 定义当一个元素的内容太大而无法适应 块级格式化上下文 时候该做什么。它是 overflow-x 和overflow-y的 简写属性

/* 默认值。内容不会被修剪,会呈现在元素框之外 */
overflow: visible;

/* 内容会被修剪,并且其余内容不可见 */
overflow: hidden;

/* 内容会被修剪,浏览器会显示滚动条以便查看其余内容 */
overflow: scroll;

/* 由浏览器定夺,如果内容被修剪,就会显示滚动条 */
overflow: auto;

/* 规定从父元素继承overflow属性的值 */
overflow: inherit;

注意: 设置一个轴为visible(默认值),同时设置另一个轴为不同的值,会导致设置visible的轴的行为会变成auto。

相关代码

参考资料:
MDN-overflow

面试题整理 -- 1.JavaScript执行机制(单线程,通过Event Loop 事件循环执行异步)

  1. JavaScript执行机制(单线程,通过Event Loop 事件循环执行异步)
console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

出处:
这一次,彻底弄懂 JavaScript 执行机制

面试题整理-js基础之this的指向

1.一般原则

1:this永远指向一个对象;

2:this的指向完全取决于函数调用的位置;

因为函数在js中既可以当做值传递和返回,也可当做对象和构造函数,所有函数在运行时需要确定其当前的运行环境,this就出生了,所以,this会根据运行环境的改变而改变,同时,函数中的this也只能在运行时才能最终确定运行环境;

function fun(){
    console.log(this.s);
}
​
var obj = {
    s:'1',
    f:fun
}
​
var s = '2';
​
obj.f(); //1
fun(); //2
function foo() {
    console.log(this.a);
}
var obj2 = {
    a: 2,
    fn: foo
};
var obj1 = {
    a: 1,
    o1: obj2
};
obj1.o1.fn(); // 2

2.构造函数中的this指向new出来的对象

image

3.箭头函数this的指向 ---- this指向其定义时候的对象

箭头函数的this指向定义时所在的对象,其实质是因为箭头函数没有自己的this,用的是外层的this

4.函数对象的call()、apply()、bind() 方法都可以改变this的指向,但是箭头函数中无效

5.window定时器中的this

在setTimeOut()或setInterval()这样的方法中,如果传入的函数包含this, 那么,默认情况下,函数中的this会指向window对象。这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。
如何获取需要的this对象

  1. 将当前对象的this存为一个变量
    定时器内部的函数来访问到这个变量,此时的this,就指向了当前对象
function doClick(){
    var that = this;
    setInterval(function() {
      console.log(that.msg);
     }, 1000);
}
  1. 利用bind()方法
function doClick(){
    setInterval(function() {
      console.log(this.msg);
     }.bind(this), 1000);  //利用bind()将this绑定到这个函数上
}
  1. ES6的箭头函数
    ES6中的箭头函数, this总是指向词法作用域,也就是外层调用者obj,因此利用箭头函数就可以轻松解决这个问题
 function doClick(){
     setInterval(() => {
       console.log(this.msg);
     }, 100);
 },

关于CSS/direction和CSS/writing-mode

1. CSS direction

定义:direction 属性设置文本,表格列和水平排列的方向。

基本上,大家只要关心下面这两个属性值就好了:

direction: ltr; // 从左往右,默认值
direction: rtl; //从右往左

image

2. writing-mode

  • writing-mode的原本作用

和float属性有些类似,writing-mode原本设计的是控制内联元素的显示的(即所谓的文本布局-Text Layout)。因为在亚洲,尤其像**这样的东亚国家,存在文字的排版不是水平式的,而是垂直的,例如**的古诗古文。因此,writing-mode就是用来实现文字可以竖着呈现的。
image

  • writing-mode的语法

学习相比其他CSS属性要复杂一些,因为我们需要记住两套不同的语法。一个是IE私有属性,第二个是CSS3规范属性。

  1. CSS3规范:
writing-mode: horizontal-tb;    /* 默认值 */
writing-mode: vertical-rl;
writing-mode: vertical-lr;

下面是各个值下的中英文表现对照(参考自MDN):
image

  1. 老IE浏览器的语法,由于历史原因,显得相当的复杂,IE官方文档显示如下:

-ms-writing-mode: lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb

writing-mode: lr-tb | tb-rl | tb-lr (IE8+);
writing-mode: horizontal-tb | vertical-rl | vertical-lr;

实际开发用的上的其实也就这三种,可以和CSS3规范中的属性完全对应上。

  1. writing-mode不经意改变了哪些规则?
    我们只需要加上一行
    writing-mode: vertical-lr;
    就能实现以下效果:
  • 水平方向也能margin重叠
  • 可以使用margin:auto实现垂直居中
  • 可以使用text-align:center实现图片垂直居中
  • 可以使用text-indent实现文字下沉效果
  • 可以实现全兼容的icon fonts图标的旋转效果

3. writing-mode和direction的关系

writing-mode, direction, unicode-bidi(MDN文档)是CSS世界中3大可以改变文本布局流向的属性。其中direction, unicode-bidi属于近亲,经常在一起使用,也是唯二不受CSS3 all属性影响的CSS属性,基本上就是和内联元素一起使用使用,且据说貌似为阿拉伯文字设计。

乍一看,writing-mode似乎包含了direction, unicode-bidi某些功能和行为,例如vertical-rl的rl和direction的rtl值有相似之处,都是从右往左。然而,实际上,两者是没有交集的。因为vertical-rl此时的文档流为垂直方向,rl表示水平方向,此时再设置direction:rtl,实际上值rtl改变的是垂直方向的内联元素的文本方向,一横一纵,没有交集。而且writing-mode可以对块状元素产生影响,直接改变了CSS世界的纵横规则,要比direction强大和鬼畜的多。且据说貌似为东亚文字设计。

然而,CSS的奇妙就在于,某些特性当初可能就是问了某些图文排版设计,但是,我们可以利用其带来的特性,发挥自己的创造力,实现其他很多意想不到的效果。所以,上面出现的三剑客都是非常好的资源。

参考:
direction(MDN)
writing-mode(MDN)
CSS direction属性简介与实际应用
改变CSS世界纵横规则的writing-mode属性

Git基础功能之stash

git stash用于保存和恢复工作进度

  • git stash

    保存当前的工作进度。会分别对暂存区和工作区的状态进行保存

  • git stash save "message..."

    这条命令实际上是第一条 git stash 命令的完整版

  • git stash list

    显示进度列表。此命令显然暗示了git stash 可以多次保存工作进度,并用在恢复时候进行选择

  • git stash pop [--index] [<stash>]

    如果不使用任何参数,会恢复最新保存的工作进度,并将恢复的工作进度从存储的工作进度列表中清除。

    如果提供参数(来自 git stash list 显示的列表),则从该 <stash> 中恢复。恢复完毕也将从进度列表中删除 <stash>

    选项--index 除了恢复工作区的文件外,还尝试恢复暂存区。

  • git stash apply [--index] [<stash>]

    除了不删除恢复的进度之外,其余和 git stash pop 命令一样

  • git stash clear

    删除所有存储的进度

  • 在Webstorm中使用stash

    VCS / Git / Stash Changes

    image

    VCS / Git / UnStash Changes

    image

参考:
git stash用于保存和恢复工作进度

git基础之Commit message规范

使用一个规范的 Git 提交记录是很有必要的,这不仅让多人开发中的参与者能更好地了解项目的迭代历史和进程,也能在出现问题时快速定位,找到问题代码的提交记录。同时我们还可以使用工具根据提交记录自动生成更新说明 (CHANGELOG),方便用户了解每次更新的具体内容,也免去了项目维护者手动更新的痛苦。
目前前端社区中使用较多的 Git Commit 提交规范是 Angular 规范 (Git Commit Message Conventions ),Commit 的格式包含 Header、Body、Footer 三个部分:

<type>(<scope>): <subject>

<body>

<footer>
  1. type

用于说明 commit 的类别,只允许使用下面7个标识。

feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
  1. scope

用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。

  1. subject

是 commit 目的的简短描述,不超过50个字符。

1.以动词开头,使用第一人称现在时,比如change,而不是changed或changes
2.第一个字母小写
3.结尾不加句号(.
  1. body

详细描述(可不写)

  1. footer

修改不兼容变动以及关闭 Issue时(可不写)

Commit 规范的作用

1.提供更多的信息,方便排查与回退;
2.过滤关键字,迅速定位;
3.方便生成文档;

生成 Change log

如果我们的提交都按照规范的话,那就很简单了。生成的文档包括以下三个部分:

New features
Bug fixes
Breaking changes.

每个部分都会罗列相关的 commit ,并且有指向这些 commit 的链接。当然,生成的文档允许手动修改,所以发布前,你还可以添加其他内容。

这里需要使用工具 Conventional Changelog 生成 Change log :

npm install -g conventional-changelog
cd jartto-domo
conventional-changelog -p angular -i CHANGELOG.md -w

为了方便使用,可以将其写入 package.json 的 scripts 字段。

{
  "scripts": {
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0"
  }
}

这样,使用起来就很简单了:

npm run changelog

参考:
你可能会忽略的 Git 提交规范
阮一峰-Commit message 和 Change log 编写指南

很实用的一些css总结

1.position 几个属性的作用

position 的常见四个属性值: relative,absolute,fixed,static。一般都要配合"left"、"top"、"right" 以及 "bottom" 属性使用。

  • static:默认位置。
    在一般情况下,我们不需要特别的去声明它,但有时候遇到继承的情况,我们不愿意见到元素所继承的属性影响本身,从而可以用Position:static取消继承,即还原元素定位的默认值。设置为 static 的元素,它始终会处于页面流给予的位置(static 元素会忽略任何 top、 bottom、left 或 right 声明)。一般不常用。
  • relative:相对定位。**
    相对定位是相对于元素默认的位置的定位,它偏移的 top,right,bottom,left 的值都以它原来的位置为基准偏移,而不管其他元素会怎么 样。注意 relative 移动后的元素在原来的位置仍占据空间。
  • absolute:绝对定位。
    设置为 absolute 的元素,如果它的 父容器设置了 position 属性,并且 position 的属性值为 absolute 或者 relative,那么就会依据父容器进行偏移。如果其父容器没有设置 position 属性,那么偏移是以 body 为依据。注意设置 absolute 属性的元素在标准流中不占位置。
  • fixed:固定定位。
    位置被设置为 fixed 的元素,可定位于相对于浏览器窗口的指定坐标。不论窗口滚动与否,元素都会留在那个位置。它始终是以 body 为依据的。 注意设置 fixed 属性的元素在标准流中不占位置。

2.box-sizing是什么

**设置CSS盒模型为标准模型或IE模型。标准模型的宽度只包括content,二IE模型包括border和padding
box-sizing属性可以为三个值之一:

content-box,默认值,只计算内容的宽度,border和padding不计算入width之内
padding-box,padding计算入宽度内 (注:只有Firefox实现了这个值,但它在Firefox 50中被删除)
border-box,border和padding计算入宽度之内

3.简述一下src与href的区别

  • href是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
  • src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。

参考:https://juejin.im/post/5a954add6fb9a06348538c0d

css垂直水平居中的N种方式

html及css基础系列----css垂直水平居中

1. 单行垂直居中

如果一个容器中只有一行文字,对它实现居中相对比较简单,我们只需要设置它的实际高度height和所在行的高度line-height相等即可

2. 多行未知高度div的垂直居中

  • 使用Flex

只需要在父盒子设置:display: flex; justify-content:(平行方向) center;align-items: center(垂直方向); 就可以达到垂直水平居中
缺点:有兼容性问题

  • 使用 display:table-cell 方法

父盒子设置:display:table-cell; text-align:center;vertical-align:middle;
(父盒子外面需要再套一个div{display:table})

  • absolute+transform 水平垂直居中

<div class="parent">
  <div class="child">Demo</div>
</div>

<style>
  .parent {
    position: relative;
  }
  .child {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
</style>
  • relative+absolute + negative margin

.parent{
    position:relative;
}
.child{
     width: 100px;
     height: 100px;
     position: absolute;
     top: 50%;
     left: 50%;
     margin: -50px 0 0 -50px;
}

缺点:需要确定子元素宽高

  • 绝对定位方式+四个方向置0

子元素可以是块级元素也可以是行内元素,没有影响

.parent{
    position:relative
}
.child{
    margin:auto;
    height: 100px;
    width: 100px;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

需设置子元素宽高,否则子元素将与父元素宽高一致
解释:
通过以上描述,绝对居中(AbsoluteCentering)的工作机理可以阐述如下:
1、在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
2、position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。
3、为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative;(非static)的容器。
4、 给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto
5、由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。
这么看来, margin:auto似乎生来就是为绝对居中(Absolute Centering)设计的,所以绝对居中(Absolute Centering)应该都兼容符合标准的现代浏览器。

参考:
关于css水平垂直居中的总结
CSS中设置DIV垂直居中的N种方法 兼容IE浏览器
盘点8种CSS实现垂直居中水平居中的绝对定位居中技术

伪元素content中counter计数器的使用

直接上代码:

计数器counter

 <div class="main">
      <div class="first">
        <div class="second">伪元素content中counter计数器的使用</div>
        <div class="second">伪元素content中counter计数器的使用</div>
      </div>
      <div class="first">
        <div class="second">伪元素content中counter计数器的使用</div>
        <div class="second">伪元素content中counter计数器的使用</div>
        <div class="second">伪元素content中counter计数器的使用</div>
      </div>
      <div class="first">
        <div class="second">伪元素content中counter计数器的使用</div>
        <div class="second">伪元素content中counter计数器的使用</div>
      </div>
 </div>

.main {
    width: 350px;
    margin: 30px auto;
    height: auto;
    overflow: hidden;
    box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.5);
    counter-reset: main;
    color: #646452;
    text-align: left;
    .first {
      counter-reset: submain;
      &::before {
        font-size: 18px;
        font-weight: bold;
        counter-increment: main;
        display: inline-block;
        padding: 5px;
        content: "类别 " counter(main) ". ";
      }
      .second {
        &::before {
          padding: 5px 16px;
          font-family: arial black;
          display: inline-block;
          counter-increment: submain;
          content: counter(main) "." counter(submain) " ";
        }
      }
    }
  }

效果图:

image

嵌套计数器counters

 <ul class="father">
      <li class="son">我的爱好
        <ul class="father">
          <li class="son">爬山</li>
          <li class="son">追剧</li>
          <li class="son">旅游</li>
        </ul>
      </li>
      <li class="son">我的偶像
        <ul class="father">
          <li class="son">王昱珩
            <ul class="father">
              <li class="son">最强大脑第二季选手</li>
              <li class="son">最强大脑第五季水之队队长</li>
            </ul>
          </li>
          <li class="son">胡歌</li>
          <li class="son">陈默</li>
        </ul>
      </li>
      <li class="son">web前端</li>
      <li class="son">啦啦啦啦啦</li>
 </ul>
 li {
    list-style: none;
  }

  .father {
    text-align: left;
    padding-left: 20px;
    counter-reset: count;
    line-height: 1.6;
    color: #666;
  }

  .son:before {
    content: counters(count, '-') '. ';
    counter-increment: count;
    font-family: arial black;
  }

效果图:

image

DOM事件流

浏览器性能优化的文章中经常会出现事件委托(代理),那事件代理是利用了事件的什么机制?事件冒泡机制。事件冒泡又是什么呢,这篇我们就来总结一下DOM事件流

DOM事件发展

DOM事件:用户或浏览器执行的动作,如click
事件处理程序:是响应某个事件的函数,如 onclick()也叫事件侦听器

DOM有4次版本更新,与DOM版本变更,产生了3种不同的DOM事件定义 DOM0级、DOM2级、DOM3级。由于DOM1级中没有事件的相关内容,所以没有DOM1级事件。

  • DOM0事件
    <p onclick="alert('click')">HTML事件处理程序</p>

    问题

  1. HTML代码域JavaScript代码紧密的耦合在一起,没有实现相互分离,在进行代码的更新与维护的时候就显得异常困难。
  2. 扩展事件处理程序的作用域链在不同浏览器当中会导致不同的结果。
  3. 如果不采用调用函数的方式,而是像例子中那样直接书写代码,那么代码的通用性很差,会使得整站的代码量很大,通用性差。如果提取出来,存放在函数当中,那么,会面临另一个问题——当函数还没有被定义,只是HTML、CSS代码加载完毕,用户进行点击,会完全没有反应。

使用js的写法

var btn = document.getElementById('btn');
 btn.onclick = function(){
     alert(this.innerHTML);
 }

问题
当希望为同一个元素/标签绑定多个同类型事件的时候(如,为上面的这个p标签绑定3个点击事件),是不被允许的

  • DOM2级事件
    el.addEventListener(event-name, callback, useCapture)

    event-name: 事件名称,可以是标准的DOM事件
    callbakc: 回调函数,当事件触发时,函数会被注入一个参数为当前的事件对象 event
    useCapture: 是否以捕获的方式触发,默认为true

  • DOM3级事件
    在DOM2级事件的基础上添加了更多的事件类

DOM事件流

1. 什么是事件流

假如在一个button上注册了一个click事件,又在其它父元素div上注册了一个click事件,那么当我们点击button,是先触发父元素上的事件,还是button上的事件呢,这就需要一种约定去规范事件的执行顺序,就是事件执行的流程。

2. 事件阶段

W3C标准中规定了事件流的三个阶段的顺序:

  • 事件捕获阶段
  • 处于目标阶段
  • 事件冒泡阶段

3. 阻止事件传播

我们要想实现点击某个元素,只触发这个元素本身的事件,而不影响父元素或子元素呢?

所以这里需要一种方法,不让事件向下捕获或向上冒泡

所以有了 e.stopPropagation() 方法,用于阻止事件的继续传递。

执行这条语句,无论我们是使用捕获模式还是冒泡模式,事件都不会继续传递,只会响应我们点击的元素。

4. 事件代理

利用事件冒泡或捕获的机制,我们可以对事件绑定做一些优化。
在JS中,如果我们注册的事件越来越多,页面的性能就越来越差,因为:

  • 函数是对象,会占用内存,内存中的对象越多,浏览器性能越差
  • 注册的事件一般都会指定DOM元素,事件越多,导致DOM元素访问次数越多,会延迟页面交互就绪时间。
  • 删除子元素的时候不用考虑删除绑定事件
    为了减少事件的注册,我们使用一个代理元素来代理它内部所有子元素事件
document.getElementById('wrap').addEventListener('click', function(e){
	if(e.target.classList.contains('box')){
		logerBox.innerHTML += '<p>'+type+': '+e.target.id+'</p>';
	}
}, useCapture)

参考:
DOM事件机制解惑
javaScript 教程-事件

关于层叠上下文(理解 CSS z-index)

层叠上下文【堆叠上下文】

对于堆叠上下文,在MDN中的描述是:
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。 ž 轴即用户与屏幕间看不见的垂直线。

层叠水平【堆叠水平】

层叠水平顺序决定了同一个层叠上下文中元素在ž轴上的显示顺序

层叠顺序【堆叠顺序】

image

层叠准则:

  1. 层叠上下文的水平比普通元素高。
  2. 当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。
  3. 层叠上下文内部嵌套的子元素均受父元素影响。
  4. 层叠上下文不会影响兄弟元素,只会影响后代元素。
  5. 在同一层叠水平上时,有明显的z-index值,则值越大,谁在上。
  6. 使用了css3属性的时候,层叠顺序是跟z-index:auto/z-index:0是一样的,当他们发生层叠的时候,遵循的是“后来居上”准则。

注意:

  1. 普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义。
  2. 如果父元素没有创建层叠上下文的时候,子元素没有受父元素的限制,父子元素是处于同一层叠水平,比较时需要按上面的7层进行比较。
  3. 只设置了position:absolute/relative是不会创建层叠上下文的,此时的div是一个普通元素。
  4. position:fixed在chrome等较高级浏览器中,就算设置为z-index:auto也会创建层叠上下文。

层叠上下文的创建

以下摘自 MDN:

  • 根元素 (HTML)
  • z-index为数值的定位元素
  • css3的属性:
  1. 一个 z-index 值不为 "auto"的 flex 项目 (flex item),其子元素为层叠上下文元素
  2. opacity 属性值小于 1 的元素
  3. transform 属性值不为 "none"的元素
  4. mix-blend-mode 属性值不为 "normal"的元素
  5. filter值不为“none”的元素
  6. perspective值不为“none”的元素
  7. isolation 属性被设置为 "isolate"的元素
  8. position: fixed
  9. 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
  10. -webkit-overflow-scrolling 属性被设置 "touch"的元素

Note: 层叠上下文的层级是 HTML 元素层级的一个层级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素 将被父层叠上下文包含。

相关demo代码

参考资料:
MDN-The stacking context
css层叠上下文【stacking context】和层叠顺序【stacking order】

行——换与不换,关于换行的CSS属性

先看看关于换行的CSS属性吧!

  white-space
    normal: 忽略/合并空白
    pre: 保留空白,如同<pre>的行为
    nowrap: 忽略/合并空白,文本不会换行,直到遇到<br/>
    pre-wrap: 保留空白,但是会正常地进行换行
    pre-line: 忽略/合并空白,但是会正常地进行换行
    inherit: 从父元素继承。
  word-wrap
    normal: 只在允许的断字点换行
    break-word: 在长单词或URL地址内部进行换行
  word-break
    normal:依照亚洲和非亚洲语言的文本规则,允许在单词内换行。
    keep-all:让亚洲语言文本如同非亚洲语言文本那样不允许在任意单词内换行。
    break-all:允许非亚洲语言文本行如同亚洲语言文本那样可以在任意单词内换行。

一个个试一下

1. white-space

image
MDN的这张表格总结了各种 white-space 值的行为:
image

2. word-wrap

image

3. word-break

image

一般情况下,想要换行=使用word-wrap:break-word;就OK了。
另外我们还可以通过word-break:keep-all;white-space:nowrap;word-break:keep-all;white-space:pre;来实现打死都不换行的效果

相关代码:
demo

参考:
CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
彻底搞懂word-break、word-wrap、white-space
(MDN) white-space

《50道CSS基础面试题(附答案)》中的答案真的就只是答案吗?---阅读笔记

1、介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的?

标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin
低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

2、box-sizing属性?

页面渲染时,dom 元素所采用的 布局模型。可通过box-sizing进行设置。根据计算宽高的区域可分为:

  • content-box (W3C 标准盒模型)
  • border-box (IE 盒模型)
  • padding-box(只有Firefox实现了这个值,它在Firefox 50中被删除。)
  • margin-box (浏览器未实现)

3、 CSS选择器有哪些?哪些属性可以继承?

CSS选择符:id选择器(#myid)、类选择器(.myclassname)、标签选择器(div, h1, p)、相邻选择器(h1 + p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel="external"])、伪类选择器(a:hover, li:nth-child)

可继承的属性:font-size, font-family, color

不可继承的样式:border, padding, margin, width, height

优先级(就近原则):!important > style 属性 > id > class > tag
!important 比内联优先级高

4、CSS优先级算法如何计算?

元素选择符: 1
class选择符: 10
id选择符:100
元素标签:1000(内联样式)

!important声明的样式优先级最高,如果冲突再进行计算。
如果优先级相同,则选择最后出现的样式。
继承得到的样式的优先级最低

5、CSS3新增伪类有那些?

p:first-of-type 选择属于其父元素的首个元素
p:last-of-type 选择属于其父元素的最后元素
p:only-of-type 选择属于其父元素唯一的元素
p:only-child 选择属于其父元素的唯一子元素
p:nth-child(2) 选择属于其父元素的第二个子元素
:enabled :disabled 表单控件的禁用状态。
:checked 单选框或复选框被选中。

拓展问题:
::after 和 :after 一个冒号和两个冒号有什么区别

::after表示法是在CSS 3中引入的,::符号是用来区分伪类和伪元素的。支持CSS3的浏览器同时也都支持CSS2中引入的表示法:after。

注: IE8仅支持:after。

浏览器中输入url后发生了什么

浏览器中输入url后发生了什么

1.DNS域名解析;
2.建立TCP连接;
3.发送HTTP请求;
4.服务器处理请求;
5.返回响应结果;
6.关闭TCP连接;
7.浏览器解析HTML;
8.浏览器布局渲染;

image

HTML页面加载和解析流程

image

Window.onload 与 DOMContentLoaded

  • load

MDN的解释:load 应该仅用于检测一个完全加载的页面 当一个资源及其依赖资源已完成加载时,将触发load事件。

意思是页面的html、css、js、图片等资源都已经加载完之后才会触发 load 事件

  • DOMContentLoaded

MDN的解释:当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。

意思是HTML下载、解析完毕之后就触发。

参考:
细说浏览器输入URL后发生了什么
浏览器中输入url后发生了什么
浏览器加载网页时的过程是什么?
再谈 load 与 DOMContentLoaded

面试题整理 --- js基础之箭头函数(不适用的一些场景)

1、对象的方法
2、原型方法
3、事件的回调
4、构造函数

回顾 MDN 给出的解释:箭头函数表达式的语法比函数表达式更短,并且没有自己的this,arguments,super或 new.target。这些函数表达式更适用于那些本来需要匿名函数的地方,并且它们不能用作构造函数。
所以说,箭头函数无疑是 ES6 带来的重大改进,在正确的场合使用箭头函数,能让代码变得更加简洁短小。但箭头函数也不是万能的,不能用的时候,千万别硬往上套。比如,在需要动态上下文的场景中,使用箭头函数需要格外地小心,这些场景包括:对象的方法、原型方法、事件的回调、构造函数。 并非一定要用箭头函数,才能解决问题。

参考:
「前端面试题系列5」ES6 中箭头函数的用法

深入理解js中let与var的区别

有两段关于for循环的代码,区别是一段使用var变量,一段使用let变量

for (var i = 0; i <5; i++) { setTimeout(()=>console.log("i:",i), 1000); } //输出结果:5 5 5 5 5
for (let i = 0; i < 5; i++) { setTimeout(()=>console.log("i:",i), 1000); } //输出结果:0 1 2 3 4 5

为什么输出结果不一样,原因后面再说,先看关于let的一些描述:

let 声明的变量的作用域是块级的(var的作用域是函数级的);

let 不能重复声明已存在的变量(var可以);

let 有暂时死区,虽然有变量提升,但是只提升变量声明 [创建]。

let变量作用域是块级

 function a() {
 for (var i = 0; i <5; i++) { 	
   setTimeout(()=>console.log("i:",i), 1000);
 }	
 console.log(i);	 //5 表明var变量的作用域在整个a函数中
};
a(); //通过setTimeout中的匿名函数引用函数外部变量 i 实际上就是一个闭包的效果
function a() {
 for (let i = 0; i <5; i++) { 	
   setTimeout(()=>console.log("i:",i), 1000);
 }	
 console.log(i);	 //Uncaught ReferenceError: a is not defined 表明let变量的作用域只在for循环代码块中
};
a();

let 不能重复声明已存在的变量(var可以)

  • 在同一个代码块中,声明已存在的let变量会报错
let a =3;
let a =5;
//  Uncaught SyntaxError: Identifier 'a' has already been declared
  • 在同一个作用域中,声明已存在的var变量可以成功

为什么有变量提升

let x = 'global'
{
   console.log(x) // Uncaught ReferenceError: x is not defined
   let x = 1
}

如果变量没有提升,应该就会打印全部的x:'global',所有存在变量提升

既然let有变量提升,为什么在 let x 之前使用 x 会报错,原因有两个

  • console.log(x) 中的 x 指的是下面的 x,而不是全局的 x
  • 执行 log 时 x 还没「初始化」,所以不能使用(也就是所谓的暂时死区)

看到这里,你应该明白了 let 到底有没有提升:

创建一个js变量有三个过程:「创建create、初始化initialize 和赋值assign」

  • let 的「创建」过程被提升了,但是初始化没有提升。
  • var 的「创建」和「初始化」都被提升了。
  • function 的「创建」「初始化」和「赋值」都被提升了。
  • const,其实 const 和 let 只有一个区别,那就是 const 只有「创建」和「初始化」,没有「赋值」过程。

两段倒计时代码打印结果为什么不一致

但是看了这么多,好像还是不太能解释一开始的两段代码为什么不一致啊?
在ES标准中,有一段是关于CreatePerIterationEnvironment,也就是for语句每次循环所要建立环境的步骤,里面有提及有关词法环境的相关步骤(LexicalEnvironment),这与使用let时会有关。所以,如果你使用了let而不是var,let的变量除了作用域是在for区块中,而且会为每次循环执行建立新的词法环境(LexicalEnvironment),拷贝所有的变量名称与值到下个循环执行。以最简单的方式改写原先的问题中的代码,相当于下面这样写:

 for (let i = 0; i <5; i++) { 
  let j = i;	
   setTimeout(()=>console.log("i:", j), 1000);
 }	

这其实也是MDN中介绍let时使用的例子,就是为了方便我们理解let的块级作用域
简单的理解上面所说的就是:
for( let i = 0; i< 5; i++) 这句话的圆括号之间,有一个隐藏的作用域
for( let i = 0; i< 5; i++) { 循环体 } 在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
那样的话,5 次循环,就会有 5 个不同的 i,console.log 出来的 i 当然也是不同的值。
再加上隐藏作用域里的 i,一共有 6 个 i。

参考:
1.怎么理解for循环中用let声明的迭代变量每次是新的变量?
2.我用了两个月的时间才理解 let
3.What's the difference between using “let” and “var” to declare a variable in JavaScript?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.