前端知识框架 前端知识框架
首页
基础
框架
插件
Node
地图
更多
前端须知
  • 分类
  • 标签
  • 归档

BestIdea

首页
基础
框架
插件
Node
地图
更多
前端须知
  • 分类
  • 标签
  • 归档
  • 国产机环境浏览器兼容问题收集(持续收集)
  • canvas电子画板,适用于H5版本,组件产出为blob类型的文件流
  • Css3 filter(滤镜) 属性
  • css选择器
  • http缓存
  • less语法
  • New date()浏览器时间兼容性
  • rem自动适应性布局方案
  • 浏览器缓存机制
  • 屏幕适配
  • 前端基础方法汇总
  • 图片转码下载方式(解决浏览器下载图片时直接打开图片问题)
  • CSS命名规范
  • 大屏定位解决方案
    • 解决方案
    • 实现
      • 样式布局
      • 定位方式
      • 实现原理
      • 实现代码
  • TypeScript入门
  • 解决有些浏览器rem不以html的font-size为基准问题
  • 解决Vue项目页面缩放问题
  • H5扫一扫功能
  • crypto前端加密
  • 基础
郝东建
2023-04-12
目录

大屏定位解决方案

此解决方案主要是为了解决大屏布局定位的方式

# 解决方案

  • 使用传统布局方式
  • 绝对定位方式
  • Grid 布局方式

最后决定使用绝对定位方式主要考虑到会出现中间空白,两边布局的方式,绝对定位的方式会更加灵活

脚手架下载索引:screenPot

# 实现

# 样式布局

如果使用绝对定位,先使用 css 保证父元素的宽高和设置元素的原始定位

    <style>
      html,
      body {
        height: 100%;
        width: 100%;
        margin: 0;
      }
      .big-screen {
        height: 100%;
        width: 100%;
        margin: 0;
        position: relative;
      }
      .big-screen > div {
        background-color: pink;
        position: absolute;
        border: 1px solid royalblue;
        box-sizing: border-box;
        font-size: 20px;
        text-align: center;
        line-height: 1;
        height: 0;
        width: 0;
        top: 50%;
        left: 50%;
        transition: all 0.5s;
      }
    </style>
  </head>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 定位方式

使用自定义属性来定义元素的位置和大小

<body>
  <div id="screen" class="big-screen">
    <div top="0" left="0" height="300" width="500">1</div>
    <div top="300" left="0" height="400" width="500">2</div>
    <div top="700" left="0" height="380" width="500">3</div>

    <div top="0" left="500" height="750" width="920">4</div>
    <div top="750" left="500" height="330" width="920">5</div>

    <div top="0" left="1420" height="300" width="500">6</div>
    <div top="300" left="1420" height="400" width="500">7</div>
    <div top="700" left="1420" height="380" width="500">8</div>
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 可以设置初始化位置的时间
let bigScreen = new SreenPot(document.getElementById("screen"), {
  gutter: 20,
  init: true,
});
1
2
3
4
5
//设置屏幕宽高,默认获取浏览器宽高
let bigScreen = new SreenPot(document.getElementById("screen"), {
  deviseHeight: 1080,
  devisetWidth: 1920,
  gutter: 20,
});
bigScreen.init();
1
2
3
4
5
6
7

# 实现原理

  • 传递父元素,获得子元素列表
  • 根据子元素获取自定义属性来计算
  • 为了适配不同设计图,可以传递设计图的宽高和默认间距
  • 计算宽高和定位的百分比,然后设置属性,留出间距

# 实现代码

!(function (global) {
  "use strict";
  class SreenPot {
    $el = null;
    $options = {};
    constructor(el, options = {}) {
      this.$options = options;
      this.$el = el;
      if (options.init) {
        this.init();
      }
    }
    init() {
      let parts = this.$el.children;
      for (const part of parts) {
        this.setPosition(part);
      }
    }
    setPosition(el) {
      let { top, left, height, width } = this.getPoit(el);
      let style = {
        top: `calc(${top})`,
        left: `calc(${left})`,
        height: `calc(${height})`,
        width: `calc(${width})`,
      };
      this.setAttr(el, style);
    }
    getPoit(el) {
      let {
        deviseHeight = document.body.clientHeight || 1080,
        devisetWidth = document.body.clientWidth || 1920,
        gutter = 20,
      } = this.$options;
      let keys = ["top", "height", "left", "width"];
      let poit = keys.reduce((total, current) => {
        total[current] = this.getAttr(el, current, true);
        return total;
      }, {});
      let { top, left, height, width } = poit;
      let mwgutt = width + left >= devisetWidth ? gutter * 2 : gutter;
      let mhgutt = height + top >= deviseHeight ? gutter * 2 : gutter;
      top = `${this.getPrecent(top, deviseHeight)} + ${gutter}px`;
      left = `${this.getPrecent(left, devisetWidth)} + ${gutter}px`;
      height = `${this.getPrecent(height, deviseHeight)} - ${mhgutt}px`;
      width = `${this.getPrecent(width, devisetWidth)} - ${mwgutt}px`;
      return { top, left, height, width };
    }
    setAttr(el, style) {
      for (const key of Object.keys(style)) {
        el.style[key] = style[key];
      }
    }
    getAttr(el, attr, isNumber) {
      let attrCount = el.getAttribute(attr);
      if (attrCount === undefined || attrCount === null) {
        throw new Error(`${attr}属性未查到`);
      }
      return isNumber ? Number(attrCount) : attrCount;
    }
    getPrecent(nume, deno) {
      return (nume / deno) * 100 + "%";
    }
  }
  if (typeof define === "function") {
    define(function () {
      return SreenPot;
    });
  } else {
    global.SreenPot = SreenPot;
  }
})(this);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
interface Options {
  deviseHeight: number;
  devisetWidth: number;
  gutter: number;
}
interface Poit {
  height: number;
  width: number;
  top: number;
  left: number;
}
interface Poits {
  height: string;
  width: string;
  top: string;
  left: string;
}
class SreenPot {
  private $el: any;
  private $options: Options;
  constructor(el, options: Options) {
    this.$options = options;
    this.$el = el;
    if (options.init) {
      this.init();
    }
  }
  init() {
    let parts = this.$el.children;
    for (const part of parts) {
      this.setPoit(part);
    }
  }
  private setPoit(el) {
    let { top, left, height, width } = this.getPoit(el);
    let style = {
      top: `calc(${top})`,
      left: `calc(${left})`,
      height: `calc(${height})`,
      width: `calc(${width})`,
    };
    this.setAttr(el, style);
  }
  private getPoit(el): Poits {
    let {
      deviseHeight = document.body.clientHeight || 1080,
      devisetWidth = document.body.clientWidth || 1920,
      gutter = 20,
    } = this.$options;
    let poit: Poit = {
      left: this.getAttr(el, "left"),
      top: this.getAttr(el, "top"),
      height: this.getAttr(el, "height"),
      width: this.getAttr(el, "width"),
    };
    let { top, left, height, width } = poit;
    let mwgutt = width + left >= devisetWidth ? gutter * 2 : gutter;
    let mhgutt = height + top >= deviseHeight ? gutter * 2 : gutter;
    let result: Poits = {
      top: `${this.getPrecent(top, deviseHeight)} + ${gutter}px`,
      left: `${this.getPrecent(left, devisetWidth)} + ${gutter}px`,
      height: `${this.getPrecent(height, deviseHeight)} - ${mhgutt}px`,
      width: `${this.getPrecent(width, devisetWidth)} - ${mwgutt}px`,
    };
    return result;
  }
  private setAttr(el, style: object) {
    for (const key of Object.keys(style)) {
      el.style[key] = style[key];
    }
  }
  private getAttr(el, attr: string): number {
    let attrCount = el.getAttribute(attr);
    if (attrCount === undefined || attrCount === null) {
      throw new Error(`${attr}属性未查到`);
    }
    return Number(attrCount);
  }
  private getPrecent(nume: number, deno: number): string {
    return (nume / deno) * 100 + "%";
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
上次更新: 2024/01/18, 10:44:15
CSS命名规范
TypeScript入门

← CSS命名规范 TypeScript入门→

最近更新
01
webpack打包替换类名命名空间
05-01
02
Vite常用配置
02-26
03
crypto前端加密
01-18
更多文章>
Theme by Vdoing | Copyright © 2022-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式