JS/CSS积累库

前言
        这篇文章呢我打算积累一些vue使用技巧,比如,在开发过程中遇到的一些奇奇怪怪令人摸不着头脑的问题,如明明使用了mouseover和mouseout为什么就是没有效果呢,诸如此类的问题,我会总结到这里,持续更新,加油。

一、鼠标事件

        今天来分享一个比较有意思的东西,vue在写某些动画的时候遇到的问题,这个问题困扰了很久,现在解决了,但还是不明白到底是收到了什么影响。
        如果遇到鼠标移入移出事件没有效果,但是你觉得代码正确,可就是出不来效果,你可能遇到了和我一样的问题,那就是该项目是移动项目。在手机端,并没有mouseover和mouseout事件,这里我们要把这两个事件对应的换成touchstart和touchend。现在我们来了解一下touch事件,js文档

touchstart事件:当手纸触摸屏幕时触发,即使已经有一个手指放在屏幕上也会触发。
touchend事件:当手指从屏幕上离开的时候触发。
touchmove事件:当手指在屏幕上滑动时连续触发。这个事件发生期间,调用prevent Default()事件 可以阻止某些鼠标事件发生。
touchcancel事件:当系统停止跟踪触摸的时候触发。关于这个时间的确切触发事件,文档中并没有具体说明。

        这里采用动态绑定事件来解决触摸事件的绑定,当然也可以在标签里写上@touchstart,都是可以滴~

<template>
	<div>
		<div ref='ban'>
		{{message}}
		</div>
	</div>
</template>
<script>
export default{
	name:'',
	data(){
		return{
			message:'Tendency'
		}
	},
	mounted(){
		//初始化绑定触摸事件
		this.touchEventAuto();
	},
	methods:{
		touchEventAuto(){
			let _this=this;
				//动态绑定事件
                this.$refs.ban.ontouchstart=function () {              
                    _this.$refs.ban.style.backgroundColor='#eee'
					this.message='Zero'
                }
                this.$refs.ban.ontouchend=function () {
                    _this.$refs.ban.style.backgroundColor='white'
                    this.message='Tendency'
                }
		}
	}
}
</script>

        网上有些说将@mouseover写成@mouseover.native,我发现在这里是不可取的,使用这个的条件是用了非原生html,即用了某些ui插件如element-ui等。同时,大前提是非移动项目。在这些前提下是可以加native的。

  • 2020.6.29 Am

二、文档滑动条

        这次的问题出现在给div设置滑动的时候,滑动条隐藏,换个方式显示滑动到哪里了,间接直观且美观的显示文本滑动条。如图:
在这里插入图片描述
        主要的难点就是如何设置滑动以及美化滚动条,这里想到了如何获取滚动像素,需要用到jQuery,可参考jquery教程(scrollLeft()或scrollTop())
        那么首先给div设置可滑动(overflow-x),然后隐藏滚动条。

<template>
	<div class='mainPageReport'>
		<div>报表1</div>
		<div>报表2</div>
		<div>报表3</div>
	</div>
</template>
<style lang='scss'>
	.mainPageReport{
		width:100%;
		display: flex;
		/*设置div可滑动*/
		overflow-x: scroll;
		
		div{
			/*让div里文本水平居中*/
			text-align: center;
			/*让div里面的内容垂直居中*/
			align-items: center;
			/*让自己垂直居中*/
            align-self: flex-start;
			width:50%;
			height:20vw;
			margin-left: 3vw;
		}
	}
	/*隐藏滑动条*/
	.mainPageReport :: -webkit-scrollbar {
        display:none
    }
</style>

        添加三个按钮,然后给滑动框绑定事件scroll。通过滚动条的值来判断哪个小圆点变亮,优化代码:

<template>
	<div class='out-mainPageReport'>
		<div class='mainPageReport' res='scrolls' @scroll='changeScroll'>
			<div>报表1</div>
			<div>报表2</div>
			<div>报表3</div>
		</div>
		
		<div class="act">
            <div :class="{'blueScroll':scrollCircle[0]}"></div>
            <div :class="{'blueScroll':scrollCircle[1]}"></div>
            <div :class="{'blueScroll':scrollCircle[2]}"></div>
        </div>
	</div>
</template>
<script>
	export default:{
		data() {
			return {
				scrollCircle:[false,false,false]//控制圆点亮度
			}
		},
		methods:{
			changeScroll(){
				//获取滑动文本框滚动条的滚动值
				let ls=$(this.$refs.scrolls).scrollLeft();
                if(ls ==0){//根据实际情况判断
                    this.scrollCircle[1]=this.scrollCircle[0]=true;
                    this.scrollCircle[2]=false;
                }else if(ls >70&& ls<100){
                    this.scrollCircle[0]=false
                    this.scrollCircle[1]=true
                    this.scrollCircle[2]=false
                }else if(ls >150){
                    this.scrollCircle[0]=false
                    this.scrollCircle[1]=this.scrollCircle[2]=true
                }
                //重新渲染scrollCircle元素
                this.scrollCircle=JSON.parse(JSON.stringify(this.scrollCircle));
			}
		}
		
	}
</script>
<style>
	.out-mainPageReport{
		/*给子元素添加一个定位*/
		position: relative;
		/*.......*/
		.act{
                /*根据父级决定定位*/
                position: absolute;
                bottom: 0vw;
                left: 43vw;
                display: flex;
                justify-content: space-between;

                div{
                    width: 3vw;
                    height: 3vw;
                    margin-left: 1vw;
                    border: 1px solid lightblue;
                    border-radius: 3vw 3vw;
                }
            }
            .blueScroll{
                background-color: #0dbaf3;
            }
	}
	
</style>
  • 2020.9.9 Pm

三、强制刷新组件

        今天遇到一个有意思的事儿,如果想要强制刷新组件,这时候该怎么办。搜到了一个帖子,上面方法讲的很详细,我挑了一个适合自己的哈,也是最简单直接了当当当当当的方法。有时间看一下这个贴子,如何强制vue组件重新渲染
        问题的答案就是,在组件上添加key标识,key的作用主要是让vue知道某个组件是由某块数据渲染的,让数据对应的组件有种惟一的对应关系,通过key,vue可以知道那些数据变了,哪些没有变。如果key不变,vue将不会重新渲染组件,如果key改变了,vue会销毁旧的组件重新创建一个。
        原理有了,那我们就开始动手实践。

<template>
	<acomponent :key="index"></my-component>
</template>
<script>
	import acomponent  from './acomponent .vue';
	export default {
		components: { acomponent },
		data() {
			return {
				index: 0
			};
		},
		methods: {
			forceRerender(){
				this.index++;
			}
		},
		mounted(){
			this.forceRerender();
		}
	};
</script>
  • 2020.11.20 Pm

四、画表格的小技巧

        画表格不难,但是把多个表格组合起来就不是很容易,尤其是遇到单元格宽度的border大小占width、设置单元格宽度、以及单元格内容,接下来看下面这几个设置

table{
	/*一般情况下,列表宽度由单元格内容决定,默认值auto,而fixed:列宽由表格宽度和列宽度设定*/
	table-layout:fixed;
	/*属性规定自动换行的处理方法*/
	word-break:break-all;
	/*需要设置固定宽度*/
	width:99vw;
	/*合并表格边框*/
	border-collapse: collapse;
	
	tr{
		th{
			/*文本水平居中*/
			text-align: center;
			/*文本垂直居中*/
            vertical-align: middle;
            /*假如您需要并排放置两个带边框的框,可通过将 box-sizing 设置为 "border-box"。这可令浏览器呈现出带有指定宽度和高度的框,并把边框和内边距放入框中。*/
            box-sizing: border-box;
		}	
	}
}

        后来再画表格的时候发现,在表格外面套个div,这个div必须有一个指定的width才有用

  • 2020.12.17 Pm

五、修改滚动条样式


/*修改滚动条样式*/
    .content::-webkit-scrollbar{
        width:10px;
        height:10px;
        /**/
    }
    .content::-webkit-scrollbar-track{
        background: rgb(239, 239, 239);
        border-radius:2px;
    }
    .content::-webkit-scrollbar-thumb{
        background: #bfbfbf;
        border-radius:10px;
    }
    .content::-webkit-scrollbar-thumb:hover{
        background: #333;
    }
    .content::-webkit-scrollbar-corner{
        background: #179a16;
    }

六、处理数据的小操作

        时隔许久,记录我常用的对数组的操作。

##  数组操作
	var arr1=[1,2,3,4]
一、增加,操作的是原数组
	//向前插入一个元素
	arr1.unshift(0)//[0,1,2,3,4]
	//向后追加一个元素
	arr1.push(5)//[0,1,2,3,4,5]
	//在数组中间插入一个元素,如在第三个位置插入'a'
	arr1.splice(2,0,'a')//[0,1,'a',2,3,4,5]
二、删除,操作的是原数组
	//从数组中删除第一个元素
	arr1.shift()//[1,'a',2,3,4,5]
	//从数组中删除最后一个元素
	arr1.pop()//[1,'a',2,3,4]
	//从数组中删除中间某个元素,案例:删除元素'a'
	arr1.splice(arr1.indexOf('a'),1)//[1,2,3,4]
三,修改,操作的是原数组
	//修改元素数组3,改成'b'
	arr1.splice(arr1.indexOf(3),0,'b')//[1,2,'b',4]
四、复制
	//根据元素下标复制数组,从下标1复制到下标3
	arr1.slice(1,4)
五、排序---箭头函数语法
1、普通数组排序
	//function xxx()相当于()
	//{return xxx}分情况,如果方法体中只有return时,可省略return如下
	//如还有其他则,{  return xxx}必须写全
	arr1.sort((a,b)=>a-b)//升序
	arr1.sort((a,b)=>b-a)//降序
	//上面例子相当于
	arr1.sort((a,b)=>{return a-b}) /*等价于*/ arr1.sort(function(a,b){return a-b})
2、数组中为对象,及对象之间按照某个属性值进行排序
	var arr=[
		{index:3},
		{index:1},
		{index:2}
	]	
	arr.sort((a,b)=>a.index-b.index)
	注:a,b代表的是arr数组下的每一个元素
3、连接两个数组,不修改原数组,返回新数组
	var arrays=arr.concat(arr1) --合并两个数组
4、数组数字相加,条件是该数组内元素必须是数字或者能转换成数组的字符串数组
	var numArr=["1",2,3,4]
	var sum=numArr.reduce((t,n)=>t+parseInt(n)) -- 输出10
5、map函数的使用方法
//据我目前了解map操作数组,如
var arr2=[
	{a:1,b:2},
	{a:2,b:2}
]
var arr3=arr2.map((e)=>{
	return e.a
})
//那么 arr3输出结果为[1,2],由此可见e代表的是数组中每个元素,这样操作不会影响到原数组.
6、es6数组去重
var a = [1,2,3,3,3,4,4,5,6,6]
//先用set对数组进行去重,然后将set对象转换成数组对象
Array.from(new Set(a))
//输出:[1,2,3,4,5,6]
//Array.form可以将类似数组形式转换成真正的数组
//某些用法可以类比map,如在上例中,对去重的数组进行自加
Array.from(new Set(a),(v)=>v+=v)
//输出:[2,3,6,8,10,12]
##   对象操作
	var obj={}
一、增加属性
	obj.name="张三"
	obj.age=18
	-- 输出:{name:"张三",age:18}
二、删除属性
	delete obj.age;
	-- 输出:{name:"张三"}
三、查找属性
	Object.keys(obj)//这个东西是obj对象的所有属性的数组
	:查看obj对象里是否含有name属性
	console.log(Object.keys(obj).indexOf("name")!=-1?"存在name属性":"不存在name属性")
四、修改属性值
	obj.name="李四"
	-- 输出:{name:"李四"}
五、合并对象
	//这样操作会返回一个修改后的对象,如果不用原对象承接,也是会直接影响到原对象的
	Object.assign(obj,{class:"三年一班"})
	-- 输出:{name:"李四",class:"三年一班"}
	
## 补充: 箭头函数
	基础格式: ()=>{}
		作用范围,目前我在用的时候,只有使用匿名函数的时候在用这个,
	而且还需要注意,如果你的函数里有使用到this这个关键字,最好还是
	不要用箭头函数,因为箭头函数里的this指向的是父级this,谁调用
	的 this 指向的就是谁的当前所在的作用域的对象。
	一个参数的格式:参数名=>{}::e=>{}
	一个参数且方法体里只有return::e=>e,返回的是e
	多个参数且方法体中还有其他内容::(a,b)=>{var x=a,y=b return x+""+y}
	例如上/述map的使用中还可以这样写:arr2.map(e=>e.a);
	==== 重   点 ====
	1、参数区域()可以创建初始值,即若调用时不传参数,就是这个值,且 无需使用类型声明(varconstlet,var test=(n=1)=>++n
	test()   -- 输出: 2
	test(5)  --输出: 6
	2、参数括号内定义的变量是局部变量(默认参数),函数体内{}不使用
	var定义的变量是全局变量,函数体内{}var定义的变量是局部变量
## 规律性字符串拼接
	split() 、join()
	例:var array = [1,2,3,4,5]
	1)"-"将array元素拼接
	var arr3 = array.join("-");	-- 输出"1-2-3-4-5"
	2) 将arr3还原成array
	var arr4 = arr3.map(e=>parseInt(e)) --输出[1,2,3,4,5]
	: join函数可以不传参数,直接将数组各个元素转换成字符串进行拼接

## 补充过滤器(filter)用法,数组对象的方法
	作用是返回符合条件的元素
	var b = [
				{
					name:"A",
					value:1
				},
				{
					name:"B",
					value:1
				}
			]
	例如返回name是A的对象
	console.log(b.filter(function(v,i,arr){
		return v.name==='A'
	}))	
##	补充reduce函数,数组方法,有累计叠加的功效
	作用是将数组进行整合然后重组,
	将其累计或添加到新数组形成一个整体或添加到对象中
	例如:
	var names=["app","user","permission","errorLog"]
	var modules=[{
		state:{},mutations:{},actions:{}
	},{
		state:{},mutations:{},actions:{}
	},{
		state:{},mutations:{},actions:{}
	},{
		state:{},mutations:{},actions:{}
	}]
	例如我想得到一个names数组和modules数组按照下标匹配的新对象
	/*
		{
			app:{state:{},...},
			user:{state:{},...},
			permission:{state:{},...},
			errorLog:{state:{},...}
		}
	*/
	/*
		1、reslt:是最终要得到的内容,其类型可以是Object,Array,Number等,
		并且每次循环都要返回该值,然后待下次循环时可以使用,
		2、reduce的第二个值可传可不传,如果不传,
		那么result的值将会取该数组下标0的值,那么value值取该数组第二个值
	*/
	var result=names.reduce((result,value,index)=>{
		result[value]=modules[index]
		return result
	},{})
##	补充:some函数,数组方法
	作用:方法测试数组中是不是至少有 1 个元素通过了被提供的函数测试。
	它返回的是一个 Boolean 类型的值。
	const array = [1, 2, 3, 4, 5];

	// checks whether an element is even
	const even = (element) => element % 2 === 0;

	console.log(array.some(even));
	// expected output: true
	
	callback
		用来测试每个元素的函数,接受三个参数:
		element
		数组中正在处理的元素。
		index 可选
		数组中正在处理的元素的索引值。
		array可选
		some()被调用的数组。
	thisArg可选
		执行 callback 时使用的 this 值。

七、var const let区别

一、var 声明的变量会存在window对象上,而constlet则不会;实际上可以用window.a得到
二、var 声明的变量存在变量提升,即在使用var声明变量之前使用到该变量时仅会提示undefined,不会报错
三、var 声明的变量可以跨作用域访问到,而constlet不行
四、var 可以声明相同变量在同一作用域下,而constlet不行
五、在块儿级作用域下,如果外部使用var 声明了一个变量a,则在块级作用域中如果再用letconst再次声明相同变量时,则外部使用var声明的a会无法直接得到,需要用到window.a的方式去获取。
六、const声明的变量,一旦声明必须赋值,不能使用null占位。且声明后不能再修改。如果声明的是个对象,可以修改对象的属性。

2021.5.17 Am

八、汉字拼音转换(小问题)

        需要用到一个js(js-pinyin),使用如下。

	1、npm引入
		npm管理的js引入方法应该都在上面的连接里,我就不多说了
	2、html直接引入pinyin.js
	<script type="text/javascript" src="js/lib/js-pinyin/pinyin.js"></script>
	3、使用:
		var pinyin = new Pinyin();
		//checkPolyphone: 是否检查多音字
		//charCase:	输出拼音的大小写模式,0-首字母大写;1-全小写;2-全大写
		pinyin.setOptions({checkPolyphone: true, charCase: 0});
		let name="河南加油!!!!郑州加油!!!!"
		//获取全拼,首字母大写
		console.log(pinyin.getFullChars(name));//HeNanJiaYou!!!!ZhengZhouJiaYou!!!!
		//简拼
		console.log(pinyin.getCamelChars(name));//HNJY!!!!ZZJY!!!!
	4、直接用简拼(getCamelChars)汇报k未定义错误,这个工具包中简拼可能需要修改一下原先的js
	在pinyin.js中找到并修改成j即可

九、vuex 将数据保存在session中

插件:vuex-along
安装:

npm install vuex-along --save
# or
yarn add vuex-along

用法

import createVuexAlong from 'vuex-along'

export default new Vuex.Store({
  state:{...},
  modules:{
		home:home
  },
  plugins: [createVuexAlong({
		name:"localData",
		session:{
			list:[home.userMessage]
		}
	})]
});

十、es5继承

function Persion(name,age){
	this.name=name;
	this.age=age
}
function Student(name,age,score){
	//继承属性
	Persion.call(this,name,age)
	this.score=score;
}
//es5原型继承——继承方法
//子类原型指向父类实例
Student.prototype=new Persion();
//子类原型构造器指向子类
Student.prototype.constructor=Student;

十一、Base64加密

npm install crypto-js

import CryptoJS from "crypto-js"
 
//encrypt
var rawStr = "hello world!";
var wordArray = CryptoJS.enc.Utf8.parse(rawStr);
console.log(1,wordArray)
var base64 = CryptoJS.enc.Base64.stringify(wordArray);
console.log(2,base64)
 
//decrypt
var parsedWordArray = CryptoJS.enc.Base64.parse(base64);
var parsedStr = parsedWordArray.toString(CryptoJS.enc.Utf8);
console.log(3,parsedStr);

十二、根据code查找目录树全目录名称

参考:树形数据 根据 code 查找 code的全路径

// 通过 code 反查全路径
// 参数:list: 属性数据 targetCode: 目标code fullPathList: 记录查找路径list
    getFullListByCode(list, targetCode, fullPathList = []) { // fullPathList 全路径
      let fullList
      for (let i = 0; i < list.length; i++) {
        let item = list[i]
        let { code, name, childList } = item
        let newfullPathList = [...fullPathList, { code, name }] // 存储上一级路径的数据
        if (item.code === targetCode) {
          return newfullPathList
        } if (childList && childList.length) {
          fullList = this.getFullListByCode(childList, targetCode, newfullPathList)
          if (fullList) return tabList
        }
      }
      return fullList
    }

十三、Vue2全局监听eventHub(Bus总线)

//main.js
import Vue from "vue"
Vue.prototype.$eventHub=new Vue();

//任意一个顶级组件用来监听
export default{
	mounted(){
		this.$eventHub.$on('myChangeEvent',this.onChange)
	},
	beforeDestroy(){
		this.$eventHub.$off('myChangeEvent')
	},
	methods:{
		onChange(data){
			console.log(data)
		}
	}
}

//子孙组件用来广播
export default{
	
	methods:{
		changeMyEvent(){
			this.$eventHub.$emit('myChangeEvent',{value:1})
		}
	}
}


十四、数组分组与统计(lodash)

这里用到了lodash这个工具,注意第二个参数,若是函数则可以利用返回唯一值来多条件筛选

let arr=[
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"02"},
	{"series":"大会议室A01","type":"03"},
	{"series":"大会议室A01","type":"04"},
	{"series":"大会议室A02","type":"04"}]
//假设你已经引入了lodash
Object.values(_.groupBy(arr,v=>`${v.series}#${v.type}`)).map(e=>{
    return _.uniqBy(e,m=>{
        m.count=e.length
        return `${m.series}#${m.type}`
    })
}).flat(1)
//
一、.groupBy(collection,func)函数
参数:
	collection:Object||Array,
	func:Function,
返回值:
	Object
1、例:单条件分组,根据班级分
let a=[
	{classroom:'一年一班',name:'小兰'},
	{classroom:'一年一班',name:'小美'},
	{classroom:'一年二班',name:'小马'},
	{classroom:'一年二班',name:'小华'},
	{classroom:'一年三班',name:'小红'},
	{classroom:'一年三班',name:'小绿'},
]
//开始分组
_.groupBy(a,'classroom')
//输出:
{
"一年一班":[{"classroom":"一年一班","name":"小兰"},{"classroom":"一年一班","name":"小美"}],
"一年二班":[{"classroom":"一年二班","name":"小马"},{"classroom":"一年二班","name":"小华"}],
"一年三班":[{"classroom":"一年三班","name":"小红"},{"classroom":"一年三班","name":"小绿"}]
}
2、例:多条件分组,根据班级和时间分组
let a=[
	{classroom:'一年一班',name:'小兰',time:'2060-1-1'},
	{classroom:'一年一班',name:'小王',time:'2060-1-1'},
	{classroom:'一年一班',name:'小美',time:'2060-1-2'},
	{classroom:'一年二班',name:'小马',time:'2060-1-2'},
	{classroom:'一年二班',name:'小赵',time:'2060-1-3'},
	{classroom:'一年二班',name:'小刘',time:'2060-1-3'},
	{classroom:'一年三班',name:'小红',time:'2060-1-4'},
	{classroom:'一年三班',name:'小绿',time:'2060-1-5'},
	{classroom:'一年三班',name:'小黄',time:'2060-1-5'},
]
//开始分组:
_groupBy(a,v=>`${v.classroom}#${v.time}`)//把字段连接起来,作为生成的对象的唯一属性
//输出:
{
	"一年一班#2060-1-1":[
		{"classroom":"一年一班","name":"小兰","time":"2060-1-1"},
		{"classroom":"一年一班","name":"小王","time":"2060-1-1"}
	],
	"一年一班#2060-1-2":[
		{"classroom":"一年一班","name":"小美","time":"2060-1-2"}
	],
	"一年二班#2060-1-2":[
		{"classroom":"一年二班","name":"小马","time":"2060-1-2"}
	],
	"一年二班#2060-1-3":[
		{"classroom":"一年二班","name":"小赵","time":"2060-1-3"},
		{"classroom":"一年二班","name":"小刘","time":"2060-1-3"}
	],
	"一年三班#2060-1-4":[
		{"classroom":"一年三班","name":"小红","time":"2060-1-4"}
	],
	"一年三班#2060-1-5":[
		{"classroom":"一年三班","name":"小绿","time":"2060-1-5"},
		{"classroom":"一年三班","name":"小黄","time":"2060-1-5"}
	]
}
二、uniqBy去重
let a=[
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"07"},
	{"series":"大会议室A01","type":"02"},
	{"series":"大会议室A01","type":"03"},
	{"series":"大会议室A01","type":"04"},
	{"series":"大会议室A02","type":"04"}]
//开始去重
_.uniqBy(arr,v=>v.series+'-'+v.type)
//输出:
[
	{series: '大会议室A01', type: '07'},
	{series: '大会议室A01', type: '02'},
	{series: '大会议室A01', type: '03'},
	{series: '大会议室A01', type: '04'},
	{series: '大会议室A02', type: '04'},
]


十五、矩阵CSS(gaps,grid,box-sizing)

1、gap:盒子里上下边距和左右边距的间隔,依托于grid布局和flex布局
2、box-sizing:
	content-box:width 与 height 只包括内容的宽和高,不包括边框(border),内边距(padding),外边距(margin)。
	border-box:width 和 height 属性包括内容,内边距和边框,但不包括外边距。
	box-sizing对外比较友好,对内可能需要自己根据实际情况调整
<style>
	:root{
		--box-width:300px;
		--box-height:100px;
	}

	.container{
		margin:0 auto;
		width:calc( var(--box-width) * 3 + 100px);
		height: calc( var(--box-height) * 4 + 30px);
		border: 1px solid black;
		display: flex;
		gap:  10px 50px;
		padding: 10px;
		flex-wrap: wrap;
		align-content: space-around;		
	}

	.box{
		width: var(--box-width);
		height: var(--box-height);
		background-color: antiquewhite;
	}
</style>
<div class="container">
	<div class="box"></div>
</div>
<!--或者-->
3、grid:
	grid-template-columns:纵列中每列的宽度,因为纵裂受宽度影响,有几列设置几个
	grid-template-rows:横排中每排的高度,因为横排受高度影响,有几排设置几个
<style>
	:root{
		--box-width:300px;
		--box-height:100px;
	}

	.container{
		margin:0 auto;
		width:calc( var(--box-width) * 3 + 100px);
		height: calc( var(--box-height) * 4 + 30px);
		border: 1px solid black;
		display: grid;
		grid-template-columns:var(--box-width) var(--box-width) var(--box-width);
		gap:  10px 50px;
		padding: 10px;	
	}

	.box{
		width: var(--box-width);
		height: var(--box-height);
		background-color: antiquewhite;
	}
</style>
<div class="container">
	<div class="box"></div>
</div>

十六、目录树,查找指定子孙目录下的所有目录树

function collectCodes(treeArray, targetCode, collectedCodes = []) {
    const findNode = findNodeByCode(treeArray, targetCode);
    
    if (findNode) {
        collectChildCodes(findNode, collectedCodes);
    }
    
    return collectedCodes;
}

function findNodeByCode(treeArray, targetCode) {
    for (const node of treeArray) {
        if (node.code === targetCode) {
            return node;
        }
        if (node.children && node.children.length > 0) {
            const foundNode = findNodeByCode(node.children, targetCode);
            if (foundNode) {
                return foundNode;
            }
        }
    }
    return null;
}

function collectChildCodes(node, collectedCodes) {
    collectedCodes.push(node.code);
    if (node.children && node.children.length > 0) {
        for (const childNode of node.children) {
            collectChildCodes(childNode, collectedCodes);
        }
    }
}

// 使用例子
const treeArray = [
    // ... (你提供的树形数组)
    {
		code:'1'
	}
];

const targetCode = "56781"; // 你想要选择的目录树中任意子目录或子孙目录的 code
const result = collectCodes(treeArray, targetCode);

console.log("收集到的 codes:", result);

十七、下载文件

//生成文件
let blob = new Blob(['测试']);
//创建下载链接
let href = URL.createObjectURL(blob);
//创建下载标签
let link = document.createElement('a');
//设置文件名
let fileName='测试下载.txt'

//download:导致浏览器将链接的 URL 视为下载资源。
link.download=fileName;
link.href=href;

link.click();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值