REC
首页
文章分类
源码资源
技术教程
程序软件
文创娱乐
玄学修炼
关于我们
其他页面
网站统计
友情链接
用户留言
高清壁纸
关于易航
热门文章
Joe再续前缘主题 - 本站同款
易航网址导航系统 – 功能强大,轻量易用
Js自动播放HTML音乐(不受浏览器限制,无需先与浏览器交互,无需对浏览器进行修改)
网易云官方歌曲解析接口
JsonDb-PHP轻量级文件数据库系统
标签搜索
PHP
Web前端
网站源码
PHP源码
Typecho
课程资料
武术内功
HTML源码
Windows程序
Web
Android软件
Typecho插件
Joe主题
国漫
网络协议
MySQL
Python
NodeJs
Windows
小说
发布
登录
注册
找到
40
篇与
Web前端
相关的结果
- 第 3 页
2024-11-12
CSS 让 height 高度属性完美支持 auto 过渡动画
众所周知,有些属性是不支持过渡动画的,比如高度 auto div{ height: 0; transition: 1s } .wrap:hover div{ height: auto }效果如下 图片 要实现过渡效果,之前提供过一个 grid 布局方式,原理是利用 grid 的尺寸单位 1fr 支持过渡的特性 一、calc-size 函数 现在要实现 auto 的过渡效果,需要用到一个全新的 calc-size 函数 图片 看到这个函数,是不是和 calc 比较类似?没错,这是一个可以将一些关键词转换成具体尺寸的函数。 回到上面这个例子,只需要将高度改成 calc-size(auto) ,如下 div{ height: 0; transition: 1s } .wrap:hover div{ height: calc-size(auto) }现在就有过渡效果了(Chrome 129+ 或者 Chrome 127+开启实验属性) 图片 其实除了 auto ,还支持其他尺寸关键词,比如 height: calc-size(min-content) height: calc-size(max-content) height: calc-size(fit-content)也支持混合计算,如下 height: calc-size(auto + 10px) height: calc-size(max-content - 10px)二、interpolate-size 属性 前面的例子,为了兼容之前的浏览器,还必须保留 height: auto 的写法 div{ height: 0; transition: 1s } .wrap:hover div{ height: auto; height: calc-size(auto) }如果是已经存在的项目,可能会有很多地方需要都要改成这种写法,有一定的侵入性。 为此,浏览器还提供了一个 interpolate-size 属性,这个属性可以设置插值计算的规则,有两个关键词 interpolate-size: numeric-only;/*默认值*/ interpolate-size: allow-keywords;其中第一个 numeric-only ,表示仅限数值,也就是只有真实的数值才会有过渡效果(目前浏览器的默认效果),第二个 allow-keywords 表示允许所有关键词,当然包括 auto 属性 有了这个属性,要做的事情就更简单了,只需要在全局 :root 加上这个属性 :root{ interpolate-size: allow-keywords; } div{ height: 0; transition: 1s } .wrap:hover div{ height: auto; }这样就全局生效了,无需在每个地方就加上 calc-size(auto) ,是不是非常方便呢? 图片 三、也支持 detail 展开过渡 大家可能都知道,detail 配合 summary 可以实现展开折叠效果 <div class="con"> <details name="a"> <summary>分组A</summary> <p>这是第一个分组 name="a"</p> </details> <details name="a"> <summary>欢迎</summary> <p>最近 details元素新增了一个name属性</p> </details> <details name="a"> <summary>关注</summary> <p>别看这只是一个普普通通的属性,这可是带来了一个全新的模式,一起了解一下吧</p> </details> </div>效果如下 图片 当然默认展开折叠是没有过渡效果的 利用 calc-size 或者 interpolate-size 也可以很轻松的实现过渡动画,关键实现如下 :root { interpolate-size: allow-keywords; } ::details-content{ content-visibility: visible; height: 0; transition: .3s; overflow: hidden; } details[open]::details-content{ height: auto; }这样就有过渡效果了,非常丝滑 图片 这是一段通用代码,可以用在任何地方 四、现在其实可以用起来了 虽然说兼容性很差(Chrome 129+),但这是一个渐进增强属性,不会影响现有功能,也无需修改已有结构,只需要全局增加这样一行就行了 :root { interpolate-size: allow-keywords; }这样能支持的浏览器自然就会有过渡动画了,完全不用担心是否兼容。 总结一下,其实就两点 calc-size 可以将非数值类型的单位转换成支持过渡的尺寸单位,包括 auto interpolate-size 可以从全局范围允许任意关键词支持过渡
技术教程
# Web前端
易航
1年前
0
186
2
2024-11-09
Three.js 可滑动魔方源码
图片 html 部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>魔方</title> <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="mofang"> <div class="mofang__background"></div> <div class="mofang__game"></div> <div class="mofang__texts"> <h1 class="text text--title"> <span>魔方</span> </h1> <div class="text text--note"> 双击即可开始 </div> <div class="text text--timer"> 0:00 </div> <div class="text text--complete"> <span>完成!</span> </div> <div class="text text--best-time"> <icon trophy></icon> <span>最佳时间!</span> </div> </div> <div class="mofang__prefs"> <range name="flip" title="翻转类型" list="迅速的 ,平滑的,弹起"></range> <range name="scramble" title="扰乱长度" list="20,25,30"></range> <range name="fov" title="摄像机角度" list="摄影,透视的"></range> <range name="theme" title="配色方案" list="灰色,浅蓝色,浅黄色,脏黄色,淡青色"></range> </div> <div class="mofang__stats"> <div class="stats" name="total-solves"> <i>全部解决:</i><b>-</b> </div> <div class="stats" name="best-time"> <i>最佳时间:</i><b>-</b> </div> <div class="stats" name="worst-time"> <i>最差时间:</i><b>-</b> </div> <div class="stats" name="average-5"> <i>平均值 5:</i><b>-</b> </div> <div class="stats" name="average-12"> <i>平均值 12:</i><b>-</b> </div> <div class="stats" name="average-25"> <i>平均值 25:</i><b>-</b> </div> </div> <div class="mofang__buttons"> <button class="btn btn--bl btn--stats"> <icon trophy></icon> </button> <button class="btn btn--bl btn--prefs"> <icon settings></icon> </button> <button class="btn btn--bl btn--back"> <icon back></icon> </button> <a href="#" class="btn btn--br btn--pwa"> </button> </div> </div> <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.min.js'></script> <script src="js/common.js"></script> </body> </html>完整项目地址 隐藏内容,请前往内页查看详情
免费资源
源码资源
# Web前端
易航
1年前
3
64
0
2024-11-08
JavaScript逆向系列 09-Js Hook
0x00 前言 缘起是我前两天看了一篇逆向文章,里面用到了一段hook脚本,在这之前我是不理解hook是什么东西,看了那段脚本后我突然就悟了,遂写下这篇文章分享一下个人心得。 注:本文不会太深入js hook。 0x01 Intro 首先我需要明确一点,我们在浏览网站时,由于js是在客户端上执行的,所以我们有最高的权限,这也就方便我们去对js进行一些操作,例如hook。我个人认为的js hook技术就是我们去修改函数或方法内部的实现过程,也就是重写方法,以便我们去利用它去实现一些我们想要的效果。 接下来我会通过一个小demo简单演示一下js hook脚本该如何编写。 0x02 Demo console.log = function (message) { alert(message); }效果: 图片 console是内置对象,不需要实例化即可使用,所以我们可以直接修改它的方法,例如log方法。代码中我将log方法的内部实现过程改成了将传入的参数进行alert。不过这个脚本其实还是有缺陷的,一般情况下我们改写某个函数或方法的内部实现过程后,我们还需要将它原本的功能实现了,否则可能会造成意想不到的后果。 改写后的脚本: var test = console.log; console.log = function (message) { alert(message); test(message); }将log方法赋值给test,代码执行完我们想要的效果后就完成它本来的工作,也就是最后执行test函数,相当于执行了log方法。 效果: 图片 图片 现在就是一个比较完善的hook脚本了。 0x03 个人脚本分享 我在看完上文提到的那篇逆向文后,立马就去写了我的第一个hook脚本(注:后文会发全部代码以及讲解如何使用): 图片 就拿上期自动化加解密的案例进行测试: 图片 图片 通过控制台输出的堆栈信息直接定位到解密位置。 我先说明一下我为什么要重写JSON.parse和JSON.stringify这两个方法,可能有看过我的逆向文章或者看过其他js逆向文章的朋友们会发现,这两个方法在加解密操作中出场率极高。一般情况下密文解密后开发可能会选择将json转为object,那么就会用到JSON.parse,JSON.stringify可能就会在加密时用到。 代码的话通过上文的讲解读者应该能看懂大部分,我觉得唯一需要讲的就是new Error().stack,Error是构造函数,需要实例化才能用,以下是MDN介绍的stack方法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error/stack 图片 简单来说就是它可以直接输出调用的堆栈,也就是上文演示的效果: 图片 不过我这里还需要提的一点的就是这个方法需要不断的实例化调用,如果只实例化一个对象然后反复调用这个实例的stack方法,只会输出实例化时的那个调用堆栈,例如: 图片 图片 0x04 如何使用js hook脚本 当我们要hook时,一般来说这个脚本一定要是文档中第一个加载执行的js,这样就能拿到函数或方法的控制权,所以我们就需要插件进行帮助。 这里我推荐大家使用油猴插件,直接在google应用商店搜篡改猴即可: 图片 安装后固定到chrome后点击添加新脚本: 图片 将代码写到注释部分即可: 图片 另外我需要提一点,我这个hook脚本一定要是文档中第一个加载的js,所以要修改一下脚本的运行时期。保存代码后点击设置: 图片 图片 修改运行时期即可,document-start是我们需要设置的: 图片 具体为什么可查看油猴中文文档(https://www.cnblogs.com/grubber/p/12560522.html): 图片 hook_JSON: // ==UserScript== // @name hook_JSON // @namespace http://tampermonkey.net/ // @version 2024-10-29 // @description try to take over the world! // @author 0xsdeo // @match http://*/* // @icon https://www.google.com/s2/favicons?sz=64&domain=csdn.net // @grant none // ==/UserScript== (function() { 'use strict'; var json_p = JSON.parse; JSON.parse = function(str){ console.log(str); console.log(new Error().stack); console.log("-----------------------------------------------------------------------------------------------------") return json_p(str); } var json_s = JSON.stringify; JSON.stringify = function(obj){ console.log(obj); console.log(new Error().stack); console.log("-----------------------------------------------------------------------------------------------------") return json_s(obj); } })();最后提一点,脚本需要指定一下要执行脚本的网站,匹配到的网站才会执行脚本,也是在设置里改: 图片 这里我设置的*,意为所有网站都执行该脚本。
技术教程
# Web前端
易航
1年前
0
50
0
2024-11-04
20个超好看又开源的落地页/首页模板(附源码)
分享 20 个超好看的落地页/首页模板。 模板预览 nefa 图片 trippi 图片 tailwind-landing-page-template 图片 vivid-landing-template 图片 shadcn-landing-page 图片 open-react-template 图片 skilline-landing-page 图片 template-landing-page 图片 SaaS-Boilerplate 图片 nextly-template 图片 fresh 图片 landing 图片 nutritrack 图片 mylandingpage 图片 React-Landing-Page-Template 图片 landy-react-template 图片 landing-template-nextui 图片 next-saas-starter 图片 daisyui-nextjs-landing-page 图片 react-landing-page-template-2021 图片 源码下载 隐藏内容,请前往内页查看详情
免费资源
源码资源
# 网站源码
# Web前端
# HTML源码
易航
1年前
6
287
0
2024-10-30
HTML+CSS实现太极八卦加载动画
动画效果预览 HTML部分 <html> <head> <meta charset="utf-8"> <title>太极八卦</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="./55-太极八卦.css"> </head> <body> <div class="table"> <div class="table-cell"> <svg width="470px" height="470px" viewBox="0 0 470 470" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1"> <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="25" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.63 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetInner1"></feOffset> <feGaussianBlur stdDeviation="25" in="shadowOffsetInner1" result="shadowBlurInner1"> </feGaussianBlur> <feComposite in="shadowBlurInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite> <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.7 0" in="shadowInnerInner1" type="matrix" result="shadowMatrixInner1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> <feMergeNode in="shadowMatrixInner1"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-2"> <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="22.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.7 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-3"> <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-4"> <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="25" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.63 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-5"> <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="15" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.23 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-6"> <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="25" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.63 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-7"> <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> <feGaussianBlur stdDeviation="15" in="shadowOffsetOuter1" result="shadowBlurOuter1"> </feGaussianBlur> <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.23 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix> <feMerge> <feMergeNode in="shadowMatrixOuter1"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter> </defs> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Artboard-1"> <ellipse id="Oval-1" fill="#485d51" cx="237" cy="228" rx="111" ry="111"></ellipse> <circle id="Oval" fill="#0E7CFE" filter="url(#filter-1)" cx="237" cy="228" r="39"></circle> <path d="M237.737045,228.155741 C206.543902,228.155741 181.166785,253.532859 181.166785,284.726749 C181.166785,312.174294 200.823516,335.102165 226.795386,340.215844 C169.77682,334.873529 125,286.749357 125,228.358226 C125,166.403809 175.404556,116 237.357479,116 C241.130723,116 242.479377,116.122537 242.479377,116.122537 C271.062631,118.710011 293.460007,142.732496 293.460007,171.989704 C293.460007,227.891241 237.737045,228.155741 237.737045,228.155741 L237.737045,228.155741 Z" id="Path1" fill="#FFFFFF" filter="url(#filter-2)"></path> <g id="Group" transform="translate(264.500000, 228.500000) scale(-1, -1) translate(-264.500000, -228.500000) translate(180.000000, 116.000000)" filter="url(#filter-3)" fill="#000000"> <path d="M112.737045,112.155741 C81.5439023,112.155741 56.1667848,137.532859 56.1667848,168.726749 C56.1667848,196.174294 75.8235156,219.102165 101.795386,224.215844 C44.7768195,218.873529 0,170.749357 0,112.358226 C0,50.403809 50.4045562,-2.84217094e-14 112.357479,-2.84217094e-14 C116.130723,-2.84217094e-14 117.479377,0.122537018 117.479377,0.122537018 C146.062631,2.71001075 168.460007,26.7324965 168.460007,55.9897038 C168.460007,111.891241 112.737045,112.155741 112.737045,112.155741 L112.737045,112.155741 Z" id="Path2"></path> </g> <circle id="Oval-3" fill="#000000" filter="url(#filter-4)" cx="164" cy="156" r="39"></circle> <circle id="Oval-3-2" fill="#000000" filter="url(#filter-5)" cx="187" cy="83" r="16"></circle> <circle id="Oval-4" fill="#FFFFFF" filter="url(#filter-6)" cx="309" cy="300" r="39"></circle> <circle id="Oval-4-2" fill="#FFFFFF" filter="url(#filter-7)" cx="286" cy="373" r="16"></circle> </g> </g> </svg> </div> </div> <a class="box-item" href="https://codepen.io/LOverride/" target="_blank"> </a> </body> </html>CSS部分 隐藏内容,请前往内页查看详情
技术教程
# Web前端
易航
1年前
2
63
1
2024-10-30
2024 年最前沿的 5 大 CSS 功能 | 高级 CSS
CSS作为Web设计的基石,一直在不断进化,以应对现代设计的挑战。2024年,CSS引入了一系列令人惊叹的新特性,大大拓展了Web设计的可能性。本文将深入探讨五个最具革命性的CSS新特性,这些特性正在彻底改变前端开发的方式。 1.CSS容器查询(Container Queries) 容器查询允许基于元素的容器大小而非视口来设置样式,这对响应式设计是一个巨大的突破。 示例: 图片 这种方法使得组件级别的响应式设计成为可能,大大提高了代码的可维护性和模块化程度。 2.CSS子网格(Subgrid) 子网格是CSS网格布局的扩展,允许网格项继承其父元素的网格定义。这对于复杂的嵌套布局特别有用。 在 subgrid 出现之前,我一直在为嵌套网格而苦苦挣扎,这往往会导致 CSS 变得复杂冗长。 子网格允许子元素与父网格无缝对齐,从而简化了这一过程。 示例: 图片 子网格简化了复杂布局的创建,减少了冗余代码,提高了网格设计的一致性。 3.@property规则定义的CSS自定义属性 @property规则允许定义具有类型检查、初始值和继承特性的自定义属性(CSS变量)。 示例: 图片 这种方法增强了CSS变量的能力,提供了更多对其行为的控制,确保了它们的正确使用。 4.CSS嵌套 CSS嵌套允许以反映HTML结构的方式嵌套CSS选择器,提高了CSS的可读性和可维护性。 示例: .card { background: white; & .title { color: black; } & .content { font-size: 0.9em; } }这种特性使CSS更加组织化,简化了样式的编写和维护过程,特别是在大型项目中。 5.CSS滚动链接动画 滚动链接动画允许创建响应用户滚动位置的动画,为网站增添了新的交互维度。 示例: @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } #box { animation: linear fade-in; animation-timeline: scroll(); }这种动画可以使网站更加动态和吸引人,增强用户体验。 结语 2024年的这些CSS新特性为创建更具响应性、组织性和吸引力的Web设计提供了强大的工具。通过在工作流程中incorporate这些前沿特性,开发者可以显著提升项目质量并简化开发过程。 这些新特性不仅提高了开发效率,还开启了Web设计的新可能性。例如,容器查询使得真正的组件级响应式设计成为现实,而滚动链接动画则为用户交互带来了新的维度。随着这些特性的广泛采用,Web开发的未来将更加灵活、高效且富有创意。 掌握这些新特性,将有助于开发者在不断演进的Web开发世界中保持领先地位。通过实践和探索这些新工具,开发者可以创造出更加动态、响应迅速且视觉吸引的Web体验。
技术教程
# Web前端
易航
1年前
0
86
0
2024-10-19
JavaScript代码的简洁之道
1、条件判断赋值布尔值 不推荐: if (a === 'a') { b = true; } else { b = false; }推荐: b = a === 'a';通过直接将条件判断的结果赋值给变量,可以简化代码,提高可读性。 2、使用三元运算符 不推荐: if (a > b) { c = a; } else { c = b; }推荐: c = a > b ? a : b;三元运算符是处理简单条件赋值的一种更简洁的方式。 3、合并重复的代码块 不推荐: function processValue(value) { if (value > 10) { console.log('Value is greater than 10'); // 其他操作 } else { console.log('Value is 10 or less'); // 其他操作 } // 重复的代码块 performAdditionalOperations(); }推荐: function processValue(value) { console.log(value > 10 ? 'Value is greater than 10' : 'Value is 10 or less'); performAdditionalOperations(); }将重复的代码块提取到条件判断之外,可以减少不必要的重复,提高代码的可读性。 4、使用数组方法代替循环 不推荐: let sum = 0; for (let i = 0; i < numbers.length; i++) { sum += numbers[i]; }推荐: let sum = numbers.reduce((acc, num) => acc + num, 0);使用数组的内置方法(如 reduce 、map 、filter 等)可以简化代码,同时提高性能,因为这些方法通常被高度优化。 5、使用模板字符串 不推荐: let greeting = 'Hello, ' + name + '!';推荐: let greeting = `Hello, ${name}!`;模板字符串(使用反引号 ` )允许嵌入变量和表达式,使字符串拼接更加简洁和直观。 6、避免不必要的全局变量 不推荐: let counter = 0; function incrementCounter() { counter++; }推荐: function createCounter() { let counter = 0; return { increment: function() { counter++; }, getValue: function() { return counter; } }; } let counterInstance = createCounter(); counterInstance.increment();通过模块或闭包来封装变量,可以避免全局命名空间的污染,提高代码的封装性和可维护性。 7、使用解构赋值 不推荐: let data = { name: 'Alice', age: 25 }; let name = data.name; let age = data.age;推荐: let { name, age } = data;解构赋值可以方便地提取对象中的属性,使代码更加简洁。 8、提前终止循环 不推荐: for (let i = 0; i < array.length; i++) { if (array[i] === target) { found = true; break; } }推荐: let found = array.includes(target);如果不需要在循环中执行其他操作,直接使用数组的内置方法(如 includes )可以提前终止搜索,提高性能。 9、使用箭头函数 不推荐: function add(a, b) { return a + b; }推荐: const add = (a, b) => a + b;箭头函数不仅语法简洁,还能避免 this 绑定的问题,使代码更加清晰。 10、避免使用 with 语句 不推荐: with (obj) { console.log(name); console.log(age); }推荐: console.log(obj.name); console.log(obj.age);with 语句会使代码难以优化,并可能导致性能问题,因此应避免使用。 11、使用 let 和 const 代替 var 不推荐: var count = 0;推荐: let count = 0; // 对于需要重新赋值的变量 const MAX_COUNT = 100; // 对于不需要重新赋值的常量let 和 const 提供了块级作用域(block scope),避免了 var 带来的函数级作用域(function scope)问题,使得代码更加清晰和可预测。 12、避免内联样式和脚本 不推荐: <div style="color: red;">This is red text</div> <script> console.log('Inline script'); </script>推荐: <link rel="stylesheet" href="styles.css"> <script src="script.js"></script>在HTML中,尽量将样式和脚本分离到外部文件,这有助于代码的组织和维护,同时也可能提高加载性能。 13、使用对象字面量进行属性赋值 不推荐: let obj = new Object(); obj.name = 'Alice'; obj.age = 25;推荐: let obj = { name: 'Alice', age: 25 };对象字面量语法更加简洁,易于阅读。 14、使用短路逻辑 不推荐: if (condition1) { doSomething(); } else if (!condition1 && condition2) { doSomethingElse(); }推荐: if (condition1) { doSomething(); } else if (condition2) { // 这里的!condition1已经被短路逻辑隐含 doSomethingElse(); }在第二个条件中,由于 else if 已经隐含了 !condition1 ,因此可以省略这部分判断,提高代码的可读性。不过,要注意这种优化仅在逻辑上确实可行时才进行。 15、避免不必要的计算 不推荐: for (let i = 0; i < array.length; i++) { // 每次循环都计算array.length console.log(array[i]); }推荐: for (let i = 0, len = array.length; i < len; i++) { console.log(array[i]); }将数组长度存储在一个变量中,避免在每次循环迭代时都重新计算它,这可以提高性能,尤其是在处理大型数组时。 16、使用 Object.assign 进行浅拷贝 不推荐: let newObj = {}; for (let key in oldObj) { if (oldObj.hasOwnProperty(key)) { newObj[key] = oldObj[key]; } }推荐: let newObj = Object.assign({}, oldObj);Object.assign 提供了一种更简洁和高效的方法来创建对象的浅拷贝。 17、使用默认参数和剩余参数 不推荐: function add(a, b) { b = b || 0; return a + b; } function sum() { let args = Array.prototype.slice.call(arguments); return args.reduce((acc, num) => acc + num, 0); }推荐: function add(a, b = 0) { return a + b; } function sum(...args) { return args.reduce((acc, num) => acc + num, 0); }默认参数和剩余参数是ES6中引入的语法糖,它们使得函数定义更加清晰和灵活。 18、避免魔法数字 不推荐: function calculateDiscount(price, discountRate) { return price * (1 - discountRate / 100); } // 调用时 let finalPrice = calculateDiscount(100, 20);推荐: const DISCOUNT_RATE_PERCENTAGE = 100; function calculateDiscount(price, discountRate) { return price * (1 - discountRate / DISCOUNT_RATE_PERCENTAGE); } // 或者使用命名参数 function calculateDiscount(price, discountPercentage) { return price * (1 - discountPercentage / DISCOUNT_RATE_PERCENTAGE); } // 调用时 let finalPrice = calculateDiscount(100, 20);通过定义常量或使用命名参数,可以避免在代码中使用难以理解的魔法数字,提高代码的可读性。 这些优化技巧可以帮助你编写出更加简洁、高效和可维护的JavaScript代码。记住,优化是一个持续的过程,随着你对语言和框架的深入理解,你会找到更多适合自己的优化方法。 我们继续深入讨论JavaScript代码优化的其他策略和最佳实践。 19、使用模板字符串 不推荐: let greeting = 'Hello, ' + name + '!';推荐: let greeting = `Hello, ${name}!`;模板字符串(Template Literals)允许你嵌入变量和表达式,使字符串拼接更加直观和易读。 20、使用解构赋值 不推荐: function getPersonInfo() { return { firstName: 'John', lastName: 'Doe' }; } let info = getPersonInfo(); let firstName = info.firstName; let lastName = info.lastName;推荐: function getPersonInfo() { return { firstName: 'John', lastName: 'Doe' }; } let { firstName, lastName } = getPersonInfo();解构赋值(Destructuring Assignment)允许你从数组或对象中提取数据,并将其赋值给不同的变量,使代码更加简洁。 21、使用箭头函数 不推荐: function add(a, b) { return a + b; } let numbers = [1, 2, 3]; let doubled = numbers.map(function(number) { return number * 2; });推荐: const add = (a, b) => a + b; let numbers = [1, 2, 3]; let doubled = numbers.map(number => number * 2);箭头函数(Arrow Functions)提供了更简洁的函数定义方式,并且没有自己的 this 绑定,这有助于避免在回调函数中常见的 this 问题。 22、使用 Promise 和 async/await 处理异步代码 不推荐: function fetchData(url, callback) { // 假设这里有一个异步的fetch操作 setTimeout(() => { callback(null, 'data'); }, 1000); } fetchData('some-url', function(err, data) { if (err) { console.error(err); } else { console.log(data); } });推荐: function fetchData(url) { return new Promise((resolve, reject) => { // 假设这里有一个异步的fetch操作 setTimeout(() => { resolve('data'); }, 1000); }); } // 使用Promise fetchData('some-url').then(data => { console.log(data); }).catch(err => { console.error(err); }); // 或者使用async/await async function getData() { try { let data = await fetchData('some-url'); console.log(data); } catch (err) { console.error(err); } } getData();Promise 和 async/await 提供了更优雅和强大的方式来处理异步代码,避免了回调地狱(Callback Hell)的问题。 23、使用 try...catch 进行错误处理 不推荐: if (someCondition) { // 可能会抛出错误的代码 } else { console.error('An error occurred'); }推荐: try { // 可能会抛出错误的代码 } catch (error) { console.error('An error occurred:', error); }try...catch 语句允许你捕获并处理在代码执行过程中抛出的错误,从而避免程序崩溃并提供更好的用户体验。 24、使用 Map 和 Set 不推荐: let obj = {}; let keys = ['a', 'b', 'c']; keys.forEach(key => { obj[key] = true; });推荐: let set = new Set(['a', 'b', 'c']);Map 和 Set 是ES6中引入的新的数据结构,它们提供了比传统对象更强大和灵活的功能,例如保持插入顺序和检测元素是否存在的时间复杂度更低。 25、避免全局变量污染 不推荐: let globalVar = 'This is a global variable';推荐: (function() { let localVar = 'This is a local variable'; // 你的代码逻辑 })();或者使用 let 和 const 在块级作用域内定义变量,以及使用模块系统(如ES6模块或CommonJS模块)来封装代码。 我们可继续探讨JavaScript代码优化的其他高级策略和最佳实践。以下是一些额外的建议: 26、使用 WeakMap 和 WeakSet WeakMap 和 WeakSet 是ES6中引入的两种新的集合类型,它们的主要特点是“弱引用”。这意味着它们不会阻止垃圾回收器回收其键(或成员)所引用的对象。这对于存储大量临时数据而不担心内存泄漏的情况非常有用。 示例: let obj = {}; let weakMap = new WeakMap(); weakMap.set(obj, 'some value'); // 当没有其他引用指向 `obj` 时,它可以被垃圾回收器回收27、使用 Symbol 类型 Symbol 是ES6中引入的一种新的原始数据类型,它表示唯一的标识符。使用 Symbol 可以避免属性名的冲突,并且可以作为对象的唯一键。 示例: let sym = Symbol('description'); let obj = {}; obj[sym] = 'value'; console.log(obj[sym]); // 输出: value28、优化循环 减少循环内的计算:将可以在循环外部计算的表达式移到外部。 使用 for...of 代替 for...in:当遍历数组时,for...of 通常比 for...in 更快,因为 for...in 还会遍历数组原型链上的属性。 使用 Array.prototype.every 、Array.prototype.some 、Array.prototype.find 等数组方法:这些方法提供了更简洁的语法,并且在某些情况下可能比传统的 for 循环更高效。 29、避免内存泄漏 清理定时器:确保在组件或页面销毁时清理所有的定时器(如 setInterval 和 setTimeout )。 取消事件监听:在不再需要时取消事件监听器。 避免全局变量:全局变量会一直存在于内存中,直到页面被关闭。尽量使用局部变量或模块作用域变量。 30、使用现代JavaScript框架和库的最佳实践 React: 使用纯函数组件和React Hooks来简化状态管理。 避免不必要的重新渲染,通过使用 React.memo 、useCallback 和 useMemo 等优化技术。 优化数据获取,使用React Query或Apollo Client等库来管理异步数据。 Vue: 使用计算属性和侦听器来优化响应式数据的处理。 避免在模板中进行复杂的计算,而是将它们放在计算属性或方法中。 使用Vuex或Pinia等状态管理库来管理全局状态。
技术教程
# Web前端
易航
1年前
0
48
0
2024-10-17
打呼噜的圣诞老人(可作为网页互动壁纸)
效果演示 打呼噜的圣诞老人图片 源代码 隐藏内容,请前往内页查看详情
源码资源
# Web前端
易航
1年前
2
81
3
2024-09-23
Js如何禁止用户调试你的网站页面?
定时器 + debugger 当你打开调试面板的时候,代码里的 debugger 断点会进行执行,阻塞你的代码执行 当使用 定时器 + debugger 会让调试者一直跳不出断点,从而起到禁止调试代码的作用 图片 图片 破解方法 + 应对方法 但是这种方式是能破解的 方法一:Activate breakpoints 图片 但是如果这样的话,那么调试者无意是饮鸩止渴,因为你都把调试关了,那你还怎么调试呢? 方法二:Add logpoint 图片 对于这个方式的话,其实也好解决,只需要通过打包工具代码压缩,把代码都放在一行即可 图片 图片
技术教程
# Web前端
易航
1年前
0
164
1
上一页
1
2
3
4
5
下一页