分享

前端知识点总结 (二)

 ZhouAndrew 2020-08-17


1 怎么让一个不定宽高的div, 垂直水平居中?

有如下代码:

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8' />
    <meta name='viewport' content='width=device-width, initial-scale=1.0' />
    <title>Document</title>
  </head>
  <style>
    .box {
      position: relative;
      width: 300px;
      height: 300px;
      outline: 1px solid black;
      float: left;
      margin: 10px;
    }
    .box > div {
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
  <body>
    <div class='box'>
      <div>1</div>
    </div>
    <div class='box'>
      <div>2</div>
    </div>
    <div class='box'>
      <div>3</div>
    </div>
    <div class='box'>
      <div>4</div>
    </div>
  </body>
</html>
复制代码

效果图:

现在问题来了,在不知道宽高的情况下,我们如何让里面的 div 水平垂直居中呢?

话不多说,上代码😴。

第一种方法:利用 transform

 /* 第一种居中方法 */
.box:nth-of-type(1) > div {
  position: relative;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
复制代码

第二种方法:使用 flex 布局

/* 第二种方法 利用flex布局*/
.box:nth-of-type(2) {
  display: flex;
  justify-content: center;
  align-items: center;
}
复制代码

第三种方法:使用绝对定位,需要在父元素中设置 position: relative;

/* 第三种方法 */
.box:nth-of-type(3) > div {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: pink;
  margin: auto;
}
复制代码

三种方法最后实现效果都是一样的,从代码简洁度来考虑,使用 flex 布局更加简单。

2 清除浮动的常用的方式有哪些?

「正确答案」:为什么要清除浮动?

清除浮动主要是为了解决高度塌陷带来的问题。关于高度塌陷前一期已经讲了。(父元素高度自适应,子元素浮动之后,父元素没有内容撑开高度,会导致父元素的高度为零,这就是高度塌陷)

那么如何清除浮动呢?下面给大家介绍四种方法👇。

① 伪元素清除:

.clearfix:after{    
    display: block;  /* 使其成为块级元素*/
    content: '';    /*为伪元素加入空内容,以便伪元素中不会有内容显示在页面中 */
    height: 0;       /* 为使伪元素不影响页面布局,将伪元素高度设置为0*/
    clear: both;     /* 清除浮动 */
 }
复制代码

② 额外标签法:在浮动元素的最后添加一个块级标签,给其设置一个 clear:both 的属性(缺点:会在页面.上产生很多空白标签) ;

.clearfix>清除浮动的标签{
  clear: both;
}
复制代码

③ 给浮动元素的父元素设置高度: (不太灵活)。

④ 给父元素添加 overflow 属性。

/* overflow属性不是为了清除浮动而定义的,要小心不要覆盖住内容或者触发了不需要的滚动条* /
.clearfix{ 
  overflow:hidden/auto
}  
复制代码

上面四种方法中推荐使用伪元素法

3 typeof 和 instanceof 的区别?

「正确答案」:

function Person(name) {
    this.name = name;
}

Person.prototype.say = function() {
    console.log('My name is' + this.name)
}

var xm = new Person('小明')
复制代码

typeof 可以判断变量的数据类型,返回值是字符串。

typeof(xm.say)  //'function'
复制代码

a instanceof b 可以判断 b 是否在 a 的原型链上(a 是 b 的实例),也可以实现判断数据类型,返回值为布尔值

xm instanceof Person  // true

xm instanceof Object  // true
复制代码

4 怎么判断两个对象相等?

「正确答案」:① 判断两个对象是否指向同一内存。

② 判断两个对象的所有 key 值是否相等相同。(利用 Object.getOwnPropertyNames获取所有键名,不包括原型链上的)

③ 判断两个对象的相应的 key 对应的值是否相同

function ObjectValueEqual(a, b) {
  // 判断两个对象是否指向同一内存,指向同一内存返回true
  if (a === b) return true
  // 获取两个对象键值数组
  let aProps = Object.getOwnPropertyNames(a)
  let bProps = Object.getOwnPropertyNames(b)
  // 判断两个对象键值数组长度是否一致,不一致返回false
  if (aProps.length !== bProps.length) return false
  // 遍历对象的键值
  for (let prop in a) {
    // 判断a的键值,在b中是否存在,不存在,返回false
    if (b.hasOwnProperty(prop)) {
      // 判断a的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回false
      if (typeof a[prop] === 'object') {
        console.log('key中存在对象')
        if (!isObjectValueEqual(a[prop], b[prop])) return false
      } else if (a[prop] !== b[prop]) {
        console.log('两个对象键值不同')
        return false
      }
    } else {
      return false
    }
  }
  return true
}
复制代码

利用上一题的代码

let xh = xm
ObjectValueEqual(xm, xh)  // true

let xl = {name: '小明'}  // false 因为 xm 的原型上有 say 
复制代码

5 Object.keys() 和 Object.getOwnPropertyNames() 的区别

「正确答案」:首先来看一下 MDN 中是如何定义的。

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。

  • 共同点:都是返回自身的属性,不会返回原型链上的。

  • 区别:Object.keys() 返回可枚举的,Object.getOwnPropertyNames() 返回所有的

Person = function(name){
    this.name = name || ''
}

Person.prototype.sayHello = function(){
    console.log('hello')
}

p = new Person('xm')

p.age = 18

// 将 age 修改为不可枚举属性
Object.defineProperties(p, {
    age:{
        enumerable:false
    }
})

console.log(Object.keys(p)) // ['name']
console.log(Object.getOwnPropertyNames(p))  // ['name''age']
复制代码

6 什么是原型对象和原型链?

「正确答案」:① 原型对象

每一个构造函数都有一个 prototype 的属性,这个属性的值是一个对象,这个对象就叫做构造函数的原型对象。一般建议将构造函数的成员属性绑定在原型对象 prototype 上, 因为原型对象 prototype 身上的属性默认可以通过实例对象访问到,这样做可以保证在每次通过new关键字创建实例对象的时候,这些方法不会被重复在内存中创建。

② 原型链

每个构造函数都有一个 prototype 属性,即原型对象。通过实例对象的 _proto_ 属性也可访问原型对象,而原型对象本质也是一个对象,是对象就有自己的原型对象,最终形成的链状的结构称为原型链。

不理解可以看下面两张图。

7 移动端的点击事件有多少秒延时?什么原因造成的?如何解决?

「正确答案」:移动端的点击事件会有300ms的延时。

是什么原因造成的呢?是因为浏览器为了保留双击缩放的功能所造成的,早期浏览器都有一个双击缩放的功能,用户在点击一次后,浏览器会等待第二次点击,如果用户在300ms内进行了第二次点击,那么浏览器就会执行缩放的功能,如果300ms内没有再次点击,则会当做单击事件处理。

那么如何解决呢?

① 使用touch触摸事件来模拟点击事件。

② 使用Fastclick插件来解决。(FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟click 事件的click事件(自定义事件),并把浏览器在 300 毫秒之后真正触发的 click 事件阻止掉。)

window.addEventListener( 'load'function() {
   FastClick.attach( document.body );
}, false );

复制代码

③ 禁止页面缩放功能。

<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0'>


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多