js小技巧
1.获取浏览器cookie值const cookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift(); cookie('_ga'); Result: "GA1.2.1929736587.1601974046"2.将RGB转换为16进制const rgbToHex = (r, g, b) =>"#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); rgbToHex(0, 51, 255); Result: #0033ff`3.复制到剪切板(使用 navigator.clipboard.writeText 轻松将任何文本复制到剪贴板上)const copyToClipboard = (text) => navigator.clipboard.writeText(text); copyToClipboard("Hello World");4.检查日期是否有效const isDateValid = (...val) => !Number.isNaN(new Date(...val).valueOf()); isDateValid("December 17, 1995 03:24:00"); Result: true5.找出一年中的某一天(即给出一个日期,程序给出属于本年的第多少天)const dayOfYear = (date) =>Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24); dayOfYear(new Date()); Result: 2726.将字符串首字母大写const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1) capitalize("follow for more") Result: Follow for more7.计算两个日期之间相差的天数const dayDif = (date1, date2) => Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 86400000) dayDif(new Date("2020-10-21"), new Date("2021-10-22")) Result: 3668.清除所有cookieconst clearCookies = document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.\*/, `=;expires=${new Date(0).toUTCString()};path=/`));9.生成随机16进制const randomHex = () => `#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")}`; console.log(randomHex()); Result: #92b00810.数组去重const removeDuplicates = (arr) => [...new Set(arr)]; console.log(removeDuplicates([1, 2, 3, 3, 4, 4, 5, 5, 6])); Result: [ 1, 2, 3, 4, 5, 6 ]11.从URL中获取查询参数const getParameters = (URL) => {URL = JSON.parse('{"' + decodeURI(URL.split("?")[1]).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') +'"}');return JSON.stringify(URL)}; getParameters(window.location) Result: { search : "easy", page : 3 }12.从日期中获取“时分秒”格式的时间const timeFromDate = date => date.toTimeString().slice(0, 8); console.log(timeFromDate(new Date(2021, 0, 10, 17, 30, 0))); Result: "17:30:00"13.确认奇偶数//通过数据%2来判断并返回布尔类型const isEven = num => num % 2 === 0; console.log(isEven(2)); Result: True14、求平值const average = (...args) => args.reduce((a, b) => a + b) / args.length;average(1, 2, 3, 4); Result: 2.515.回到顶部(适用于网页右下角快捷返回功能)//通过将x、y设置为0来实现const goToTop = () => window.scrollTo(0, 0); goToTop();16.反转字符串const reverse = str => str.split('').reverse().join(''); reverse('hello world'); Result: 'dlrow olleh'17.检查数组是否为空//通过对数组长度判断来确定是否为空const isNotEmpty = arr => Array.isArray(arr) && arr.length > 0; isNotEmpty([1, 2, 3]); Result: true 18.获取用户选定的文本const getSelectedText = () => window.getSelection().toString(); getSelectedText();19.打乱数组const shuffleArray = (arr) => arr.sort(() => 0.5 - Math.random()); console.log(shuffleArray([1, 2, 3, 4])); Result: [ 1, 4, 3, 2 ]20、检查用户是否处于暗模式const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches console.log(isDarkMode) Result: True or False
查看详情点赞评论收藏浏览172023-03-17 13:33:12css 限制显示行数,超出部分加上...(兼容IE)
在我们日常前端开发中,经常会遇到列表或者首页文本只显示几行等问题。一般我们通过css 就可以解决。代码:/*一行文本超出显示省略号*/ .one-line { overflow: hidden; white-space: nowrap; display: block; -o-text-overflow: ellipsis; text-overflow: ellipsis; } /*多行文本超出显示省略号*/ .two-line { overflow: hidden; -o-text-overflow: ellipsis; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; /* 可以显示的行数,超出部分用...表示*/ -webkit-box-orient: vertical; }但是在IE中有兼容问题,虽然现在很少再兼容IE了。有兴趣的同学可以了解下。兼容IE // 处理多行文本超出部分隐藏 function wordLimit(cName, wordLength) { var cName = document.getElementsByClassName(cName); for (var i = 0; i < cName.length; i++) { var nowHtml = cName[i].innerHTML; var nowLength = cName[i].innerHTML.length; if ( nowLength > wordLength) { cName[i].innerHTML = nowHtml.substr(0, wordLength) + '…'; } } };
查看详情点赞评论收藏浏览502023-03-10 21:45:21这样喝酒!真的好吗?即使做人再失败或者感情很失意!
分享这个话题,不是一时心血来潮,也不是看不起这样喝酒的人,只是自己看到的这一幕有感而发。只是感叹!!这个时代真的不光是表面的光彩,绝大一部分的人都在为了生计努力打拼,努力挣钱努力让生活过得更好。有一首歌和这个短视频确实很戳心,就是《用力活着》我们都在用力的活着酸甜苦辣里醒过也醉过也曾倔强脆弱依然执着相信花开以后会结果我们都在用力的活着爱恨成败里赢过也输过也曾灿烂失落无悔选择相信磨难历尽是收获成长的路上有几程曲折这首歌触动了太多的人,道出了太多的辛酸,很多人成功了,但是他们背后流的汗水,竭尽全力的付出,都是其他人看不到的。当然了,回归正题。成功的人毕竟只是少数,都说这个世界上的财富是掌握在20%的人手中,那么剩下的80%人呢,他们一天的生活是什么样的,他们在经历什么样的人生。不可而知,但是我知道,他们肯定在这个社会上努力着,默默为了家庭,为了亲人和自己挥洒汗水。甚至有一部分人曾经走到了绝望。照片上的时间在晚上2点多,我没有睡着,准确的说还没有睡。我听到下面有人在说话声音比较大,习惯性的想看看发生了什么事情。我看到他趟在草坪上说着什么,像诉说着什么也像哭,不久就在草坪上睡着了。我不知道他发生了什么,或许是事业失败了,或许是感情收到了挫折,又或许生活的压力太大 。就他一个人,不知道他的家人在哪里,不知道他一个人怎么到的这儿。通过后面救护车和医生的沟通,我知道他是喝醉了。神志不清晰,不知道家在哪里也没有联系方式,手机密码解不开。总之怎么说呢,一个可怜人。这个社会有很多这样的人。说真的,分享这个话题不是看不起他,相反对这个事情,我表示同情。没有亲人照顾,也没有爱人陪伴,也没有朋友知道他在这里。是经历了什么绝望的事情,让他喝成这样,我猜想可能是因为应酬,最后一想不太可能。如果是生意上的事情,喝酒之后肯定有朋友问候或者送他回家。多半是因为生活、工作、感情上的压力导致。有谁能说自己没有喝成这样或者以后会喝成这样。酒不醉人人自醉,多是人到伤情时。当自己到了这个时候,会不会比他更不堪,受打击之后会不会更极端。有多少人因为生活的压力,在绝望的时候,选择结束自己的生命,这样的例子太多了。坚强的人,会重新站起来,脆弱的人,也要努力让自己站起来!怎么说呢,只能说,当我们经历选择的时候多考虑一点,多往好的地方想想,适当的放纵的自己可以,过后生活得照样过起走。生活中,还是多给一些关心,一些理解。生活中,多坚持,努力一点,保持学习!希望他没事!
查看详情点赞评论收藏浏览452023-03-10 19:31:04three学习路线(二)
1.第一个3D案例—透视投影相机Threejs如果想把三维场景Scene渲染到web网页上,还需要定义一个虚拟相机Camera,就像你生活中想获得一张照片,需要一台用来拍照的相机。a.透视投影相机PerspectiveCameraThreejs提供了正投影相机OrthographicCamera (opens new window)和透视投影相机PerspectiveCamera (opens new window)。本节课先给大家比较常用的透视投影相机PerspectiveCamera。透视投影相机PerspectiveCamera本质上就是在模拟人眼观察这个世界的规律。// 实例化一个透视投影相机对象 const camera = new THREE.PerspectiveCamera();b.相机位置.posiiotn生活中用相机拍照,你相机位置不同,拍照结果也不同,threejs中虚拟相机同样如此。比如有一间房子,你拿着相机站在房间里面,看到的是房间内部,站在房子外面看到的是房子外面效果。相机对象Camera具有位置属性.posiiotn,通过位置属性.posiiotn可以设置相机的位置。//相机在Three.js三维坐标系中的位置 // 根据需要设置相机位置具体值 camera.position.set(200, 200, 200); c.相机观察目标.lookAt()你用相机拍照你需要控制相机的拍照目标,具体说相机镜头对准哪个物体或说哪个坐标。对于threejs相机而言,就是设置.lookAt()方法的参数,指定一个3D坐标。//相机观察目标指向Threejs 3D空间中某个位置 camera.lookAt(0, 0, 0); //坐标原点 camera.lookAt(0, 10, 0); //y轴上位置10 camera.lookAt(mesh.position);//指向mesh对应的位置d.判断相机相对三维场景中长方体位置你可以把三维场景中长方体mesh想象为一个房间,然后根据相机位置和长方体位置尺寸对比,判断两者相对位置。你可以发现设置相机坐标(200, 200, 200),位于长方体外面一处位置。// 长方体尺寸100, 100, 100 const geometry = new THREE.BoxGeometry( 100, 100, 100 ); const mesh = new THREE.Mesh(geometry,material); // 相机位置xyz坐标:0,10,0 mesh.position.set(0,10,0); // 相机位置xyz坐标:200, 200, 200 camera.position.set(200, 200, 200); e.定义相机渲染输出的画布尺寸你生活中相机拍照的照片是有大小的,对于threejs而言一样,需要定义相机在网页上输出的Canvas画布(照片)尺寸,大小可以根据需要定义,这里先随机定义一个尺寸。Canvas画布:课程中会把threejs虚拟相机渲染三维场景在浏览器网页上呈现的结果称为Canvas画布。// 定义相机输出画布的尺寸(单位:像素px) const width = 800; //宽度 const height = 500; //高度f.透视投影相机PerspectiveCamera:视锥体透视投影相机的四个参数fov, aspect, near, far构成一个四棱台3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上。// width和height用来设置Three.js输出的Canvas画布尺寸(像素px) const width = 800; //宽度 const height = 500; //高度 // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面 const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);PerspectiveCamera参数介绍:PerspectiveCamera( fov, aspect, near, far )参数含义默认值fov相机视锥体竖直方向视野角度50aspect相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height1near相机视锥体近裁截面相对相机距离0.1far相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向2000
查看详情点赞评论收藏浏览492023-03-10 15:05:41JS 表单弹出键盘兼容性处理
在我们日常前端开发或者工作中,经常会遇到HTML页面提交表单,弹出手机键盘出现各种各样的兼容性问题。android终端还是ios终端弹出异常等。下面总结了基础的处理弹出键盘的兼容性问题,以供参考。//判断是android终端还是ios终端 $("document").ready(function () { var m = navigator.userAgent; var isAndroid = m.indexOf('Android') > -1 || m.indexOf('Adr') > -1; //android终端 var isIos = !!m.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 var timer; if (isIos) { // ios 弹出与收起软键盘执行事件 document.body.addEventListener('focusin', () => { //软键盘弹起事件 $(".footer").css('position', 'relative'); $('.mask').css({'height':'200%','top':'-50%'}); window.addEventListener("touchmove", () => { $("input").blur(); }); }) document.body.addEventListener('focusout', () => { //软键盘关闭事件 $(".footer").css('position', 'fixed'); $('.mask').css('height','100%'); // 解決ios端用微信打开页面,收起软键盘后,底部出现空白问题 setTimeout(() => { const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0; window.scrollTo(0, Math.max(scrollHeight - 1, 0)); }, 100); }) } if (isAndroid) { // android 弹出与收起软键盘执行事件 const innerHeight = window.innerHeight; window.addEventListener('resize', () => { const newInnerHeight = window.innerHeight; if (innerHeight > newInnerHeight) { // 键盘弹出事件处理 $(".footer").hide(); } else { // 键盘收起事件处理 $(".footer").show(); } }); } });
查看详情点赞评论收藏浏览322023-03-10 13:07:43three学习路线(一)
安装three官网包引入three.js<script type="module"> // 现在浏览器支持ES6语法,自然包括import方式引入js文件 import * as THREE from './build/three.module.js'; </script>three.js三个基本概念:场景Scene、相机Camera、渲染器Renderer1.三维场景Scene你可以把三维场景Scene (opens new window)对象理解为虚拟的3D场景,用来表示模拟生活中的真实三维场景,或者说三维世界。创建3D场景对象Sceneconst scene = new THREE.Scene();2.物体形状:几何体Geometry Three.js提供了各种各样的几何体API,用来表示三维物体的几何形状{ 长方体(BoxGeomentry) 圆柱体(CylinderGeometry) 球体(SphereGeometry) 圆锥(ConeGeometry) 矩形平面(PlaneGeometry) 圆面图(CircleGeometry)}//创建一个长方体几何对象Geometryconst geometry = new THREE.BoxGeometry(100, 100, 100); 3.物体外观:材质Material如果你想定义物体的外观效果,比如颜色,就需要通过材质Material相关的API实现。threejs不同材质渲染效果不同,下面就以threejs最简单的网格基础材质MeshBasicMaterial (opens new window)为例给大家实现一个红色材质效果。{ 网格基础材质(MeshBasicMaterial) 网格漫反射材质(MeshLamberMaterial) 网格高光材质(MeshPhongMaterial) 物理材质(MeshStanderMaterial)(MeshPhysicalMaterial) 点材质(PointsMaterial) 线基础材质(LineBasicMaterial) 精灵材质(SpriteMaterial)}//创建一个材质对象Materialconst material = new THREE.MeshBasicMaterial({ color: 0xff0000,//0xff0000设置材质颜色为红色 }); 4.物体:网格模型Mesh实际生活中有各种各样的物体,在threejs中可以通过网格模型Mesh (opens new window)表示一个虚拟的物体,比如一个箱子、一个鼠标。// 两个参数分别为几何体geometry、材质materialconst mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh5.模型位置:position实际生活中,一个物体往往是有位置的,对于threejs而言也是一样的,你可以通过位置属性position定义网格模型Mesh在三维场景Scene中的位置。const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh //设置网格模型在三维空间中的位置坐标,默认是坐标原点 mesh.position.set(0,10,0);6.add()方法在threejs中你创建了一个表示物体的虚拟对象Mesh,需要通过.add()方法,把网格模型mesh添加到三维场景scene中。scene.add(mesh); 代码小结<script type="module"> // es6引入three.js import * as THREE from "../build/three.module.js"; // 创建场景 const scene = new THREE.Scene(); // 创建物体形状(几何体) const geomeyry = new THREE.BoxGeometry(100, 100, 100); // 添加物体外观(材质) const material = new THREE.MeshBasicMaterial({ color: 0xff0000, }); // 创建网格模型 把形状外观放入模型中 const mesh = new THREE.Mesh(geomeyry, material); // 设置模型所在场景(Scene)中的位置 mesh.position.set(0, 10, 0); // 把模型添加到场景(Scene)中 scene.add(mesh); </script>
查看详情点赞1评论1收藏浏览732023-03-07 15:11:28go 发送邮件功能
上一篇 go-zero 数字图形验证码功能 之后,接下来我们要开发一个发送邮件的功能。框架还是go-zero,好吧,我们开始撸!1、引包:我们用到的是这个包(github.com/jordan-wright/email)github.com/jordan-wright/email2、新建一个邮件发送的工具:新建一个utils文件加,然后创建mail.go文件直接撸代码:我用的是163邮箱,开干之前。需要在邮箱进行配置。具体步骤百度一下或者联系我沟通。package utils import ( "crypto/tls" "fmt" "net/smtp" "strings" "github.com/jordan-wright/email" ) func Email(To, subject string, body string) error { to := strings.Split(To, ",") return send(to, subject, body) } func send(to []string, subject string, body string) error { from := "这里是发件人邮箱地址,需要自己配置" nickname := "这里是名称" secret := "秘钥" host := "smtp.163.com" port := 465 isSSL := true auth := smtp.PlainAuth("", from, secret, host) e := email.NewEmail() if nickname != "" { e.From = fmt.Sprintf("%s <%s>", nickname, from) } else { e.From = from } e.To = to e.Subject = subject e.HTML = []byte(body) var err error hostAddr := fmt.Sprintf("%s:%d", host, port) if isSSL { err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host}) } else { err = e.Send(hostAddr, auth) } return err } OK,工具方法已经好了。我们开始引用:utils.Email(in.Email, "xxx", "您好,欢迎加入xxxxx!邮箱已发送,祝您使用愉快!")
查看详情点赞1评论收藏1浏览942023-03-03 16:22:48go 数字图形验证码功能
最近在开发一个项目,需要用到验证码,很久没有用到验证码的项目还不习惯;在网上参考了一些资料,简单用Go语言开发了一个数字验证码功能;用到的框架是最近比较火的一款 go-zero 微服务框架;首先,应用包,我用的是常用的包,验证码用的默认数字图形验证码;引入包:github.com/mojocn/base64Captchaetc yaml配置文件配置如下:Captcha: KeyLong: 6 ImgWidth: 240 ImgHeight: 80Config 文件验证码结构体:KeyLong int64 ImgWidth int64 ImgHeight int64 }到此,配置完成了,最后直接调用包new一个验证码// 获取验证码 func (l *GetCaptchaCodeLogic) GetCaptchaCode(in *member.GetCaptchaReq) (*member.GetCaptchaResp, error) { // 验证码 driver := base64Captcha.NewDriverDigit(int(l.svcCtx.Config.Captcha.ImgHeight), int(l.svcCtx.Config.Captcha.ImgWidth), int(l.svcCtx.Config.Captcha.KeyLong), 0.7, 80) cp := base64Captcha.NewCaptcha(driver, storeBlog) id, b64s, err := cp.Generate() fmt.Println(err) if err != nil { return &member.GetCaptchaResp{ Code: 500, Msg: "获取验证码失败", }, nil } return &member.GetCaptchaResp{ Code: 200, Msg: "获取成功", CaptchaId: id, PicPath: b64s, }, nil }用go-zero完成的简单的图形数字验证码功能就OK了。如果想要了解go-zero的api和protobuf文件,可以点击下面链接进行跳转。 go-zero微服务框架 api 案例 go-zero微服务框架 proto 案例
查看详情点赞评论收藏浏览492023-03-03 15:52:41流程引擎在Java中的使用
流程引擎是指一种用于定义、执行和管理业务流程的软件工具。在Java中,常用的流程引擎有Activiti、Camunda、jBPM等。这些流程引擎提供了一套标准的流程定义语言、流程执行引擎和流程管理工具,可以帮助开发人员快速地设计、实现和优化业务流程。以下是使用流程引擎的基本步骤:引入流程引擎库:根据具体的流程引擎选择相应的库文件,并将其引入项目中。定义流程模型:使用流程引擎提供的图形化工具或者XML文件定义业务流程模型。流程模型包括流程节点、流程变量、流程条件等。部署流程模型:将定义好的流程模型部署到流程引擎中,可以使用API接口或者管理界面实现。启动流程实例:根据流程模型创建流程实例,可以使用API接口或者管理界面实现。执行流程任务:根据流程模型执行流程任务,每个任务对应一个流程节点,可以使用API接口或者管理界面实现。处理流程事件:流程引擎支持各种事件(如流程开始、结束、节点执行等),可以通过注册事件监听器的方式进行处理。监控流程状态:流程引擎提供了流程监控工具,可以实时查看流程状态和性能指标。总之,在Java中使用流程引擎可以帮助开发人员快速实现业务流程,并提高流程的可控性和可管理性。但是需要注意,流程引擎并不是银弹,需要根据具体场景选择合适的解决方案。
查看详情点赞2评论1收藏1浏览1132023-03-02 11:44:54分布式事务控制
分布式事务是指在分布式系统中跨多个节点和多个数据库执行的事务。由于分布式事务存在网络延迟、节点故障、数据同步等问题,因此需要采用一些控制方法来保证事务的正确性和一致性。以下是一些常用的分布式事务控制方法:两阶段提交(2PC):2PC 是一种经典的分布式事务协议,通过协调器(Coordinator)和参与者(Participant)两个角色来实现分布式事务的提交和回滚。2PC 分为投票阶段和提交阶段两个阶段,其中在投票阶段,协调器向所有参与者发送提交请求,参与者返回同意或者拒绝,如果所有参与者都同意,则进入提交阶段,否则回滚事务。2PC 算法能够保证事务的一致性,但是会带来性能和可扩展性的问题。三阶段提交(3PC):3PC 是在 2PC 的基础上发展而来,通过增加准备阶段来避免了 2PC 中的两阶段问题。3PC 分为准备阶段、提交阶段和确认阶段,其中在准备阶段,协调器会向参与者发送准备请求,参与者返回准备就绪或者失败,如果所有参与者都准备就绪,则进入提交阶段,否则回滚事务。在提交阶段,协调器向所有参与者发送提交请求,参与者返回提交就绪或者失败,如果所有参与者都提交就绪,则进入确认阶段,否则回滚事务。3PC 算法相对于 2PC 可以减少一次网络通信,但是仍然存在性能和可扩展性问题。补偿事务(Compensating Transaction):补偿事务是一种更加灵活的分布式事务处理方法,它通过记录操作的逆向操作,来实现事务的回滚和恢复。当发生异常时,通过执行补偿操作来回滚事务,从而保证数据的一致性。补偿事务相对于 2PC 和 3PC 更加灵活,但是需要开发者手动实现补偿逻辑,并且可能会引入一些数据不一致性的问题。消息队列(Message Queue):消息队列是一种异步处理和解耦的分布式消息传递机制,可以用于实现分布式事务的处理。通过将需要提交的事务操作封装成消息,将消息发送到消息队列中,然后由消费者节点异步处理消息,最终完成事务操作。消息队列相对于传统的分布式事务控制方法的优点是可以解耦和提高系统的可扩展性和可靠性。但是也存在一些缺点,比如性能、可靠性、一致性和复杂性等问题。因此,在实际应用中需要根据具体的场景和需求来选择合适的分布式事务控制方法。另外,除了以上提到的控制方法,还有一些其他的分布式事务控制方法,比如 TCC(Try-Confirm-Cancel)事务、本地消息表(Local Message Table)等。这些方法都有各自的优缺点和适用场景,需要根据实际情况进行选择。总的来说,分布式事务的控制是一个比较复杂和关键的问题,需要考虑各种因素,包括性能、可靠性、一致性和复杂性等。在实际应用中需要根据具体的场景和需求来选择合适的控制方法,并且需要注意分布式事务的设计和实现,以保证事务的正确性和一致性。
查看详情点赞13评论收藏浏览572023-03-02 11:43:09