前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CSS的BFC和Vue的一个函数

CSS的BFC和Vue的一个函数

作者头像
terrence386
发布2022-07-14 21:21:33
3750
发布2022-07-14 21:21:33
举报

云中的神啊,雾中的仙,神姿仙态桂林的山。这首诗是小时候背过的《桂林山水歌》。

前情回顾

上篇文章聊了下vue源码中的生命周期。有时候我觉的看源码其实是在浪费时间,今天聊一下css中的BFC和今天看的Vue里的一个比较有意思的函数。

BFC 块儿格式化上下文

块元素布局过程的区域,也是浮动元素与其他元素交互的区域。可以理解为设置块元素属性的过程。从如何创建bfc来看,bfc的过程主要发生在块元素布局的过程

什么样的操作会创建BFC?
  • 根元素html
  • 使用浮动float
  • 使用绝对定位position:absuote|fixed
  • 使用行内块display:inline-block
  • 使用overflow
  • 使用display:flow-root
  • 弹性布局display:flex|inline-flex
  • 网格布局display:grid|inline-grid
  • 表格布局display:table|table-cell
BFC相关的Bug
  • 浮动元的父元素高度塌陷处理这个问题通常是给父元素加一个overflow。overflow会创建一个新的BFC,将子元素包含进去。 另外一个方法是使用display:flow-root。它可以创建无副作用的BFC,中的所有内容都会参与 BFC,浮动的内容不会从底部溢出。
  • 外边距重合

CSS如何工作?

  • 浏览器载入HTML
  • html转为DOM,DOM是文件在计算机内存中的表现形式。
  • 浏览器会拉取该HTML相关的大部分资源,比如嵌入到页面的图片、视频和CSS样式。
  • 拉取到css之后进行解析。基于选择器规则
  • 渲染树进行布局
  • 展示到网页上

当css遇到无法解析的属性或值时,会忽略并继续执行下一个解析

CSS shape 形状

css 其实是可以直接设置形状的。这个有一篇文章写得非常好。回头我找一下看看。

隐藏元素的六种方法

  • display:none
  • vusibility:hidden
  • opacity:0
  • clip-path:inset(100%)
  • html的hidden属性
  • html的aria-hidden属性
代码语言:javascript
复制
/*******************************************************************************\
 *                                                                             *
 * Visually hide any element (mostly text) accessibly.                         *
 * Support includes IE9+                                                       *
 * Source: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html   *
 *                                                                             *
 *******************************************************************************/

.sr-only {
    clip: rect(0 0 0 0);
    clip-path: inset(100%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap; 
    width: 1px;
}

display:nonevusibility:hidden会将元素从dom中移除,尽量不使用。

那个有意思的函数generateCodeFrame

src/complier/codeframe.js

代码语言:javascript
复制

const range = 2

export function generateCodeFrame (
  source: string,
  start: number = 0,
  end: number = source.length
): string {
  const lines = source.split(/\r?\n/)
  let count = 0
  const res = []
  for (let i = 0; i < lines.length; i++) {
    count += lines[i].length + 1
    if (count >= start) {
      for (let j = i - range; j <= i + range || end > count; j++) {
        if (j < 0 || j >= lines.length) continue
        res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}|  ${lines[j]}`)
        const lineLength = lines[j].length
        if (j === i) {
          // push underline
          const pad = start - (count - lineLength) + 1
          const length = end > count ? lineLength - pad : end - start
          res.push(`   |  ` + repeat(` `, pad) + repeat(`^`, length))
        } else if (j > i) {
          if (end > count) {
            const length = Math.min(end - count, lineLength)
            res.push(`   |  ` + repeat(`^`, length))
          }
          count += lineLength + 1
        }
      }
      break
    }
  }
  return res.join('\n')
}

function repeat (str, n) {
  let result = ''
  if (n > 0) {
    while (true) { // eslint-disable-line
      if (n & 1) result += str
      n >>>= 1
      if (n <= 0) break
      str += str
    }
  }
  return result
}

这个函数会将接受到的source字符串按照回车键及换行符分割。然后生成一个字符串模板。比如你在文件里写的代码是:

代码语言:javascript
复制
  <template>
    <div>测试</div>
  </template>

它会返回一个类似的

代码语言:javascript
复制
1  |  <template>
   |  ^^^^^^^^^^
2  |          <div>测试</div>
   |  ^^^^^^^^^^^^^^^^^^^^^
3  |        </template>
   |  ^^^^^^^^^^^^^^^^^

如果你写的是js代码:

代码语言:javascript
复制
  function test() {
    console.log('test')
  }

它会返回一个类似的:

代码语言:javascript
复制
1  |  function test() {
   |  ^^^^^^^^^^^^^^^^^
2  |          console.log('test')
   |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
3  |        }
   |  ^^^^^^^

刚开始我一直在想找个函数有什么用,似乎确实是没啥用。然后我找到了如下代码:

代码语言:javascript
复制
 // check compilation errors/tips
    if (process.env.NODE_ENV !== 'production') {
      if (compiled.errors && compiled.errors.length) {
        if (options.outputSourceRange) {
          compiled.errors.forEach(e => {
            warn(
              `Error compiling template:\n\n${e.msg}\n\n` +
              generateCodeFrame(template, e.start, e.end),
              vm
            )
          })
        } else {
          warn(
            `Error compiling template:\n\n${template}\n\n` +
            compiled.errors.map(e => `- ${e}`).join('\n') + '\n',
            vm
          )
        }
      }
  
    }

说明这个generateCodeFrame是为了在编译出错的时候给出相应的提示。

总结

BFC块儿格式化上下文,其实是块儿元素尤其是块元素在布局过程中衍生出来的一个概念。而重点是元素布局的常见方法,浮动、定位、弹性、网格。

而对于这个函数,在我们的代码编译出错时,控制台及页面上的错误信息就是这个函数的返回结果。

javascript基础知识总结

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JavaScript高级程序设计 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前情回顾
  • BFC 块儿格式化上下文
    • 什么样的操作会创建BFC?
      • BFC相关的Bug
      • CSS如何工作?
      • CSS shape 形状
      • 隐藏元素的六种方法
      • 那个有意思的函数generateCodeFrame
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档