js、css与高度(宽度)共享

简介: 高度共享,是高度共享和宽度共享的总称。是笔者总结的一个针对某些问题解决的思路。并不是一个新的技术点或模式 —— 至少目前来说。甚至可能你已经在项目中用过类似的。它的核心就是:降低 js 复杂计算和耗时操作在类似场景中的比重。没啥说的,通过两个业务场景描述一下即可。

高度共享,是高度共享和宽度共享的总称。是笔者总结的一个针对某些问题解决的思路。并不是一个新的技术点或模式 —— 至少目前来说。甚至可能你已经在项目中用过类似的。
它的核心就是:降低 js 复杂计算和耗时操作在类似场景中的比重。

没啥说的,通过两个业务场景描述一下即可。

宽度共享

有一个很常见的场景:侧边栏。侧边栏一般都是 fixed 定位,脱离了文档流会造成可能影响旁边的元素内容。
toy微前端框架初始页面-fixed遮挡后面文字
fixed 元素不管怎么说,脱离了文档流已经“不可控”。于是大多数网站采用了这样的方式:侧边栏固定大小。但是对一种情况来说不是很好:响应式。

这时候有两种方法,而且都是和 js 相关的:

  1. 根据侧边栏大小的改变,动态改变右边内容的 margin-left 大小;
  2. 有一个元素能够作为 fixed 元素的“影子”,它的大小和 fixed 元素大小保持一致,并且不脱离文档流存在

先说,这两种方法在这个场景下是基本一致的,但是第二种方法可以封装组件复用,甚至可以不侵入右边内容的业务逻辑。
而且,侧边栏不一定在左边,还可能在右边;还可能是顶部或底部的 fixed。

我随手写了一个组件,可以根据传参进行判断:

<template>
    <section class="highly-s-content" :class="{'highly-s-content-column': side[0]=='height'}">
        <div class="highly-shadow" v-if="showSlide" :style='highlyShadowStyle'></div>
        <div :class="['highly-body', highlyShadowClass]" ref="highlyRef">
            <slot name="highlyslide"></slot>
        </div>
        <!-- 要么把右边/左边内容放到slot中,要么必须保证这个组件引用位置的父组件有display flex或者行内设置 -->
        <slot name="content"></slot>
    </section>
</template>

<script>
    export default {
        props: {
            showSlide: { //外部传进来的,在外部是控制slide是否显示,传进来后控制slide的“影子组件”是否显示
                type: Boolean,
                default: false
            },
            side: {
                type: Array,
                default: ()=> { return ['width', 'left'] }
            }
        },
        data() {
            return {
                noHeighlyBox: false,
                innerShareWidth: "100px",
            }
        },
        computed: {
            highlyShadowClass() {
                return this.side[0] == 'width' ? `highly-width-${this.side[1]}-body` : `highly-height-${this.side[1]}-body`;
            },
            highlyShadowStyle() {
                if(this.side[0] == 'width') {
                    return { width: this.innerShareWidth, overflow: "hidden", flex: `0 0 ${this.innerShareWidth}`, maxWidth: this.innerShareWidth, minWidth: this.innerShareWidth, transition: "background-color 0.3s ease 0s, min-width 0.3s ease 0s, max-width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) 0s" }
                } else {
                    return { height: this.innerShareWidth, overflow: "hidden", flex: `0 0 ${this.innerShareWidth}`, maxHeight: this.innerShareWidth, minHeight: this.innerShareWidth, transition: "background-color 0.3s ease 0s, min-height 0.3s ease 0s, max-height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) 0s" }
                }
            }
        },
        mounted() {
            console.log('高度共享组件-初次实践')
            if(this.$refs.highlyRef.children[0]) {
                this.innerShareWidth = window.getComputedStyle(this.$refs.highlyRef.children[0],null)["width"]
            }
        },
        methods: {
            $_resizeBox() {
                if(this.$refs.highlyRef.children[0]) {
                    this.innerShareWidth = window.getComputedStyle(this.$refs.highlyRef.children[0],null)["width"]
                }
            }
        }
    }
</script>

<style lang="scss">
    .highly-s-content {
        display: flex;
        &.highly-s-content-column {
            flex-direction: column;
        }
        &>.highly-body {
            position: fixed;
            z-index: 2;
            &.highly-width-left-body {
                top: 0;
                left: 0;
                height: 100%;

            }
            &.highly-width-right-body {
                top: 0;
                right: 0;
                height: 100%;
            }
            &.highly-height-top-body {
                top: 0;
                left: 0;
                width: 100%;
            }
            &.highly-height-bottom-body {
                bottom: 0;
                left: 0;
                width: 100%;
            }
        }
    }
</style>

如果页面改变,可以调用组件的 $_resizeBox 方法更新大小。
toy微前端框架初始页面-解决遮挡问题

高度共享

和上面宽度共享是一个道理。拿上面的项目截图来说,顶部的内容其实就做了高度共享。而且上面封装的组件是可以通过参数传入决定是高度共享还是宽度共享的。
toy微前端框架初始页面-高度共享
但是高度共享不止于此。

我前同事曾经告诉我一个场景(虽然我至今都想不出设计是怎么想出这个方案的):一个商品列表项,每行有两列,如果某行其中一个有 sku,而另一个没有,则没有的那个商品展示的高度要和有 sku 的商品展示的高度一致。
简单来说就是,每行展示两个商品,高度保持一致。
前东家-微店买家侧-test数据

他是这么做的:利用 js 遍历商品数组,然后判断他们有没有sku,再根据是第几个商品返回 true 或 false,比如第一个商品有 sku,那第一个商品和第二个商品都返回 true。

现在这个需求要求的比较简单,几个商品即可,这种写法还能支持,若是后面迭代要展示几十个或者不限制呢?毫无疑问这种写法是不可能上线的。

当时我就已经在进行有关“高度共享”的想法了,我当即想到:为什么不能在 HTML 结构中以“每一行”为一个整体,它拥有一个 min-height,然后在 js 中初始时遍历商品数组将一维数组转变成 2 为基数的二维数组呢?这样对每一行的每一项都设置 height: 100% 即可轻松解决问题。

so easy~


细想,这种思路还可以用在更多的业务场景中,解决结构问题、提高代码效率。

我上次文章中提到的toy-micro-web微前端项目已开源至 gitee: toy-microWeb项目 !欢迎star!
本框架是一次test,采用“以主应用为主,总控所有应用”的方式,以“页面级”为维度,是我对微前端的探索和第一版产出。
本框架除了尝试微前端,还将作为作者提出的“新组件库”和“css架构”想法的试验模板。
相关文章
|
4天前
|
JavaScript 前端开发
页面滚动触发css3动画js插件
delighters.js是一款页面滚动触发css3动画js插件。该js插件可以在页面向下滚动时,为进入浏览器视口的元素制作各种炫酷的CSS3动画效果。
29 13
|
12天前
纸屑飘落生日蛋糕场景js+css3动画特效
纸屑飘落生日蛋糕CSS3动画特效是一款js+css3制作的全屏纸屑飘落,生日蛋糕点亮庆祝动画特效。
31 3
|
1月前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
优化CSS和JavaScript加载
|
1月前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
Next.js和Nuxt.js在优化CSS和JavaScript加载方面提供了多种策略和工具。Next.js通过代码拆分、图片优化和特定的CSS/JavaScript优化措施提升性能;Nuxt.js则通过代码分割、懒加载、预渲染静态页面、Webpack配置和服务端缓存来实现优化。两者均能有效提高应用性能。
|
1月前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
124 1
|
1月前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
46 3
|
25天前
JS+CSS3文章内容背景黑白切换源码
JS+CSS3文章内容背景黑白切换源码是一款基于JS+CSS3制作的简单网页文章文字内容背景颜色黑白切换效果。
17 0
|
23天前
|
前端开发 测试技术 定位技术
如何利用HTML和CSS构建企业级网站的全过程。从项目概述到页面结构设计,再到HTML结构搭建与CSS样式设计,最后实现具体页面并进行优化提升,全面覆盖了网站开发的关键步骤
本文深入介绍了如何利用HTML和CSS构建企业级网站的全过程。从项目概述到页面结构设计,再到HTML结构搭建与CSS样式设计,最后实现具体页面并进行优化提升,全面覆盖了网站开发的关键步骤。通过实例展示了主页、关于我们、产品展示、新闻动态及联系我们等页面的设计与实现,强调了合理布局、美观设计及用户体验的重要性。旨在为企业打造一个既专业又具吸引力的线上平台。
46 7
|
23天前
|
前端开发 JavaScript 搜索推荐
HTML与CSS在Web组件化中的核心作用及前端技术趋势
本文探讨了HTML与CSS在Web组件化中的核心作用及前端技术趋势。从结构定义、语义化到样式封装与布局控制,两者不仅提升了代码复用率和可维护性,还通过响应式设计、动态样式等技术增强了用户体验。面对兼容性、代码复杂度等挑战,文章提出了相应的解决策略,强调了持续创新的重要性,旨在构建高效、灵活的Web应用。
31 6
下一篇
DataWorks