最近,公司要做一个类似挖矿的项目,大概其是当用户登录进入首页后,如果用户有已经生成的原力值,则在其点击原力值后可以类似蚂蚁森林那样收集原力值,当用户将所有的原力值收集完毕后开始提醒用户新的原力值正在生成中,待新的原力值生成后,用户可以继续以上的操作收集原力值。如下图:

以上是一种逻辑,还有一种是当用户前一天有剩余的原力值没有收集时,在第二天收集完当天的已生成的原力值后,前一天的原力值还可以出现在页面当中继续供用户收集(具体的情况,看你公司的实际业务需求,比如可以设置三天内的原力值都能收集,也可以设置两天内的原力值可供收集等)。

本文不考虑后端业务逻辑的实现,只分享前端多个原力值在页面中的随机不重叠分布的实现方法,在此之前,我本来想参考网易星球的实现方法(算法),但人家的是APP的项目,根本看不到具体是如何实现的,后来又参考了其他的实现方法,发现其虽然也是有一定的随机性,但元素距离左边的距离其实是固定死的,只有距离顶部的距离是随机的,而且元素基本上就是只分两行随机分布。如下图:

圆圈1那个圆其实永远都在第一行的第一个位置,其唯一变化的就是它距离顶部的距离,其他的圆圈也是类似,这样给人的效果就不理想。再后来,也参考过其他的一些写法,效果都不好。那么,以下就是本篇博客所要实现的代码,妥妥滴的满足了开发的需要:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no,viewport-fit=cover">
<title>js多个元素随机且不重叠分布在页面中</title>
<script>
//计算根节点HTML的字体大小
function resizeRoot(width) {
var deviceWidth = document.documentElement.clientWidth,
num = width,
num1 = num / 100;
if (deviceWidth > num) {
deviceWidth = num;
}
document.documentElement.style.fontSize = deviceWidth / num1 + "px";
}
//根节点HTML的字体大小初始化
resizeRoot(750); window.onresize = function () {
resizeRoot(750);
};
</script>
<style>
*{margin:0;padding:0;}
.demo{height:5rem;position:relative;}
img{width:.8rem;height:.8rem;position:absolute;border-radius:50%;}
</style>
</head>
<body>
<div class="demo"></div>
<script>
createBubble(10); //初始化气泡
function createBubble(num){
var iconWidth = 60; //值越大,元素左右间隔越大
var iconHeight = 60; //值越大,元素上下间隔越大
var targetHeight = document.querySelector(".demo").offsetHeight;
var targetWidth = document.querySelector(".demo").offsetWidth;
var _tmpArray = [];
var html = '';
//当放置的元素的宽高大于浏览器窗口的宽高时,直接返回
if(targetWidth < iconWidth || targetHeight < iconHeight){
return false;
} var xNum = parseInt(targetWidth / iconWidth, 10); //用浏览器的宽度除以一个元素的宽度可算出浏览器窗口内一行可以放置元素的个数
var yNum = parseInt(targetHeight / iconHeight, 10); //用浏览器的高度除以一个元素的高度可算出浏览器窗口内一列可以放置元素的个数
var allNum = xNum * yNum; //浏览器窗口内总共可以放置元素的个数
//当需要放置的元素的个数超过浏览器窗口内总共可以放置的元素的个数时,则返回
if(num >= allNum){
return false;
} for(var i = 0; i < allNum; i++){
_tmpArray.push(i);
} var xStart = 0, yStart = 0; while(num){
var pointer = Math.floor(Math.random() * allNum); //向下取整取出0到allnum之间的任意一个整数
//如果数组_tmpArray中不存在第pointer值,则继续
if(!_tmpArray[pointer]){
continue;
} delete _tmpArray[pointer]; //删除数组_tmpArray中第pointer个值
yStart = parseInt(pointer / xNum, 10) * iconWidth;
xStart = (pointer % xNum) * iconHeight; html += "<img src='http://tp1.sinaimg.cn/1642634100/50/5613120647/0' style='top:" + yStart + "px;left:" + xStart + "px'/>";
num--;
}
document.querySelector(".demo").innerHTML = html;
}
</script>
</body>
</html>

本文代码参考自:https://segmentfault.com/q/1010000000188540

js多个元素随机且不重叠分布在页面中的更多相关文章

  1. js将数组元素随机排序的方法

    在群里看见的一个面试题,试了一下,还是可以做出来的,但是需要查资料,主要是岁一些方法了解的不清楚,可能这个跟我平时不太注重基础理论有关系,像什么构造函数啊,我根本就不关心什么叫构造函数,我一直都以为我 ...

  2. 原生js实现多个随机大小颜色位置速度小球的碰壁反弹

    文章地址 https://www.cnblogs.com/sandraryan/ 需求:生成n个小球,让他们在一个大盒子中碰壁反弹,要求小球随机颜色,大小,初始位置,运动速度. 思路分析: 创建小球随 ...

  3. js获取隐藏元素宽高的方法

    网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了. 例如: <!DOCTYPE html> <html lang="en"> <h ...

  4. js改变HTML元素的值

    js改变HTML元素的值(常用,备忘) <!DOCTYPE html> <html> <body> <h1>我的第一段 JavaScript</h ...

  5. JS控制HTML元素的显示和隐藏

    JS控制HTML元素的显示和隐藏 利用来JS控制页面控件显示和隐藏有两种方法,两种方法分别利用HTML的style中的两个属性,两种方法的不同之处在于控件隐藏后是否还在页面上占空位. 方法一: 1 2 ...

  6. 使用HTML5的JS选择器操作页面中的元素

    文件命名为:querySelector.html,可在Chrome浏览器中预览效果. 1 <!DOCTYPE html> 2 <html lang="en"> ...

  7. JS1 js获取dom元素方法

     js获取dom元素方法  1.通过ID选取元素(getElementById) 1)使用方法:document.getElementById("domId")         其 ...

  8. 使用JS控制伪元素的几种方法

    一. 缘由: 本文源于在OSC社区中,有人提问如何用jq获取伪元素.我第一想法是强大的CSS Query应该可以获取伪元素吧. 然而事实上,CSS Query并不能.即我们不能通过$(":b ...

  9. 使用原生JS定位网页元素

    约定:1.<meta name="viewport" content="width=device-width">这种标记简称"wdw&qu ...

随机推荐

  1. javaScript(4)---数据类型

    javaScript(4)---数据类型 第4章 数据类型 学习要点: 1.typeof操作符 2.Undefined类型 3.Null类型 4.Boolean类型 5.Number类型 6.Stri ...

  2. javap

    本词条缺少概述.信息栏.名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具. j ...

  3. Java框架数据库连接池比较 [转贴 2010-3-20 9:57:51]

    现在常用的开源数据连接池主要有c3p0,dbcp和proxool三种,其中: ¨hibernate开发组推荐使用c3p0; ¨spring开发组推荐使用dbcp (dbcp连接池有weblogic连接 ...

  4. centos6-7克隆主机网卡无法启动问题

    1,centos6和redhat6左右的版本  第一,先找到网卡的mac地址,将其配置在配置文件中,重新启动网卡. 故障产生的原因: 由于克隆虚拟机,vmware只是修改了虚拟机的名字等信息,并没有修 ...

  5. clear read-only status问题的解决

    IDEA系工具可能会报出的错误. 解决方法见官方文档吧:Changing Read-Only Status of Files  : https://www.jetbrains.com/help/ide ...

  6. Codeforces Round #479 (Div. 3) C. Less or Equal

    题目地址:http://codeforces.com/contest/977/problem/C 题解:给一串数组,是否找到一个数x,找到k个数字<=x,找到输出x,不能输出-1.例如第二组,要 ...

  7. 一些Gym三星单刷的比赛总结

    RDC 2013, Samara SAU ACM ICPC Quarterfinal Qualification Contest G 思路卡成智障呀! Round 1:对着这个魔法阵找了半天规律,效果 ...

  8. 使用Navicat for MySQL把本地数据库上传到服务器

    服务器系统基本都是基于linux的,这个数据库上传的方式适用于linux的各种版本,比如Ubuntu和Centos(尽管这两个版本各种大坑小坑,但至少在数据库传输上保持了一致性) 当然本地数据库上传到 ...

  9. (转)java之Spring(IOC)注解装配Bean详解

    java之Spring(IOC)注解装配Bean详解   在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看 ...

  10. 云计算一:VMware workstation的安装和使用教程

    VMware workstation的安装和使用教程 一.VMware 安装 1.从网上找到VMware的安装包以及要安装的映像文件,下载到本地,然后备份一份存储到百度云盘. 链接:http://pa ...