CSS-五种方法隐藏元素,成本消耗以及对事件的影响

1,926 阅读3分钟

如果问大家如何隐藏一个元素,相信大家都会很快的答上来,如果再加上对回流和重绘的影响呢 ?再加上对事件的哦影响呢 ?如果再追加一个问题,如何隐藏父元素但是子元素要显示呢?
本文将回答上面的四个问题。

写本文的还有有一个原因,是在面试的时候被问到了,完整面试内容点击这儿

如何隐藏一个元素

  1. visibility: hidden
  2. opacity: 0
  3. display: none
  4. position: relative; z-index: -1;
  5. position: relative;left: -1000px;(要求父元素overflow: hidden)
    示例:
    示例写了一个可视区域,里面除了一个文本节点,还有两个node节点,我们对item1的节点进行了一个操作,可见只有display: none时,元素彻底消失在了页面中(看不见且不占据空间)。 image.png 代码:(文章结尾)

回流和重绘

回流:当页面必须重新处理和绘制部分或全部页面时,回流就会发生,例如当一个交互式站点更新后。
重绘:由于元素的外观,形态例如颜色透明度发生变化时,页面需要重新绘制

  • visiblity 重绘
  • opacity 重绘
  • display 布局发生变化 回流 + 重绘
  • position 回流 + 重绘

事件的影响

用户点击:分别js给五种情况绑定了DOM0级事件,可以看到opacity:0时,输出了结果。 image.png 原因是为什呢?

  1. visibility 不触发,元素不可见用户也无法点击,在页面中鼠标页无法直接选中
  2. opacity 触发,opacity只是改变了不透明度,所以元素能正常点酒
  3. display 不触发,页面已经没有显示元素了,所以我们无法点击,也就无法触发相关的点击事件
  4. z-index,虽然它还在文档流中占据空间,但是元素已经在父元素之下了,根据图层关系,已无法点中子元素,肯定是无法触发子元素的点击事件
  5. position 不触发,虽然它还在文档流中占据空间,但是元素已经不在我们可以点击的范围了,自然是无法点中。

js模拟用户点击

如果用js选中元素,然后模拟点击,点击事件都可以正常触发 代码:(完整代码参考末尾)

// 模拟点击
document.querySelector('.visibility').click();
document.querySelector('.opacity').click();
document.querySelector('.display').click();
document.querySelector('.z-index').click();
document.querySelector('.left').click();

demo:

image.png

父元素隐藏,子元素显示

未给子元素添加样式后前 image.png 子元素添加样式后 image.png

  1. 情况给子元素添加了visiblity: visible,子元素可以显示了
  2. 给子元素添加了opacity: 1,子元素不可以显示,原因 0 * 1 = 0,子元素实际不透明都为0
  3. 给子元素添加了display: block,子元素不显示
  4. 给子元素添加了position: relative;z-index: 99",子元素不显示,原因是子的z-index是基于父元素的
  5. 给子元素添加了position: relative;left: 200px,子元素显示 完整代码参考文尾

总结

隐藏方式回流重绘用户点击js click显示子元素
visibility: none无法点击可以visiblity: visible
opacity: 0可以可以不可以
display: none无法点击可以不可以
postion: relative; z-index:0无法点击可以不可以
postion: relative; left: -200px无法点击可以postion: relative; left: 200px

完整示例代码

如果需要测试点击相关内容,建议先先注释子元素相关的代码,因为会点击效果造成影响

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hidden</title>
    <style>
        .box {
            display: inline-block;
            width: 200px;
            height: 300px;
            background-color: honeydew;
            border-radius: 4px;
            border: 1px solid #ccc;
            margin-bottom: 20px;
            margin-right: 20px;
            vertical-align: top;
            overflow: hidden;
        }
        .box .item {
            height: 100px;
            width: 100px;
            border-radius: 4px;
            background-color: pink;
            margin-top: 20px;
        }
        .box .child{
            width: 60px;
            height: 60px;
            color: #fff;
            background-color: red;
        }

    </style>
</head>
<body>
    <div class="box">
        0 -- 不隐藏的效果
        <div class="item" onclick="itemClick(' no hidden')">
            item1
            <div class="child">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>
    <div class="box">
        1 -- visibility: hidden
        <div class="item visibility" style="visibility: hidden" onclick="itemClick('visibility')">
            item1
            <div class="child" style="visibility: visible">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>

    <div class="box">
        2 -- opacity: 0
        <div class="item opacity" style="opacity: 0" onclick="itemClick('opacity')">
            item1
            <div class="child" style="opacity: 1">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>

    <div class="box">
        3 -- display: none
        <div class="item display" style="display: none" onclick="itemClick('display')">
            item1
            <div class="child" style="display: block">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>

    <div class="box">
        4 -- postion + z-index
        <div class="item z-index" style="position: relative;z-index: -1;" onclick="itemClick('position z-index')">
            item1
            <div class="child" style="position: relative;z-index: 99">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>

    <div class="box">
        5 -- postion + left
        <div class="item left" style="position: relative;left: -200px" onclick="itemClick('position left')">
            item1
            <div class="child" style="position: relative;left: 200px">子元素</div>
        </div>
        <div class="item">item2</div>
    </div>
    <script>
        function itemClick(type) {
            console.log('the type of hidden elemment is ' + type);
        }

        // 模拟点击
        document.querySelector('.visibility').click();
        document.querySelector('.opacity').click();
        document.querySelector('.display').click();
        document.querySelector('.z-index').click();
        document.querySelector('.left').click();
    </script>
</body>
</html>