Git Product home page Git Product logo

owenli_blog's People

Contributors

jesuslove avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

owenli_blog's Issues

如何实现 CSS 半透明边框?

background-clip 实现半透明边框?

如何实现半透明颜色,如何控制背景的侵入行为?

半透明颜色

CSS 中实现半透明颜色方法:rgba()hsla()

PS: HSLA(H, S, L, A)
H:
Hue(色调)。0(或360)表示红色,120表示绿色,240表示蓝色,也可取其他数值来指定颜色。取值为:0 - 360
S:
Saturation(饱和度)。取值为:0.0% - 100.0%
L:
Lightness(亮度)。取值为:0.0% - 100.0%
A:
Alpha透明度。取值0~1之间。

使用 background-clip 控制背景的侵入方式。

默认情况下:background-clip 取值 border-box,背景被元素的边框外沿裁切掉。如图1-1。可以设置为 padding-box,沿着内边框外沿裁切。如图1-2。

实现代码

.container {
  width: 200px;
  height: 200px;
  background: red;
}
/* 默认:侵入 border-box 图1-1*/
.demo-1 {
  border: 20px solid hsla(0, 0%, 100%, 0.2);
}
/* 图1-2 */
.demo-2 {
  border: 20px solid hsla(0, 0%, 100%, 0.2);
  /* // 设置背景的侵入方式。 */
  background-clip: padding-box;
}

图1-1
1-1
图1-2
1-2

如何实现一个深拷贝?

image

思维导图

实现深拷贝:

  1. 基本实现方法:递归 + 浅拷贝
  2. 处理数组和循环引用
  3. 处理 Symbol 拷贝
  4. 处理递归爆栈问题

处理问题 1 和 2

function isObject(obj) {
  return typeof obj === 'object' && obj != null
}
function deepCopy(source, hash = new WeakMap()) {
  // 验证:非对象 或者 Null 直接返回
  if (!isObject(source)) return source
  // 使用 WeakMap 解决循环引用,使用过的存放在 WeakMap 中
  if (hash.has(source)) return hash.get(source) // 重新哈希表
  // 数组处理
  const target = Array.isArray(source) ? [] : {}
  // 缓存
  hash.set(source, target) // 设置哈希表值

  for (let key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      if (isObject(source[key])) {
        target[key] = deepCopy(source[key], hash)
      } else {
        target[key] = source[key]
      }
    }
  }
  return target
}

使用 Hash 表解决寻源应用的问题,将使用过的内容缓存起来,下次使用的时候直接读取。

处理问题 3

// 1. 使用 Object.getOwnPropertySymbols(...) 获取 Symbol 属性数组
function deepCopy2(source, hash = new WeakMap()) {
  if (!isObject(source)) return source

  if (hash.has(source)) return hash.get(source)

  const target = Array.isArray(source) ? [] : {}

  hash.set(source, target)

  // 处理 Symbol
  const symKeys = Object.getOwnPropertySymbols(source)

  if (symKeys.length) {
    symKeys.forEach(symKey => {
      if (isObject(source[symKey])) {
        target[symKey] = deepCopy2(source[symKey], hash)
      } else {
        target[symKey] = source[symKey]
      }
    })
  }
  // 处理正常情况
  for (let key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      if (isObject(source[key])) {
        target[key] = deepCopy2(source[key], hash)
      } else {
        target[key] = source[key]
      }
    }
  }
  return target
}

// 2. 使用 Reflect.ownKeys 处理 Symbol 属性
function deepCopy22(source, hash = new WeakMap()) {
  
  if (!isObject(source)) return source
  if (hash.has(source)) return hash.get(source)

  const target = Array.isArray(source) ? [] : {}

  hash.set(source, target)

  Reflect.ownKeys(source).forEach(key => {
    if (isObject(source[key])) {
      target[key] = deepCopy22(source[key], hash)
    } else {
      target[key] = source[key]
    }
  })
  return target
}

迭代解决递归爆栈

function deepCopy3(source) {
  if (!isObject(source)) return source
  const root = {}
  const queue = [
    {
      parent: root,
      key: undefined,
      source
    }
  ]
  while (queue.length) {
    // 广度优先
    const node = queue.pop()
    const { parent, key, source } = node
    let res = parent
    if (typeof key !== 'undefined') {
      res = parent[key] = Array.isArray(source) ? [] : {}
    }
    Reflect.ownKeys(source).forEach(key => {
      if (isObject(source[key])) {
        queue.push({
          parent: res,
          key,
          source: source[key]
        })
      } else {
        res[key] = source[key]
      }
    })
  }
  return root
}

参考

面试题之如何实现一个深拷贝?

防抖、节流、分段函数

防抖(debounce)

防抖:任务在频繁触发的情况下,只有触发的时间间隔超过指定时间,才会真正的执行。例如:输入框实时搜索。

/**
 * 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
 */
function debounce(func, wait = 500, immediate = false) {
  let timer, result
  return function() {
    // 清空定时器
    timer && clearTimeout(timer)
    if (immediate) {
      !timer && (result = func.apply(this, arguments))
    } else {
      // this 指向 和 event 指向; => 和 apply
      timer = setTimeout(() => {
        result = func.apply(this, arguments)
      }, wait)
    }
    return result
  }
}

节流(throttle)

节流:函数在指定的时间间隔内只执行一次。

/**
 * 高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
 */
// 反转标志位
function throttle(func, wait) {
  let isOK = true // 标志位
  return function() {
    if (!isOK) return
    isOK = false
    setTimeout(() => {
      func.apply(this, arguments)
      isOK = true
    }, wait);
  }
}

定时器实现

var throttle = function(fn, interval) {
    var self = fn,timer,firstTime = true
    return function() {
      var args = arguments
      // 首次
      if (firstTime) {
        self.apply(this, args)
        return firstTime = false
      }
      if (timer) return false // 定时器还在,说明前一次还没有结束

      timer = setTimeout(() => { // 延迟一段时间后执行
        clearTimeout(timer)
        timer = null
        self.apply(this, args)
      }, interval || 500)
    }
  }

分段函数

思路:例如,创建 10000 个对象,分组创建一次创建 10 个,防止卡顿。

// 分时函数
/**
 *
 * @param {*} datas 数据源数组
 * @param {*} fn 方法
 * @param {*} count 数量
 */
let timeChunk = function (datas = [], fn, count = 1) {
  const length = datas.length
  // 执行方法
  let start = function () {
    for (let i = 0; i < Math.min(count, length); i++) {
      let obj = datas.shift() // 每次取一个 执行 fn
      fn(obj)
    }
  }
  return function () {
    let timer = setInterval(() => {
      if (length === 0) {
        clearInterval(timer) // 全部数据创建完成
      }
      start()
    }, 1000) // 分段执行的间隔时间
  }
}

call & apply 模拟实现

Call 模拟实现

思路:把函数当做对象的属性,执行函数后,删除该属性。

Function.prototype.call2 = function (context) {
    // context 为 null  指向 window  对象
    var context = context || window;
   //  fn 指向该函数
    context.fn = this;
  // 处理 arguments
    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
   // 使用 eval 执行 fn 
    var result = eval('context.fn(' + args +')');
  // 删除 fn 属性
    delete context.fn
  // 返回执行结果
    return result;
}

Apply 模拟实现

Function.prototype.apply = function (context, arr) {
    var context = Object(context) || window;
    context.fn = this;

    var result;
    if (!arr) {
        result = context.fn();
    }
    else {
        var args = [];
        for (var i = 0, len = arr.length; i < len; i++) {
            args.push('arr[' + i + ']');
        }
        result = eval('context.fn(' + args + ')')
    }

    delete context.fn
    return result;
}

CSS 实现居中的常用方法

目录

  • flexbox 实现元素居中
  • CSS transform 元素居中
  • 使用 margin: 0 auto; 实现水平居中
  • text-align 文本居中
  • 使用 position: absolute 绝度定位实现居中
  • 使用 calc() 函数实现居中
  • line-height 单行文本居中
  • 三行代码实现任意元素垂直居中

1、使用 flexbox 实现水平垂直居中

HTML:

<div class="container">
  <div class="element"></div>
</div>

CSS:

.container {
  height: 300px;
  display: flex;
  justify-content: center; // 水平居中
}
.element {
  align-self: center; // 垂直居中
}

或者

.container {
  height: 300px;
  display: flex;
  justify-content: center; // 水平居中
  align-items: center; // 垂直居中
}

兼容问题

Flexbox 是 CSS3 中被引入,意味着它是相对较新的技术没有被所有的浏览器支持。

支持情况如下:

  • IE8 和 9 不支持 flexbox。如果想用 flex 属性,需要使用 flexbox polyfill 实现,不过嘛,效果差了点不在维护了。
  • IE10 支持 flexbox 的早起版本,需要使用供应商前缀。不支持 flex-grow,flex-shrink 和 flex-basis等属性。
  • IE11 支持当前的 flexbox 标准,不过有 bug。
  • Chrome、Firefox 和 Edge 支持。
  • Safari 9+ 支持 flexbox 不需要前缀。低版本需要加 -webkit 前缀。

关于 flexbox 支持问题可以参考这个问题

参考 Flexbox浏览器支持 - stackoverflow

在线演示-CodePen

2、CSS transform

transform 是基于元素大小的属性,不需要知道元素的宽高。

.container {
  position: relative;
}
.element {
  position: absolute; // 绝对定位
  top: 50%; 
  left: 50%;
  transform: translate(-50%, -50%);
}

兼容问题

translate 属性需要添加前缀支持旧浏览器。IE8及更低版本不支持。

-webkit-transform: translate(-50%, -50%); /* Chrome, Safari, Opera, Android */ 
    -ms-transform: translate(-50%, -50%); /* IE 9 */
        transform: translate(-50%, -50%);
在线演示-CodePen

3、使用 margin: 0 auto; 实现水平居中

<div class="container">
  <div class="element"></div>
  <img class="element-image"
src="https://www.baidu.com/img/superlogo_c4d7df0a003d3db9b65e9ef0fe6da1ec.png?where=super" />
</div>

CSS

/* 
  margin: 0 auto; 居中布局
*/
.element {
  margin: 0 auto; 
}
.element-image {
  display: block;
  width: 200px;
  border: 1px solid red;
  margin: 0 auto;
}

4、text-align 文本居中

最简单的元素文本居中使用 text-align:center 属性。

<p>Lorem ipsum</p>

CSS :

p {
    text-align:  center;
}

5、使用 position: absolute 绝度定位实现居中

<div class="container">
  <img src="https://www.baidu.com/img/superlogo_c4d7df0a003d3db9b65e9ef0fe6da1ec.png?where=super" alt="">
</div>

CSS:

// 布局 
.container {
  position: relative;
  height: 500px;
}
// 需要有初始的宽高
img {
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
}
在线演示-CodePen

6、使用 calc() 函数实现居中

<div class="container">
  <div class="center"></div>
</div>

CSS:

.container {
  height: 300px;
  background-color: #5CC9F5;
  position: relative;
}

.center {
  position: absolute;
  height: 100px;
  width: 100px;
  background-color: #F78AE0;
  top: calc(50% - 100px / 2); // height 的二分之一
  left: calc(50% - 100px / 2); // width 二分之一
}

PS: calc()CSS3 新语法的一部分,可以计算元素的大小和位置,只可以是像素、百分比等。注意使用时需要注意空格问题,两个值之间必须要空格。

在线演示-CodePen

7、line-height 单行文本居中

line-height 实现元素中 单行文本 的垂直居中。

<div class="container">
   line-height 实现文本垂直居中
</div>

CSS

.container {
  height: 100px;
  background-color: #5CC9F5;
  line-height: 100px;
}

PS: 文本换行时,结果并没有居中。

在线演示-CodePen

8、三行代码实现任意元素垂直居中

<div class="parent">
  <div class="vertical">Vertical aligned text!</div>
</div>

CSS

// 父容器设置高度
.parent {
  height: 200px;
  background-color: #5CC9F5;
}
.vertical {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}

PS: 使用三行代码实现垂直居中,只要设置父容器高度。

在线演示-CodePen

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.