1.字符串占位宽度

  • 计算占位宽度:字符串的占位宽度除了涉及到具体的字符串内容,还与字体大小有关,可以将其放入Dom中来获取实际占位宽度
//计算字符串的占位宽度
function getTextWidth(str = '',font_size=12) {
const dom = document.createElement('span')
dom.style.display = 'inline-block'
dom.style['font-size'] = font_size + 'px'
dom.textContent = str
document.body.appendChild(dom)
const width = dom.clientWidth
document.body.removeChild(dom)
return width;
} //计算字符串数组中的最大宽度
function getMaxWidthByArray(text_arr=[],font_size=12){
//计算设备编号占位的最大宽度
var max_width = 0
text_arr.forEach(function(str){
var now_text_width = getTextWidth(str,font_size)
if(now_text_width > max_width){
max_width = now_text_width
}
})
return max_width
}

2.树形对象转换

  • 由来:多层级数据在存储时,是每个数据平级存储,通过id与pid字段进行进行关联,后台返回这些数据时,可能没经过转换,直接以数组形式返回,前端需要自己转换成树形对象
<script>
//封装方法:一维数组转树形对象
function buildTree(array, id = "id", parent_id = "pid") {
//不是数组则返回
if (!Array.isArray(array)) {
return []
}
// 创建临时对象
let temp = {};
// 创建需要返回的树形对象
let tree = {};
// 先遍历数组,将数组的每一项添加到temp对象中
for (let i in array) {
temp[array[i][id]] = array[i];
} // 遍历temp对象,将当前子节点与父节点建立连接
for (let i in temp) {
// 判断是否是根节点下的项
if (temp[i][parent_id] !== 0) {
//是否存在该父节点 存在才添加
if (temp[temp[i][parent_id]]) {
//父节点是否已经存在children属性 没有则新建
if (!temp[temp[i][parent_id]].children) {
temp[temp[i][parent_id]].children = new Array()
}
temp[temp[i][parent_id]].children.push(temp[i])
}
} else {
tree[temp[i][id]] = temp[i];
}
} return tree;
}
</script>
<script>
//待转换的数据格式
var menu_list = [
{
id: 1,
pid: 0,
title: "一级菜单"
},
{
id: 2,
pid: 1,
title: "二级菜单A"
},
{
id: 3,
pid: 1,
title: "二级菜单B"
}
]
//转换
var menu_tree = buildTree(menu_list, "id", "pid")
console.log(menu_tree)
</script>

  • 思路解析:

    1.函数假定条件:根节点id必须是0,也就是说一级节点的pid要==0

    2.先假设所有节点都是一级节点,设置临时对象进行存储,然后遍历临时对象中的key,将其挂载到对应的pid中

    3.遍历临时对象的节点,如果父节点是0,则添加到目标树形对象中,如果不是,则添加到对应的pid中(重要!!!,表面是给一级属性赋值,其实因为引用的关系,可能操作的是更深层次的节点)

    4.返回目标树形对象(没有找到pid的节点数据将被丢失)

  • 总结:正常的思路,都是操作树形对象,给所有的节点找到对应的pid节点进行挂载,因为pid是多层次嵌套的,为了找到对应的pid,通常所需要递归遍历,但是这里非常聪明,利用对象是引用类型的机制,直接操作一级节点来代替多层次嵌套节点

3.数字转换为金额格式

  • 使用toLocaleString()可将小数转成金额格式
  • 注意,如果是整数,需要转换成小数才能调用toLocaleString()
var num = 123456789
//转换成小数
num = parseFloat(num)
//转换金额格式
num.toLocaleString() //'123,456,789'
  • 封装一个方法:将数字的每个字符拆开遍历(从后往前)重新拼接,遇到第3*n个字符且不是最后一个字符,则额外多输出一个","
<script>
function numForamt(nun){
//转换成字符串,在转换成数组
var arr = (nun + '').split('')
//要输出的结果
var result = ""
//遍历数组元素,从后面开始,每3个元素就添加一个 ","
for(var i = arr.length - 1;i>=0;i--){
//当前下标(从前往后)
var index = arr.length - 1 - i
//是否是第3*n个字符,且不是最后一个字符,需要额外输出一个 ","
if((index + 1)%3 == 0 && index != (arr.length - 1)){
//拼接
result = ("," + arr[i] + result)
}else{
//拼接
result = (arr[i] + result)
}
} return result
}
console.log(numForamt(123456789)) //123,456,789
</script>

4.浮点数乘法

  • 浮点数直接计算会有问题,自己封装了一个,先转换乘整数进行计算,后除以对应的百分数即可
<script>
//小数乘法,转换为正数再计算,然后在除以对应的百分数
function floatMultiplication(value = 0, multiplier){
//转换为整数的函数
function toIntValue(_value){
//小数点下标
var index = _value.toString().indexOf('.')
//如果是整数,直接返回
if(index == -1){
return {
intValue: _value, divisor: 1
}
}
//小数点后的未数(需要被除的数)
var divisor = Math.pow(10, _value.toString().length - index - 1)
//转换为整数
var intValue = Number(_value.toString().slice(0,index) + _value.toString().slice(index+1))
return {
intValue, divisor
}
} //转换为正数计算,后再整除10的幂
var valueObj = toIntValue(value)
var multiplierObj = toIntValue(multiplier)
return (valueObj.intValue * multiplierObj.intValue) / (valueObj.divisor * multiplierObj.divisor)
} //原生测试 不准
console.log('1.5*1.2 = ',1.5*1.2) //1.7999999999999998 //测试
console.log(floatMultiplication(1.5,1.2)) //1.8
</script>

5.递归查询是否有目标值

  • 在多级嵌套的数据中,通过递归的方式查询是否存在目标值
  • 需要4个人参数:目标数据(数组或者对象),目标值,目标值所在的属性,嵌套数组的属性值
<script>
var list = [
{
value: 1, children: [
{
value: 2,
children: [
{
value: 3
},
{
value: 4
}
]
}
]
},
{
value: 5,children: [
{
value: 6
},
]
},
{
value: 7,children: [
{
value: 8
}
]
}
] //多级嵌套数据是否有目标值
//参数一:目标数据(数组或者对象)
//参数二:目标值
//参数三:目标属性
//参数四:数组属性名称
function hasValue(data = {},target_value = '', key = 'value', list_key = 'children'){
//数组类型
if(Array.isArray(data)){
//遍历元素,依次判断
for(var i=0;i<data.length;i++){
if(data[i][key] == target_value){
//已经找到匹配值 返回查找结果
return true }else if(data[i][list_key] && data[i][list_key].length > 0){
//没找到,从子元素中递归查找,并得到查找结果
var flag = hasValue(data[i][list_key],target_value)
//如果找到,则退出函数
if(flag){
return true
}
}
}
}else if(data && typeof data == 'object'){
//对象类型
if(data[key] == target_value){
//返回匹配结果
return true
}
}else{
//基本类型
if(data == target_value){
//返回匹配结果
return true
}
} //返回本轮查找结果(走到最后一步就是没找到)
return false
} var flag = hasValue(list,5)
</script>

Javascript 常用封装(二)的更多相关文章

  1. javascript 常用手势 分析

    javascript 常用手势, 个人觉得有3个 tap,swipe(swipeLeft,swipeRight,swipeTop,swipeRight),hold tap 是轻击 判断的原则是,在to ...

  2. Javascript常用的设计模式详解

    Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...

  3. 原生JavaScript常用本地浏览器存储方法一(方法类型)

    有时需要将网页中的一些数据保存在浏览器端.好处就是当下次访问页面时,直接就可以从本地读取数据,不需要再次向服务器请求数据.目前常用的有以下几种方法: 1.cookie cookie会随着每次HTTP请 ...

  4. JavaScript 常用功能总结

    小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式. 目录: 众所周知,JavaScri ...

  5. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  6. JavaScript基本概念(二)

    JavaScript 基本概念(二) 操作符和语句 目录 操作符 一元操作符 位操作符 布尔操作符 乘性操作符 其他操作符 语句部分 说起操作符,回忆下上一篇文章末尾说的话. 操作符 一元操作符 ++ ...

  7. javascript常用代码大全

    http://caibaojian.com/288.html    原文链接 jquery选中radio //如果之前有选中的,则把选中radio取消掉 $("#tj_cat .pro_ca ...

  8. Javascript 常用函数【3】

    jquery选中radio //如果之前有选中的,则把选中radio取消掉 $("#tj_cat .pro_category").each(function() { if ($(t ...

  9. javascript常用知识点集

    javascript常用知识点集 目录结构 一.jquery源码中常见知识点 二.javascript中原型链常见的知识点 三.常用的方法集知识点 一.jquery源码中常见的知识点 1.string ...

  10. 第一百三十节,JavaScript,封装库--连缀

    JavaScript,封装库--连缀 学习要点: 1.连缀介绍 2.改写库对象 本章我们重点来介绍,在调用库的时候,我们需要能够在前台调用的时候可以同时设置多个操作,比如设置CSS,设置innerHT ...

随机推荐

  1. 论文解读 -TongGu:专注于文言文的大模型

    一.简要介绍 文言文是通往中国古代丰富遗产和智慧的门户,但其复杂性给大多数没有专业知识的现代人构成了巨大的理解障碍.虽然大型语言模型(LLM)在自然语言处理(NLP)方面显示出了显著的能力,但它们在文 ...

  2. Angular 17+ 高级教程 – Routing 路由 (功能篇)

    前言 这篇只讲功能不讲原理.没有循序渐进,没有由浅入深,一个主题讲到底. Route 目录 上一篇 Angular 17+ 高级教程 – Routing 路由 (原理篇) 下一篇 Angular 17 ...

  3. Azure – Front Door (AFD)

    前言 会研究到 Azure Front Door (AFD) 是因为想安装 WAF. 结果研究了一圈, 发现 AFD 好弱啊. 有许多功能都有 limitation. Limitation & ...

  4. .NET 8 + Vue/UniApp 高性能前后端分离框架

    前言 作为一名开发者,我们知道能够简化开发流程.提升工作效率的工具是至关重要的. 推荐一款前后端分离框架 Admin.NET(ZRAdmin),它不仅可以满足项目开发的需求,还应用了一些新的特性,如R ...

  5. [C++] Rander

    注 这个Rander对单个数据的平均分散不太优秀,但是获取大量数据十分平均 当前版本 2.0 for Windows 功能 int rander::reset() 按默认大小重置随机数序列,返回默认大 ...

  6. 第27天:安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞 - Shortcut

    https://www.kancloud.cn/manual/thinkphp5_1/354000 ThinkPHP-Vuln-master

  7. 80篇国产数据库实操文档汇总(含TiDB、达梦、openGauss等)

    国产数据库发展得如火如荼,数据库的国产化替代也正在进行中.最近,有越来越多的朋友都加入了学习国产数据库的队伍中,本文便选取了墨天轮技术社区的国产数据库流行度排行榜上排名靠前的几个数据库,整理了相关的实 ...

  8. js中常见的继承

    1. 使用原型链继承 2. 通过构造函数继承 通过构造函数,创建的实例,可以访问构造函数的属性和方法,以及可以访问构造函数的原型对象 prototype 上的数据和方法 : 3. 组合继承(1 和 2 ...

  9. 超越预期:Containerd 如何成为 Kubernetes 的首选容器运行时

    > 作者:尹珉,KubeSphere Ambassado,rKubeSphere Contributor,KubeSphere 社区用户委员会杭州站站长. 踏上 Containerd 技术之旅 ...

  10. 从0到1实现项目Docker编排部署

    在深入讨论 Docker 编排之前,首先让我们了解一下 Docker 技术本身.Docker 是一个开源平台,旨在帮助开发者自动化应用程序的部署.扩展和管理.自 2013 年推出以来,Docker 迅 ...