瀑布流布局详谈

本文深入探讨了瀑布流布局的三种实现方式:column-count、flex-box和JS计算绝对定位。对比了CSS布局的兼容性和易用性,以及JS布局的空间利用率和动态加载能力。通过具体代码示例,详细解析了JS如何实现瀑布流布局,包括元素定位和响应式设计。

瀑布流3种布局方式

  1. column-count (纯css)
  2. flex-box (纯css)
  3. js 计算每个元素绝对定位

布局优劣

  • css
    兼容性差,只能纵向排列,无法应用于动态加载
    好处是容易写
  • js
    写起来麻烦,性能差
    横向排布,能更好地利用空间,可支持动态加载

JS 布局代码


  // 瀑布流布局
  const waterfall = useCallback(() => {
    // 外层
    const layer = document.getElementById('approval-desk')
    // 容器
    const container: HTMLElement = _.get(document.getElementsByClassName('tabs-content'), '[0]')
    // 容器内需要瀑布流布局的元素
    const arr = document.getElementsByClassName('tabs-container') as HTMLCollectionOf<HTMLElement>

    if (!layer || !container || !arr.length) return

    // 移动端布局
    if (document.documentElement.clientWidth <= 1020) {
      // 清除样式
      container.style.cssText = ''
      _.forEach(arr, item => { item.style.cssText = '' })
    }

    const layerWidth = layer.clientWidth
    const clientRects = _.map(arr, item => item.getBoundingClientRect())

    // 列宽:由于每列宽度一样,取第一列即可
    const columnWidth = clientRects[0].width
    // 列数
    let columnCount = parseInt(`${layerWidth / columnWidth}`)
    // 不能超过总元素个数
    if (columnCount > clientRects.length) columnCount = clientRects.length

    if (!columnCount) return

    // 布局中每个元素的定位数据
    const cells = Array(columnCount).fill(1).map(() => []) as {
      top: number,
      height: number,
    }[][]

    // 容器样式
    container.style.cssText
      = `position: relative; width: ${columnCount * columnWidth}px; margin: auto;`

    // 当前循环的元素需要放入的列下标
    let columnIndex = 0
    for (let i = 0; i < clientRects.length; i++) {
      // 当前循环的元素
      const rect = clientRects[i]
      // 需要放入的列
      const column = cells[columnIndex]

      // 该列的最后一个元素的定位数据,还未放入过元素则取默认值
      const lastColumnRect = column.length
        ? column[column.length - 1]
        : { top: 0, height: 0 }

      // 当前元素的定位数据
      const newCell = {
        top: lastColumnRect.top + lastColumnRect.height,
        height: rect.height,
      }
      column.push(newCell)

      arr[i].style.cssText
        = `position: absolute; top: ${newCell.top}px; left: ${columnWidth * columnIndex}px`

      // 每一列的高度
      const columnHeights = cells.map(column => _.sum(column.map(cell => cell.height)))
      // 最低高度
      const minHeight = Math.min(...columnHeights)
      // 下一个元素需要放入的列下标
      columnIndex = columnHeights.findIndex(height => height === minHeight)
    }
  }, [])

  // 拉取到分类数据后,调用瀑布流布局函数
  useEffect(() => waterfall, [categories])
  // 窗口大小改变时,调用瀑布流布局函数
  useEffect(() => {
    window.addEventListener('resize', waterfall)
    return () => window.removeEventListener('resize', waterfall)
  }, [])
### PLC的详细解析 #### 工作原理 可编程逻辑控制器(PLC)是一种专为工业环境设计的数字计算机,用于自动化控制。其核心工作原理基于循环扫描的方式执行用户程序。在每次扫描周期中,PLC会完成输入采样、程序执行和输出刷新三个阶段[^1]。 - **输入采样**:PLC读取所有输入信号的状态,并将这些状态存储到输入映像寄存器中。 - **程序执行**:根据输入映像寄存器中的数据,按照用户编写的程序进行逻辑运算或算术运算。 - **输出刷新**:将程序执行的结果写入输出锁存器,从而改变外部设备的状态。 这种循环扫描机制确保了PLC能够实时响应外部事件并作出相应的控制动作。 #### 应用场景 PLC广泛应用于各种工业自动化领域,包括但不限于: - **制造业**:如汽车装配线、食品加工生产线等,用于控制机械臂、传送带以及其他生产机械。 - **过程控制**:在化工、石油精炼等行业中,用来监控和调节温度、压力、流量等参数。 - **楼宇自动化**:用于暖通空调系统(HVAC)、电梯控制系统以及安全系统等。 - **能源管理**:在电力分配系统中实现负载平衡和故障检测等功能。 #### 编程方法 PLC的编程通常采用几种标准化语言,最常见的是梯形图(Ladder Diagram, LD)、功能块图(Function Block Diagram, FBD)、结构化文本(Structured Text, ST)和指令列表(Instruction List, IL)。每种语言都有其特点和适用场合。 - **梯形图**是最直观的一种图形化编程语言,它模仿继电器逻辑电路的设计方式,易于理解和学习。 - **功能块图**允许开发者使用预定义的功能块来构建复杂的控制逻辑,支持模块化设计。 - **结构化文本**是一种高级文本编程语言,适合处理复杂的数据操作和算法实现。 - **指令列表**类似于汇编语言,提供了对硬件直接访问的能力,但相对难以编写和维护。 下面是一个简单的梯形图示例,展示了如何通过两个按钮控制一个指示灯: ```plaintext |----[ ]----( )--| I0.0 Q0.0 |----[ ]----( )--| I0.1 Q0.0 ``` 在这个例子中,如果任一按钮(I0.0 或 I0.1)被按下,则指示灯(Q0.0)会被点亮。 此外,现代PLC还支持更复杂的编程技术,比如面向对象的方法,其中可以创建可重用的功能块(FBs),例如`FB_RobotCtrl`、`FB_Vision` 和 `FB_Safety`,它们分别用于机器人控制、视觉通信处理和安全联锁逻辑。全局数据块(如`DATA_DB.gxw`)则用来保存配方信息和运行时参数,使得不同功能块之间能够共享数据。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值