JS和CSS实现毛玻璃图片模糊效果

笔记哥 / 04-29 / 48点赞 / 0评论 / 473阅读
#### 线上效果图 ![](https://cdn.res.knowhub.vip/c/2505/06/aa9668a4.png?G1cAAMTsdJxI8pKUbqMO2jvFHc2ARRpBpYT1es9Z%2byb6%2fgaGxmfUPtv%2b8JvaZyNRmBcjMIwVIeCSnJIUcw8CzcrqyHGNBg%3d%3d) #### 思路分析 图片我们使用背景图片的方式插入 如果我们的图片大于容器的话 我们使用background-size: cover 进行比例缩放,覆盖整个容器 毛玻璃效果使用 backdrop-filter 来进行处理,值越大模糊程度越大 #### 使用毛玻璃实现图片模糊效果 ```csharp 使用毛玻璃实现图片模糊效果
成都 | 28岁
研究生
Ta看过你10次
``` ![](https://cdn.res.knowhub.vip/c/2505/06/ccf23688.png?G1cAAMTsdJxIPhKl26hD2jvFHc2ARRpBpYT1es9Z%2byb6fhcWjc9offr%2b8JvWpxNULFcjYTFWhCAXSlJDQQ7QWhmQYnENBw%3d%3d) #### 发现问题:控制台去掉backdrop-filter属性 没有想到吧,这么简单就实现了这个效果 但是机智的小伙伴沉思片刻就发现了一个问题 若是用户操作控制台去掉backdrop-filter属性 那不是就可以看见真实的图像了? 这样肯定是不得行的,产品肯定喊你小子改 好嘛,我只有老老实实的去解决这个问题 ![](https://cdn.res.knowhub.vip/c/2505/06/4f11ba43.png?G1YAAMTsdJxIvCSq26hD2jvFHc2ARBZBpYT1es9Z%2byb6fgdD4jNan74%2f%2fKX16ZQEalUJDGVB8CjpyiaqGUGs1KqFLa7h) #### 解决用户在控制台去掉backdrop-filter属性问题 方法1:禁用使用操作控制台,通过去监听用户的按键来进行处理 方法2: 使用 MutationObserver 方法来解决 #### MutationObserver 的简单介绍 用于监测DOM树的变化,它提供了一种异步的方式来监听DOM元素的增加、删除、属性变化、文本节点等变化。 通过MutationObserver,我们可以实时地知道到DOM的变化,并做出相应的操作。 首先我们要选择一个观察的元素对象。 然后通过 new MutationObserver 创建观察者对象,观察发生变化后触发回调函数 。 配置观察选项,这个非常重要,我们等会要详细去了解 最后通过 observer.observe传入需要观察的元素和配置选项 ```csharp // 第一步:选择目标节点 var targetElement = document.getElementById('domID'); // 回调函数 function callBackFun(mutationsList, observer){ // mutationsList:一个数组,包含所有检测到的变化。 // observer:此回调函数的 MutationObserver 实例。 } // 第二步: 创建观察者对象,观察发生变化后触发回调函数 let observer = new MutationObserver(callBackFun); // 第三步:配置观察选项: let configObj = { attributes: true, childList: true, characterData: true } //第四步: 传入目标节点和观察选项 observer.observe(targetElement, configObj); // 适当的时机,停止观察的方法 observer.disconnect(); ``` ![](https://cdn.res.knowhub.vip/c/2505/06/0b494738.jpg?G1YAAER17rxga2EQ%2fU48pgaFBJoBiSyCSgnrde891ynyfE5ljtff%2bvD14S%2btDxdkWjlMqDTNCJ6VYCXMSgCgYLIU3%2bk%3d) #### 配置观察选项 ```csharp const config = { attributes: true, // 监听属性变化,等会详细介绍一下这个属性,场景:防样式篡改行为 childList: true, // 监听某个元素下的子节点变化(不包含目标节点),如:用户在控制台删除(新增)节点,场景:动态内容加载监控 subtree: true, // 监听目标节点自身 + 所有后代节点,单独配置{subtree:true}不会产生任何效果, attributeFilter: ['id'], // 只监听特定属性(此处为 id), attributeFilter: ['data-*']监听 data-* 属性的变化 characterData: true // 监听目标节点及其所有后代节点的文本内容变化,场景:富文本编辑器内容追踪 }; ``` #### attributes: true 的详细介绍 1,通过控制台去除了css行内样式的属性 2,通过js给元素新增了某个属性 如:ele.setAttribute()、ele.removeAttribute()、ele.id = 'newId'、ele.className = 'newClass' 3,通过 style 属性修改:如 element.style.color = 'red'。 特别提醒:内部样式表,如:类名{ }这种,在控制台去除样式属性是监听不到的。 #### subtree: true 的详细介绍 监听所有后代节点,单独配置 { subtree:true }不会产生任何效果。 因为 subtree 本身只是一个范围扩展标记,而不是独立的监听类型。 通常需要配合其他选项,如:attributes: true, 监听属性变化。 childList: true, 监听某个元素下的子节点变化(删除,新增) #### 关于 MutationObserver的回调 如果在同一时间,某个被监听的元素属性发生了1000次变化。 MutationObserver的回调函数会执行1000次嘛? 答:不会。只会执行一次。 MutationObserver的回调是异步执行的,并且会将多个变化合并到一个回调函数中去处理。 也就是说,如果在同一时间(或者同一事件循环中)发生了多次变化,这些变化会被收集起来。 然后一次性传递给回调函数,而不是每次变化都立即触发回调。 #### MutationObserver的使用场景 总体来讲:只要DOM发生变化,就可以使用MutationObserver。 具体的场景:echarts 容器大小发生变化。用户通过控制台更改了元素的属性。响应式网页。窗口大小发生变化的场景。 #### 使用MutationObserver监听元素的属性是否发生变化 ```csharp
成都 | 28岁
研究生
Ta看过你10次
``` ![](https://cdn.res.knowhub.vip/c/2505/06/6677e4f7.jpg?G1cAAMTW3Dgp8EIebaMNVGfpnTYDFmkElRLW6957rpPo%2bQIMzdff%2boj14TetjyBR2OFGYBgrUkAVhxZ2r0kKCpuK1fzOAA%3d%3d) #### 又发现问题 我们的背景图是插入在 `
` 这个元素上的 毛玻璃的效果是用在 `
` 这个节点上的。 如果用户删除watchElementNode这个节点的话,一样可以看到真实的图像。 怎么来解决这个问题呢? 监听 `
`这个元素的子节点是否有变化。 如果监听到发生变化了,给这个节点隐藏起来同时不影响文档布局 ![](https://cdn.res.knowhub.vip/c/2505/06/a2399d20.jpg?G1YAAMTydJx4zj10G3X4ttGSaDMgkUVQKWG9rv9f%2bxC5X0MA%2ffn1MW1%2f%2bEsf0yQSmpsKAjQQzqPEBqamqK4w5ZIq6Z9l) #### 使用MutationObserver监听子节点是否发生变化 ```csharp 使用毛玻璃实现图片模糊效果
成都 | 28岁
研究生
Ta看过你10次
``` ![](https://cdn.res.knowhub.vip/c/2505/06/00a151ff.jpg?G1YAAMTW3Dgp8KJh22gD1Vl6p82ARBZBpYT1uvee6yR6PgdD4%2fW3Pnx9%2bEvrw0kUudRMYGRWBI9DKlStQAJSBcwsxXc6) #### 可以优化一下吗? 有机制的小伙伴说:我们可以直接去监听 id = imgbox这会元素。 如果这个元素的子节点和子节点的属性发生变化了。 我们直接将这个 id = imgbox 隐藏起来。 这样就不需要写2个监听器了,大佬果然有点东西。 那我们就按照这个思路再来优化一下 #### 监听子节点和子节点的属性是否发生变化 ```csharp 使用毛玻璃实现图片模糊效果
成都 | 28岁
研究生
Ta看过你10次
``` ![](https://cdn.res.knowhub.vip/c/2505/06/d12c0023.png?G1cAAMTsdJxIfBKq26hD2jvFHc2ARRpBpYT1es9Z%2byb6fgdD4zNan74%2f%2fKb16ZQUlqsRGMaKEFBShdqlqiGJ5CombHENBw%3d%3d) #### 最后说一下 看到最后,我们会发现写的更多的是关于MutationObserver的使用。 而不是毛玻璃的实现。 如机智的小伙伴们说的那样:通过网络就可以看到真实的图片。 因此:要想真正实现这个效果,必须从服务端返回一张模糊图片。 否则,都有办法看到真实的图像