• HTML&CSS面试高频考点(三)


     【面试 · 回看】

    ♥HTML&CSS面试高频考点(一)

    ♥HTML&CSS面试高频考点(二)

    11. CSS隐藏元素的方式

    /*占据空间,无法点击*/
    visibility: hidden;
    position: relative; top: -999em;
    
     /* 不占据空间,无法点击 */
    position: absolute; top: -999em; 
    display: none; 
    position: absolute; visibility: hidden; 
    height: 0; overflow: hidden; 
    
    /*可以点击*/
    opacity: 0; filter:Alpha(opacity=0); /* 占据空间,可以点击 */
    position: absolute; opacity: 0; filter:Alpha(opacity=0); /* 不占据空间,可以点击 */

    => display: none; 和 visibility: hidden; 的区别?

    1. display: none; 元素消失,也不再占据空间;visibility: hidden; 元素消失但仍然占据空间;
    2. visibility具有继承性,其子元素也会继承此属性,若给子元素设置visibility:visible,则子元素会显示;
    3. visibility不会影响计数器的计算,虽然隐藏掉了,但是计数器依然继续运行着;
    4. 在css3的transition中支持visibility属性,但是不支持display,因为transition可以延迟执行,因此配合visibility使用纯css实现hover延时显示效果可以提高用户体验;
    5. display:none会引起回流(重排)和重绘 visibility:hidden只会引起重绘。

    opacity:0 只是让内容不可见,透明度为0,在渲染树中,在dom文档中仍旧占领位置,子元素也不会展示,而且子元素不能通过设置opacity:1来展示,元素的点击事件可用。

    重绘重排

    重绘重排是由于浏览器再次渲染引起的,首先了解浏览器的渲染过程。

    渲染引擎会解析HTML文档来构建DOM树,同时用CSS解析器解析CSS文档构建CSSOM树。接下来将两者关联起来构成渲染树(RenderTree),这一过程称为Attachment。然后浏览器按照渲染树进行布局(Layout),最后一步通过绘制显示出整个页面。

    • 重排(回流):render tree中的一部分因元素的规模尺寸、布局、隐藏等改变需要重新构建。页面第一次加载的时候必须进行一次回流。回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分树。
    • 重绘:完成回流后,浏览器重新绘制受影响的部分到屏幕中。

    回流必定引起重绘,而重绘不一定引起回流。

    回流导致渲染树需要重新计算,开销较大,所以要尽量避免回流。

    重绘的产生:更新只影响元素的外观、风格,而不影响布局的属性。eg: visibility, outline, 背景颜色等。

    避免回流的方法

    1. 样式集中改变(老版本才有的问题,现代浏览器已有Flush队列进行渲染队列优化);
    2. 缓存布局信息;
    3. position属性为absolute或fixed的元素,回流开销比较小;
    4. 使用DocumentFragment,让要操作的元素进行“离线处理”。

    12. Flex布局

    ♥前文介绍

    13. 双栏布局 三栏布局

    ♥两列布局

    三列布局:

    (1)浮动解决方案

    .layout1 .left{
        float: left;
    }
    .layout1 .right{
        float: right;
    }

    (2)绝对定位解决方案

    .layout2 .left-center-right>div{
        position: absolute;
    }
    .layout2 .left{
        left: 0;
        width: 300px;    
    }
    .layout2 .center{
        left: 300px;
        right: 300px;  //定左右栏的宽度
    }
    .layout2 .right{
        right: 0;
        width: 300px;
    }

    (3)Flex布局

    .layout3 .left-center-right{
        display: flex;
    }
    .layout3 .left{
        width: 300px;
    }
    .layout3 .center{
        flex:1;
    }
    .layout3 .right{
        width: 300px;
    }

    (4)表格布局

    .layout4 .left-center-right{
        width: 100%;
        display: table;
        height: 100px; //高度会跟着变
    }
    .layout4 .left-center-right>div{
        display: table-cell;
    }
    .layout4 .left{
        width: 300px;
    }
    .layout4 .right{
        width: 300px;
    }

    在高度不已知的情况下3,4仍能使用(会自动撑开)。

    14. 重排和重绘

    *前面有提到哟~

    触发重排的机制

    1. 添加或删除可见的DOM元素
    2. 元素位置改变
    3. 元素本身的尺寸发生改变
    4. 内容改变
    5. 页面渲染器初始化
    6. 浏览器窗口大小发生改变

    性能优化

    下面这段代码,会使浏览器发生三次重排:

    var el = document.querySelector('.el');
    el.style.borderLeft = '1px';
    el.style.borderRight = '2px';
    el.style.padding = '5px';

    如果能够合并为一次处理,这样DOM就只修改节点一次。这样最小化的方式有两种:

    (1)使用cssText属性

    var el = document.querySelector('.el');
    el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px';

    (2)改变类名

    // css 
    .active {
        padding: 5px;
        border-left: 1px;
        border-right: 2px;
    }
    // javascript
    var el = document.querySelector('.el');
    el.className = 'active';

    最小化的方式适合修改单个节点的情况。当需要批量修改节点的时候,则需要换一种方式:

    (1)隐藏元素,进行修改后,然后再显示该元素

    let ul = document.querySelector('#mylist');
    ul.style.display = 'none';
    appendNode(ul, data);
    ul.style.display = 'block';

    发生了两次重排,分别是隐藏和显示的时候。

    (2)使用文档片段创建一个子树,然后再拷贝到文档中

    let fragment = document.createDocumentFragment();
    appendNode(fragment, data);
    ul.appendChild(fragment);

    只在将文档片段的子节点群插入的时候发生了一次重排。且不会造成元素短暂消失的逻辑问题。

    (3)将原始元素拷贝到一个独立的节点中,操作这个节点,然后覆盖原始元素

    let old = document.querySelector('#mylist');
    let clone = old.cloneNode(true);
    appendNode(clone, data);
    old.parentNode.replaceChild(clone, old);

    这种方法也只发生了一次重排(将操作完的复制节点插入的时候),但相较于文档片段的方式,更多的操作了DOM。

    缓存布局信息

    当访问诸如offsetLeftclientTop这种属性时,会冲破浏览器自有的优化——通过队列化修改和批量运行的方法,减少重排/重绘版次。所以我们应该尽量减少对布局信息的查询次数,查询时,将其赋值给局部变量,使用局部变量参与计算。

    //bad
    div.style.left = 1 + div.offsetLeft + 'px';
    div.style.top = 1 + div.offsetTop + 'px';
    
    //good
    current = div.offsetLeft;
    div.style.left = 1 + ++current + 'px';
    div.style.top = 1 + ++current + 'px';

    每次都会访问div的offsetLeft,造成浏览器强制刷新渲染队列以获取最新的offsetLeft值。更好的办法就是,将这个值保存下来,避免重复取值。

    15. CSS选择器

    ♥前文

    (一)基本选择器

    1. 标签选择器

    2. ID选择器  “#”

    ID的命名要求:

    • 只能有字母、数字、下划线。
    • 必须以字母开头。
    • 不能和标签同名。比如id不能叫做body、img、a。
    • 大小写严格区分,也就是说aa,和AA是两个不同的ID

    HTML页面,不能出现相同的id,哪怕他们不是一个类型。比如页面上有一个id为pp的p,一个id为pp的div,是非法的!

    3. 类选择器  “.” 

    • 特性1:类选择器可以被多种标签使用。

    • 特性2:同一个标签可以使用多个类选择器。用空格隔开。

    4. 通配选择器 => 属性选择器

    属性名选择器

    [attribute],用于选择所有带有特定属性的元素,例如 [title],选择所有带有 title 属性的元素。

    属性值选择器

    *[title(="...")]{...},匹配所有带有title标签的

    a[href(="...")][title(="...")]{color:red}将同时有 href(="...")和 title(="...")属性的 HTML 超链接的文本设置为红色

    (二)高级选择器

    1. 后代选择器

    空格隔开  后代不一定是子元素,只要有祖先后代的关系就可以。

    子元素选择器: >(直接的子元素)

    同级元素选择器: a~b (与a元素同级的b元素)

    相邻元素选择器:eg: h3+p 意思是h3后面的第一个p。

    2. 交集选择器

    不空格!(空格的就是后代选择器了)

    一般不会连交,IE低版本不支持。

    3. 并集选择器

    逗号隔开。

    4. 伪类选择器

    <a>标签对应几种不同的状态:

    • link:超链接点击之前
    • visited:超链接点击之后
    • focus:是某个标签获得焦点的时候(比如某个输入框获得焦点)
    • hover:鼠标放到某个标签上的时候
    • active:点击某个标签没有松鼠标时

    (1)静态伪类:只能用于超链接

    a{}a:link{}的区别:

    • a{}定义的样式针对所有的超链接(包括锚点)
    • a:link{}定义的样式针对所有写了href属性的超链接(不包括锚点)

    (2)动态伪类:针对所有标签都适用

    • focus(聚焦,点击某个文本框后输入文字,可以定义文本框和文字的属性):是某个标签获得焦点的时候(比如某个输入框获得焦点)
    • hover(盘旋,鼠标停留在上面):鼠标放到某个标签上的时候
    • active(长按状态):点击某个标签没有松鼠标时

    (3)结构伪类选择器

    :nth-child(n),选择同级元素中的第 n 个元素(元素下标是从1开始的)

    也可以使用 even(偶数), odd(奇数) 关键字

    :nth-last-child(n)

    :first-child

    :last-child

    :only-child

    :nth-of-type(n),选择同级元素中的第 n 个同类元素

    eg:.box > :nth-of-type(2)

    <div class="box">
      <p>第一个 p 子元素,不会被选中</p>
      <span>第一个 span 子元素,不会被选中</span>
      <p>第二个 p 子元素,会被选中</p>
      <span>第二个 span 子元素,会被选中</span>
    </div>

    :nth-last-of-type

    :first-of-type

    :last-of-type

    :only-of-type

    (4):root 选择器

    选择文档的根元素,对于 HTML 文档就是 html 元素。

    (5):empty 伪类选择器

    选择没有子元素的元素(包括文本节点)

    5. 伪元素选择器

    ::first-letter,选择元素的第一个字母

    ::first-line,选择元素的第一行

    ::before/::after 

    ::before,选择在元素之前插入的生成内容

    ::after,选择在元素之后插入的生成内容

    ::selection,选择用户选取的内容

    【面试 · 下期】

    ♥HTML&CSS面试高频考点(四)

  • 相关阅读:
    剑指 Offer 46. 把数字翻译成字符串
    leedcode:27. 移除元素
    1052. 爱生气的书店老板(滑动窗口)
    剑指 Offer 56
    剑指 Offer 11. 旋转数组的最小数字(二分)
    1919年巴黎和会顾维钧英语演讲稿
    状语从句
    定语从句
    名词性从句
    并列句
  • 原文地址:https://www.cnblogs.com/hermionepeng/p/13202297.html
Copyright © 2020-2023  润新知