每日1个前端知识点

201 阅读9分钟

工作日每天一道项目开发过程中的前端知识点总结,一年后再回头,会感谢曾经努力的自己!


第1题 js每隔一秒打印1,2,3,4,5

方法一: 自执行函数

for (var i=0; i<5; i++) {
  //闭包
  (function (i) {
    setTimeout(() => console.log(i), 1000*i)
  })(i)
}

方法二: es6块级作用域let

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

方法三:传址传递

var out = (i) => {
  setTimeout (() => console.log(i), 1000*i)
}
for (var i=0; i<5; i++) {
  out(i)
}

方法四: Promise.all()方法

var arr = []
var output = (i) => new Promise(res => {
  setTimeout(()=>{
    console.log(i)
    res()
  }, 1000*i)
})
for (var i=0; i<5; i++) {
  arr.push(output(i))
}
Promise.all(arr).then(()=> console.log(5))

方法五:async await方法

var sleep = () => new Promise (res => setTimeout(res, 1000))
async function count () {
  for (let i=0; i<5; i++) {
    await sleep()
    console.log(i)
  }
}
count()
function sleep(){
  return new Promise((resolve)=>{
    setTimeout(resolve,1000);
  })
}
async function count(){
  for(let i=0;i<5;i++){
    await sleep();
    console.log(i)
  }
}
count()

方法6:setInterval

function count(num, time) {
  var i = 0;
  var fn = setInterval(function () {
    console.log(i++);
    if (i >= num) {
      clearInterval(fn);
    }
  }, time * 1000);
}
count(5, 1);

第2题 利用animation制作文字遮罩动画效果

 h1{
  font-size:60px;
  background: url(bg.jpg) repeat;
  -webkit-background-clip:text;
  -webkit-text-fill-color:transparent;
  animation:fn 5s alternate infinite;
}
@keyframes fn{
  0%{
      background-position:0px 0px;
  }
  20%{
      background-position:30% 0px;
  }
  50%{
      background-position:50% 0px;
  }
  70%{
      background-position:70% 0px;
  }
  100%{
      background-position:100% 0px;
  }
}

第3题 title为渐变色且颜色一致在变化

.title{
  color: #f35626;
  background-image: linear-gradient(92deg, #f35626 0%,#feab3a 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: hue 60s infinite linear;
}

@keyframes hue {
  from {
    filter: hue-rotate(0deg);
  }
  
  to {
    filter: hue-rotate(-360deg);
  }
}

第4题 CSS3 之text-fill-color属性

text-fill-color是设置指定文字的填充颜色。 若同时设置 和 , < text-fill-color >定义的颜色将覆盖< color > 属性

注意:background-clip必须放在background后面不然不起作用,之所以要用background是因为text-fill-color不能使用linear所以只好借助background了。

background-clip:text会将背景作为文字区域裁剪。

text-fill-color可以实现渐变色字体和镂空字体,具体如下:

渐变色字体
<p class="font1">你好,这是我的渐变色字体</p>
.font1{
  font-size:22px;
  background-image: -webkit-linear-gradient(bottom, red, blue);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  display:inline-block; // 为了渐变全部应用到字体上
}
镂空字体
.font1{
  font-size:32px;
  -webkit-text-fill-color: transparent;
  -webkit-text-stroke:1px #000;
 }

第5题 CSS3 Filter详解(改变模糊度 亮度 透明度等方法)

CSS3 Filter(滤镜)属性提供了提供模糊和改变元素颜色的功能。CSS3 Fitler 常用于调整图像的渲染、背景或边框显示效果。

-webkit-filter是css3的一个属性,Webkit率先支持了这几个功能

现在规范中支持的效果有:

  • grayscale 灰度 值为0-1之间的小数
  • sepia 褐色       值为0-1之间的小数
  • saturate 饱和度     值为num
  • hue-rotate 色相旋转  值为angle
  • invert 反色       值为0-1之间的小数
  • opacity 透明度     值为0-1之间的小数
  • brightness 亮度     值为0-1之间的小数
  • contrast 对比度     值为num
  • blur 模糊       值为length
  • drop-shadow 阴影

demo查看

  1. 模糊
-webkit-filter: blur(9px);
filter: blur(9px);
  1. 灰度
-webkit-filter: grayscale(1);
filter: grayscale(1);
  1. 亮度
-webkit-filter: brightness(2.3);
filter: brightness(2.3);
  1. 对比度
-webkit-filter: contrast(4.4);
filter: contrast(4.4);
  1. 饱和度
-webkit-filter: saturate(3.6);
filter: saturate(3.6);
  1. 色相旋转
-webkit-filter: hue-rotate(185deg);
filter: hue-rotate(185deg);
  1. 反色
-webkit-filter: invert(1);
filter: invert(1)
  1. 阴影
-webkit-filter: drop-shadow(0px 0px 5px #000);
filter: drop-shadow(0px 0px 5px #000);
  1. 透明度
-webkit-filter: opacity(55%);
filter: opacity(55%);
  1. 褐色
-webkit-filter: sepia(0.77);
filter: sepia(0.77);

第6题 JSON.stringify(value[, replacer [, space]])

  • value 将要序列化成 一个JSON 字符串的值。

这是第一个参数,应该都不陌生,最常用的也是这个。其他两个基本用不到。

一般传入一个对象。但是不仅仅如此,还可以传入其他值哦。

  • replacer | 可选 可以三种类型的值:
    • 函数,在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理
    • 数组,只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中
    • null或者未提供,对象所有的属性都会被序列化

一般情况下,我们都不传,按第3种方式处理。

  • space | 可选 指定缩进用的空白字符串,用于美化输出。

可以指定三种类型的值:

  • 数字,代表有多少的空格。上限为10,该值若小于1,则意味着没有空格。
  • 字符串,字符串的前十个字母,该字符串将被作为空格。
  • null或者未提供,将没有空格。

一般情况下,我们都不传,按第3种方式处理。

返回值 一个表示给定值的 json 字符串。

第7题 delete操作符返回一个布尔值: true指删除成功,否则返回false.

const name = "Lydia";
age = 21;

console.log(delete name);
console.log(delete age);
// false true

delete操作符返回一个布尔值: true指删除成功,否则返回false. 但是通过 var, const 或 let 关键字声明的变量无法用 delete 操作符来删除

name变量由const关键字声明,所以删除不成功:返回 false. 而我们设定age等于21时,我们实际上添加了一个名为age的属性给全局对象。对象中的属性是可以删除的,全局对象也是如此,所以delete age返回true.

第9题 import引入的模块是 只读 的: 你不能修改引入的模块

// counter.js
let counter = 10;
export default counter;

// index.js
import myCounter from "./counter";
myCounter += 1;
console.log(myCounter);
// 打印的值:Error

引入的模块是 只读 的: 你不能修改引入的模块。只有导出他们的模块才能修改其值。

当我们给myCounter增加一个值的时候会抛出一个异常: myCounter是只读的,不能被修改。

第10题 值和对象的传递赋值


function getInfo(member, year) {
  member.name = "Lydia";
  year = "1998";
}

const person = { name: "Sarah" };
const birthYear = "1997";

getInfo(person, birthYear);

console.log(person, birthYear);
// A: { name: "Lydia" }, "1997"

普通参数都是 值 传递的,而对象则不同,是 引用 传递。所以说,birthYear是值传递,因为他是个字符串而不是对象。当我们对参数进行值传递时,会创建一份该值的 复制

变量birthYear有一个对"1997"的引用,而传入的参数也有一个对"1997"的引用,但二者的引用并不相同。当我们通过给 year赋值"1998"来更新year的值的时候我们只是更新了year(的引用)。此时birthYear仍然是"1997".

而person是个对象。参数member引用与之 相同的 对象。当我们修改member所引用对象的属性时,person的相应属性也被修改了,因为他们引用了相同的对象. person的 name属性也变成了 "Lydia".

第11题 VUE中nextTick的用途

官网说法:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

VUE异步更新队列:vue是依靠数据驱动视图更新的,该更新的过程是异步的。即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新队列)。视图需要等队列中所有数据变化完成之后,再统一进行更新

个人理解:需要在视图更新之后,基于新的视图进行操作。

  • 获取更新之后的DOM
  • 如果要在created()钩子函数中进行的DOM操作,由于created()钩子函数中还未对DOM进行任何渲染,所以无法直接操作,需要通过$nextTick()来完成
  • 更新数据后,想要使用js对新的视图进行操作时
  • 在使用某些第三方插件时 ,这些插件需要dom动态变化后重新应用该插件,这时候就需要使用$nextTick()来重新应用插件的方法

因为 $nextTick() 返回一个 Promise 对象,所以我们也可以使用async/await语法完成相同的事情:

<div id="myApp">
    <input type="button" value="点我呀" @click="changeStr">
    <p ref="myP">{{str}}</p>
</div>
<script>
    new Vue({
        el:"#myApp",
        data:{
            str:"初始化内容!"
        },
        methods:{
            changeStr(){
                this.str = "changed 过的内容 !";
                // 输出结果:初始化内容!
                console.log(this.$refs.myP.innerText)
            },
            changeStr(){
              this.str = "changed 过的内容 !";
              // 我们可以通过$nextTick() 获取到更新之后的DOM
              this.$nextTick(()=>{
                  // 输出结果:我爱你中国,我亲爱的母亲!
                  console.log(this.$refs.myP.innerText);
              });
              this.str = "我爱你中国,我亲爱的母亲!"
            },
            changeStr3:async function(){
                this.str = "changed 过的内容!";
                this.str = "我爱你中国,我亲爱的母亲!"
                await this.$nextTick();
                console.log(this.$refs.myP.innerText);
            },
            changeStr4(){
                this.str = "changed 过的内容!";
                this.$nextTick().then(()=>{
                    // 输出结果:我爱你中国,我亲爱的母亲!
                    console.log(this.$refs.myP.innerText);
                });
                this.str = "我爱你中国,我亲爱的母亲!"
            }          
        }
    })
</script>
<div id="app">
  <input ref="input" v-show="inputShow">
  <button @click="show">show</button>  
 </div>

export default { 
 data() {
   return {
     inputShow: false
   }
  },
  methods: {
    show() {
      this.inputShow = true
      this.$nextTick(() => {
        this.$refs.input.focus()
      })
    }
  }
}

第12题 金额千分位并保留2位小数

export function toThousandFilter(num) {
  if (!num) {
    return ''
  }
  return (+num).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); //使用正则替换,每隔三个数加一个',';
  // return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}

第13题 Vue定义filter

import * as filters from './filters' // global filters
// register global utility filters
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

第14题 input[file]安卓机下掉不起来摄像头

当写<input type="file">的时候,在ios下可以成功掉起拍照和图库2块,在Android手机上只能调取图库而没有拍照功能

解决办法:在input上加上accept属性,加上了capture='camera'属性之后的安卓手机就直接调用了拍照,没有了图库的功能

<input type="file" accept="iamge/*" capture="camera"> //相机
<input type="file" accept="video/*" capture="camcorder"> //视频
<input type="file" accept="audio/*" capture="microphone"> //音频

注:capture表示,可以捕获到系统默认的设备,如camera 照相,camcorder 摄像,microphone 录音。

第15题 javascript中apply、call和bind的区别

在JS中,这三者都是用来改变函数的this对象的指向的。

三者的相似之处:

  1. 都是用来改变函数的this对象的指向的。
  2. 第一个参数都是this要指向的对象。
  3. 都可以利用后续参数传参。

三者的区别:

  1. call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以
  2. call后面的参数与方法中是一一对应的,而apply的第二个参数是一个数组
  3. bind可以像call那样传参,还可以在调用的时候再进行传参
var xw = {
  name : "小王",
  gender : "男",
  age : 24,
  say : function(school,grade) {
          alert(this.name + " , " + this.gender + " ,今年" + this.age + " ,在" + school + "上" + grade);                                
  }
}
var xh = {
  name : "小红",
  gender : "女",
  age : 18
}
// 对于call来说是这样的
xw.say.call(xh,"实验小学","六年级");  
//而对于apply来说是这样的
xw.say.apply(xh,["实验小学","六年级"]);     
// bind传参
xw.say.bind(xh,"实验小学","六年级")();
xw.say.bind(xh)("实验小学","六年级");

第16题 parseInt只返回了符串中第一个字母

const num = parseInt("7*6", 10);
// num = 7

只返回了字符串中第一个字母. 设定了 进制 后 (也就是第二个参数,指定需要解析的数字是什么进制: 十进制、十六机制、八进制、二进制等等……),parseInt 检查字符串中的字符是否合法. 一旦遇到一个在指定进制中不合法的字符后,立即停止解析并且忽略后面所有的字符。

*就是不合法的数字字符。所以只解析到"7",并将其解析为十进制的7. num的值即为7.