Javascript

関連コンテンツ

Vue - TypeError: Cannot read properties of null (reading 'insertBefore')

In Vue 3/Nuxt 3, one may occur the error TypeError: Cannot read properties of null (reading 'insertBefore') which has little information and is hard to solve. In the following, we summerize some tips that help you solve this error :1. Change v-if to v-show , or change all v-if , v-else to v-show. Sometimes, the error appears because there are v-if or v-if, v-else pairs.2. Change katex auto-render. The error may appear because you use katex auto-render. To solve this, you could either change katex to mathjax, or change document.body in the auto-render function to a specific area document.getElementById(Id) as follows :<script> var node = document.getElementById(Id) document.addEventListener("DOMContentLoaded", function() { renderMathInElement(node, { // customised options // • auto-render specific keys, e.g.: delimiters: [ {left: '$$', right: '$$', display: true}, {left: '$', right: '$', display: false}, {left: '\\(', right: '\\)', display: false}, {left: '\\[', right: '\\]', display: true} ], // • rendering keys, e.g.: throwOnError : false }); }); </script>If katex render all corresponding symbols in document.body, it may also influence some normal part. So you need to restrict it to a specific area.3. Change your dialog component. If you are using SSR, like Nuxt.js, the error may occur due to your dialog component in the UI library. You could either try to wrap the dialog with ClientOnly <ClientOnly> <Dialog> </Dialog> </ClientOnly>or try to use another UI library.
2024-05-05 12:19:38

npm run build error: Heap out of memory in Nuxt3

When running npm run build , an error may occur which looked like :<--- Last few GCs ---> [2656:000001DF58927940] 511573 ms: Mark-sweep 2013.9 (2091.6) -> 2012.7 (2091.4) MB, 1022.4 / 0.0 ms (average mu = 0.211, current mu = 0.009) allocation failure; scavenge might not succeed [2656:000001DF58927940] 513611 ms: Mark-sweep 2028.4 (2091.4) -> 2027.2 (2117.4) MB, 2021.5 / 0.0 ms (average mu = 0.083, current mu = 0.008) allocation failure; scavenge might not succeed <--- JS stacktrace ---> FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory 1: 00007FF60B131B7F node_api_throw_syntax_error+203775 2: 00007FF60B0B1556 v8::internal::wasm::WasmCode::safepoint_table_offset+63558 3: 00007FF60B0B28C2 v8::internal::wasm::WasmCode::safepoint_table_offset+68530 4: 00007FF60BB547F4 v8::Isolate::ReportExternalAllocationLimitReached+116 5: 00007FF60BB3FB52 v8::Isolate::Exit+674 6: 00007FF60B9C1BBC v8::internal::EmbedderStackStateScope::ExplicitScopeForTesting+124 7: 00007FF60B9BEDDB v8::internal::Heap::CollectGarbage+3963 8: 00007FF60B9D5013 v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath+2099 9: 00007FF60B9D58BD v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath+93 10: 00007FF60B9E50F3 v8::internal::Factory::NewFillerObject+851 11: 00007FF60B6D6825 v8::internal::DateCache::Weekday+1349 12: 00007FF60BBF1E81 v8::internal::SetupIsolateDelegate::SetupHeap+558193 13: 00007FF5AD7902ACTo solve this error, you could try to change your package.json as follows ://package.json "scripts": { "build": "node --max-old-space-size=8192 node_modules/nuxt/bin/nuxt.mjs build", "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" }Or you could set your nuxt.config.ts ://nuxt.config.ts export default defineNuxtConfig({ sourcemap: false })
2024-05-02 16:19:43

Vue - Go to anchor smoothly without changing url

In Vue.js, we can define an anchor by RouterLink or HTML tag <a> , while in Nuxt.js, we can additionally use NuxtLink which is similar to RouterLink .<a href="#content">My Link</a> <RouterLink to="#content">My Link</RouterLink> <NuxtLink to="#content">My Link</NuxtLink>However, on loading a page, the above ways would change the url which makes it slow to go to #content . To speed up anchor link and not change the url, there are two ways.The first way is to use pure javascript method scrollIntoView to scroll to the specified div id, which is fast and would not change url.function scrollSmoothTo(Id) { var node = document.getElementById(Id); node.scrollIntoView({ behavior: 'smooth' }); } <a @click="scrollSmoothTo('content')"> Scroll to userdiv </a> <RouterLink @click="scrollSmoothTo('content')"> Scroll to userdiv </RouterLink> <NuxtLink @click="scrollSmoothTo('content')"> Scroll to userdiv </NuxtLink> <div id="content"> example </div>Note that adding behavior: 'smooth' can add animation when scrolling. However, using this way, a could not have attribute href, i.e. <a href="#content" @click="scrollSmoothTo('content')" /> <RouterLink href="#content" @click="scrollSmoothTo('content')" /> <NuxtLink href="#content" @click="scrollSmoothTo('content')" />would not perform the click event. This is not SEO friendly.Therefore, the second way is the improvement of the first that is SEO friendly, which can smoothly go to #content without changing the url. We should use Vue's event modifiers for v-on.<a href="#content" @click.native.prevent="scrollSmoothTo('content')"> Scroll to userdiv </a> <div id="content"> example </div>This way, we could prevent the default href action when clicking and perform the scrollSmoothTo function. However, It seems that using RouterLink or NuxtLink in the same way could not prevent the default action, i.e.<RouterLink href="#content" @click.native.prevent="scrollSmoothTo('content')"> Scroll to userdiv </RouterLink> <NuxtLink href="#content" @click.native.prevent="scrollSmoothTo('content')"> Scroll to userdiv </NuxtLink>not work.
2024-04-30 16:52:12

Vue add whitespaces in a string

In Vue.js, if you simply add multiple whitespaces in a string, it eventually displays a single whitespace.//This will display a single whitespace. 'ab c'If you want to display multiple whitespaces, you could use unicode to represent whitespace.let str1 = 'ab\u00A0\u00A0\u00A0 c'; let str2 = 'ab\u0020\u0020\u0020 c'; let str3 = 'ab\u3000\u3000\u3000 c';These will output multiple whitespaces in strings.
2024-05-09 20:18:57

JSON Parse报错: Unterminated string

我在JSON parse函数中使用转义引号时,遇到了一个常见的问题。如果存在转义引号,在本例中为“test”,则会导致以下错误'SyntaxError: JSON Parse error: Unterminated string'.var information = JSON.parse('[{"-1":"24","0":"","1":"","2":"","3":"0.0000","4":"","5":"0.00","6":"0.00","7":"1.00","8":"0","9":"false","10":"false","11":[""],"12":"","13":"","14":"test\""}]');JSON Lint验证该JSON为有效的。
2024-08-14 16:28:24

什么是JavaScript中的箭头函数(arrow functions)?

什么是JavaScript中的箭头函数(arrow functions)?1. 引言箭头函数(Arrow Functions)是ES6(ECMAScript 2015)引入的一种简洁的函数定义方式。它们不仅在语法上更加简洁,还在行为上与传统的函数表达式有所不同。本文将详细介绍箭头函数的语法、特点、与普通函数的区别,以及使用场景和注意事项。2. 箭头函数的语法2.1 基本语法箭头函数使用=>符号来定义,语法形式如下:(param1, param2, ..., paramN) => { /* function body */ }如果只有一个参数,可以省略括号:param => { /* function body */ }如果函数体只有一个表达式,可以省略大括号和return关键字:(param1, param2) => param1 + param2;2.2 示例// 无参数的箭头函数 const greet = () => { console.log('Hello, World!'); }; // 一个参数的箭头函数 const square = x => x * x; // 多个参数的箭头函数 const add = (a, b) => a + b; // 调用箭头函数 greet(); // 输出: Hello, World! console.log(square(5)); // 输出: 25 console.log(add(2, 3)); // 输出: 53. 箭头函数的特点3.1 简洁的语法箭头函数的语法更为简洁,适合用于编写简短的回调函数和内联函数。减少了函数声明的样板代码,使代码更加简洁明了。3.2 没有this绑定箭头函数不会创建自己的this,它会捕获外部上下文的this值。传统函数的this值是在调用时确定的,而箭头函数的this值是在定义时确定的。function Person() { this.age = 0; setInterval(() => { this.age++; console.log(this.age); }, 1000); } const p = new Person(); // 每秒输出递增的age值在上述示例中,箭头函数内部的this指向Person实例,而不是setInterval的调用者。3.3 不能用作构造函数箭头函数不能用作构造函数,不能使用new关键字调用。如果尝试使用new调用箭头函数,会抛出错误。const Foo = () => {}; const foo = new Foo(); // TypeError: Foo is not a constructor3.4 没有arguments对象箭头函数没有arguments对象,如果需要使用参数,可以使用剩余参数语法...args。const sum = (...args) => args.reduce((acc, val) => acc + val, 0); console.log(sum(1, 2, 3, 4)); // 输出: 103.5 不能使用yield关键字箭头函数不能用作生成器函数,不能使用yield关键字。const generator = () => { yield 1; // SyntaxError: Unexpected number };4. 与普通函数的区别4.1 语法差异箭头函数的语法更加简洁,省略了function关键字,并且在只有一个参数和一个返回值表达式时,可以省略括号和大括号。4.2 this绑定普通函数的this值是在调用时确定的,而箭头函数的this值是在定义时确定的。箭头函数没有自己的this,它会捕获外部上下文的this。4.3 arguments对象普通函数有arguments对象,箭头函数没有。如果需要在箭头函数中访问参数,可以使用剩余参数语法...args。4.4 构造函数普通函数可以用作构造函数,箭头函数不能用作构造函数。4.5 生成器函数普通函数可以用作生成器函数,可以使用yield关键字。箭头函数不能用作生成器函数,不能使用yield关键字。5. 使用场景5.1 简化回调函数箭头函数非常适合用于简化回调函数的写法,特别是在处理数组方法如map、filter和reduce时。const numbers = [1, 2, 3, 4, 5]; const squares = numbers.map(n => n * n); console.log(squares); // 输出: [1, 4, 9, 16, 25]5.2 保留上下文的this在需要保留上下文this的场景中,箭头函数非常有用,比如在事件处理程序和定时器回调中。class Timer { constructor() { this.seconds = 0; setInterval(() => { this.seconds++; console.log(this.seconds); }, 1000); } } const timer = new Timer(); // 每秒输出递增的seconds值5.3 简化内联函数箭头函数可以简化内联函数的写法,使代码更加简洁和易读。const add = (a, b) => a + b; console.log(add(2, 3)); // 输出: 56. 注意事项6.1 避免滥用虽然箭头函数语法简洁,但在一些场景中使用普通函数可能更合适,特别是在需要动态绑定this或使用arguments对象的情况下。6.2 可读性在一些复杂的逻辑中,使用箭头函数可能会影响代码的可读性。在这种情况下,可以考虑使用普通函数来提高代码的清晰度。6.3 兼容性箭头函数是ES6引入的特性,如果需要兼容旧版本的JavaScript环境,可能需要使用Babel等工具进行转译。7. 总结箭头函数(Arrow Functions)是ES6引入的一种简洁的函数定义方式。它们不仅在语法上更加简洁,还在行为上与传统的函数表达式有所不同,特别是在this绑定和arguments对象的处理上。箭头函数非常适合用于简化回调函数、保留上下文this以及内联函数的写法。然而,在一些场景中,使用普通函数可能更合适。通过理解箭头函数的特点和使用场景,开发者可以更好地编写简洁、易读和高效的JavaScript代码。原文链接:https://blog.csdn.net/JHXL_/article/details/140141821
2024-08-29 21:38:33

Vue 如何在 style 标签里使用变量

在Vue项目开发中,有时候我们需要在style标签中使用我们所定义的JS变量来编写CSS。根据官方文档,我们可以使用v-bind来实现这个目的选项式API:<template> <div class="text">hello</div> </template> <script> export default { data() { return { color: 'red' } } } </script> <style> .text { color: v-bind(color); } </style>组合式API:<script setup> import { ref } from 'vue' const theme = ref({ color: 'red', }) </script> <template> <p>hello</p> </template> <style scoped> p { color: v-bind('theme.color'); } </style>还有一个问题,如果我们的变量是数字,但是我们想要设置像素px怎么办?以下以组合式API为例(选项式API方法大同小异),提供两种解决方案。一种是使用 computed 计算属性改变它<script setup> import { computed } from 'vue'; const props = defineProps({ size: Number }); const sizePx = computed(() => `${props.size}px`) </script> <template> <p>hello</p> </template> <style scoped> p { font-size: v-bind(sizePx); } </style>还有一种方式是使用 CSS 计算属性calc<script setup> defineProps({ size: Number }); </script> <template> <p>hello</p> </template> <style scoped> p { font-size: calc(1px * v-bind(size)); } </style>那么如何在代码中使用style属性呢?也很简单,根据官方文档,在style标签中加上module,然后就能通过$style来使用style中的CSS属性。<template> <p :class="$style.red">This should be red</p> </template> <style module> .red { color: red; } </style>还可以给style的module attribute设置不同的名字,从而调用不同style标签中的属性<template> <p :class="classes1.red">This should be red</p> </template> <style module="classes1"> .red { color: red; } </style> <style module="classes2"> .red { color: green; } </style>如果想要在<script setup>中使用,可以使用 useCssModuleimport { useCssModule } from 'vue'; const classes1 = useCssModule('classes1'); const classes2 = useCssModule('classes2');
2024-08-28 21:30:05

JS实现数组去重的七种方法

JS数组去重的方式例:将下面数组去除重复元素(以多种数据类型为例)const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]1.利用Set()+Array.from()Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的。Array.from() 方法:对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。const result = Array.from(new Set(arr)) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]注意:以上去方式对NaN和undefined类型去重也是有效的,是因为NaN和undefined都可以被存储在Set中, NaN之间被视为相同的值(尽管在js中:NaN !== NaN)。2.利用两层循环+数组的splice方法通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时NaN !== NaN。function removeDuplicate(arr) { let len = arr.length for (let i = 0; i < len; i++) { for (let j = i + 1; j < len; j++) { if (arr[i] === arr[j]) { arr.splice(j, 1) len-- // 减少循环次数提高性能 j-- // 保证j的值自加后不变 } } } return arr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]3.利用数组的indexOf方法新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。此方法也无法对NaN去重。indexOf() 方法:返回调用它的String对象中第一次出现的指定值的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。function removeDuplicate(arr) { const newArr = [] arr.forEach(item => { if (newArr.indexOf(item) === -1) { newArr.push(item) } }) return newArr // 返回一个新数组 } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]4.利用数组的includes方法此方法逻辑与indexOf方法去重异曲同工,只是用includes方法来判断是否包含重复元素。includes()方法:用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。function removeDuplicate(arr) { const newArr = [] arr.forEach(item => { if (!newArr.includes(item)) { newArr.push(item) } }) return newArr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]注意:为什么includes能够检测到数组中包含NaN,其涉及到includes底层的实现。如下图为includes实现的部分代码,在进行判断是否包含某元素时会调用sameValueZero方法进行比较,如果为NaN,则会使用isNaN()进行转化。具体实现可参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes简单测试includes()对NaN的判断:const testArr = [1, 'a', NaN] console.log(testArr.includes(NaN)) // true5.利用数组的filter()+indexOf()filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。filter() 方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。function removeDuplicate(arr) { return arr.filter((item, index) => { return arr.indexOf(item) === index }) } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined ]注意:这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。测试如下:const testArr = [1, 'a', NaN] console.log(testArr.indexOf(NaN)) // -16.利用Map()Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合has()和set()方法判断键是否重复。Map 对象:用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。function removeDuplicate(arr) { const map = new Map() const newArr = [] arr.forEach(item => { if (!map.has(item)) { // has()用于判断map是否包为item的属性值 map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true newArr.push(item) } }) return newArr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]注意:使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。7.利用对象其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。function removeDuplicate(arr) { const newArr = [] const obj = {} arr.forEach(item => { if (!obj[item]) { newArr.push(item) obj[item] = true } }) return newArr } const result = removeDuplicate(arr) console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]原文链接:https://blog.csdn.net/qq_52732369/article/details/121877897
2024-08-28 23:24:49

JS高级使用3.0——JS中获取页面的高度、距离顶部的距离

创作场景   记录闭包的博客中有一个节流函数的实际用法和这个知识点相关,创作过程中发现这个知识点涉及到的还有很多,在此记录一下相关的所有知识点并进行比较。阅读前提   此博客适用于所有人群,不仅有基础的用法,同时也对多种实现方式进行比较,本文将围绕一个例子进行讲解,并对涉及到的所有知识点进行穿插,最后进行总结。提前了解的知识点1. 页面可视化高度(clientHeight)   页面可视化高度指的是你当前页面能看到内容的高度,这个高度是可以动态变化的,比如你打开了F12调试器,那么你的可视化高度就会变化,如果你将浏览器最大化,那么你的可视化高度也会变化,但这并不代表你实际页面的高度,可能你的页面高度会远远超过页面可视化高度。代码实现:document.body.clientHeight2. 滚动条高度(scrollHeight)   滚动条高度就是当你的页面高度超过了页面可视化高度,比如body的高度是900,你的页面高度是800,那么滚动条就会产生,一般来说,滚动条高度是比你的页面高度要大16px,可能不同设备会不一样。代码实现:document.body.scrollHeight统计距离页面顶部的距离参考:https://blog.csdn.net/mouday/article/details/125444003 // 滚动方向枚举值 const DIRECTION_ENUM = { DOWN: "down", UP: "up", }; // 距离顶部或底部的阈值,一般滚动条高度是要比页面高度大的,阈值指的就是大的这一点儿 const threshold = 20; // 记录前一个滚动位置 let beforeScrollTop = 0; function handleScroll() { // 距顶部 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset || window.scrollY; // 可视区高度 var clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 滚动条总高度 var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; // 打印数值,console.table是控制台打印表格的写法,同时也有 // console.error和console.warn,对应警告和错误 // 一般使用的就是console.info console.table([ { label: "距顶部", value: scrollTop, }, { label: "可视区高度", value: clientHeight, }, { label: "滚动条总高度", value: scrollHeight, }, { label: "距顶部 + 可视区高度", value: scrollTop + clientHeight, }, ]); // 确定滚动方向 let direction = DIRECTION_ENUM.DOWN; if (beforeScrollTop > scrollTop) { direction = DIRECTION_ENUM.UP; } // 通过滚动方向判断是触底还是触顶 if (direction == DIRECTION_ENUM.DOWN) { // 滚动触底 if (scrollTop + clientHeight + threshold >= scrollHeight) { console.log("滚动触底"); } } else { // 滚动到顶部 if (scrollTop <= threshold) { console.log("滚动到顶部"); } } beforeScrollTop = scrollTop; } window.addEventListener('scroll', handleScroll)window、document、documentElement的区别window是当前页面的顶级对象,其中包含了很多属性和方法,是一个BOM对象,可进行浏览器的交互。document是window对象的子元素,它可以理解为一个DOM对象,其中有很多方法和属性,主要是在页面元素中进行交互。documentElement是document的子元素,注意,这是一个只读对象,也就是说它只能读取元素的属性,不能对元素进行操作。一般他就是你本页面的HTML元素。这里一定要注意一下,如果你的页面是在一个iframe中,那你获取的一定是你iframe中的所有元素,并不是你最大页面的对象。一般在实际开发中都有头部导航栏,而子页面中也会嵌套子页面,那么获取最外部的HTML元素可以用parent对象,一层一层循环,因为最外部的iframe肯定是有一个ID的,这是我在开发中遇到的一个小问题,分享一下。// 第一个参数是当前的iframe对象,第二个是parent对象 // 调用时parentNode不用传入 function getFrameTop(frame, parentNode) { if (frame.attr('id') !== "iframeContent") { if (parentNode) { frame = parentNode.parent.$("iframe") } else { frame = parent.$("iframe") } getFrameTop(frame, parent) } else { topIframe = frame return frame } }解读获取距离页面顶部距离的四种方式 // 距顶部 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset || window.scrollY;  这四种拆分下来就是在两个对象上进行操作的,一个是window,一个是document,而之所以这么写完全是为了兼容性,尤其是pageYOffset方法,这是一个过时方法,但是在某些IE就只能识别这个,如果你的产品不需要兼容,那其中一个就够用了。   解读一下原理:   我的div高度是900,页面可视化高度是818,而距离顶部的距离(scrollTop)是98,这其实就是滚动条的高度减去可视区高度算出来的,而这个高度指的是你的div最顶部距离和你可视化页面的顶部距离,如果是计算底部的距离,那加上页面可视化距离即可。如何使用代码滚动页面(四种方式)1. scroll()方法滚动窗口至文档中的特定位置。window.scroll(x, y) x和y就是你需要滚动的绝对位置坐标window.scroll(options) options是一个对象,包含x、y坐标,同时也有滚动的方式window.scroll({ top: 100, left: 100, behavior: "smooth", });   上面这是一种标准用法,当然一般我们不这么写,直接用第一种方式滚动即可。2. scrollBy()方法在窗口中按指定的偏移量滚动文档(比如你只是想在这个基础上向下滚动100px)scrollBy(x-coord, y-coord)scrollBy(options)x-coord 是你想滚动的水平像素值。y-coord 是你想滚动的垂直像素值。options   包含以下参数的字典top   指定沿 Y 轴滚动窗口或元素的像素数。left   指定沿 X 轴滚动窗口或元素的像素数。behavior   指定滚动是否应该平滑(smooth)、瞬时运动到该位置(instant)、或者让浏览器选择(auto,默认)。window.scrollBy({ top: 100, left: 100, behavior: "smooth", });   这个方法和scroll区别在于,这里的x和y指的是偏移量,而不是绝对位置。3. scrollTo()   这个和scroll方法是一样的,个人比较喜欢这种方式,因为可读性比较高,不容易出错,使用标准写法可以随意在x和y上进行随意滚动,因为对象上参数可选。// 设置滚动行为改为平滑的滚动 window.scrollTo({ top: 1000, behavior: "smooth" });4. document.documentElement.scrollTop = 0(非标准写法)   上面说过documentElement是一个只读属性,官方上也是这么说的,但是经过实验发现这种方式也可以用来操作页面的滚动,但不建议这么使用,也不知道会存在什么bug。使用节流函数优化关于节流函数是什么,这个博客中有说明节流函数(闭包中的使用) function throttle(func, wait){ let previous = 0; return function() { var now = Date.now() var context = this // ES5写法:var args = []; args.push.apply(null, arguments) var args = [...arguments] // ES6数组解构知识点:复制数组 // 如果当前时间减去上一次执行时间大于我们执行函数的时间间隔再执行 if(now - previous > wait){ func.apply(context, args); // 闭包,记录本次执行时间戳 // 这么写就是不用将上次执行的时间作为参数传给函数了 // 就算多次调用闭包不会消失,上一次执行时间不会消失,这就是闭包的常用方式 previous = now; } } } // 滚动方向枚举值 const DIRECTION_ENUM = { DOWN: "down", UP: "up", }; // 距离顶部或底部的阈值,一般滚动条高度是要比页面高度大的,阈值指的就是大的这一点儿 const threshold = 20; // 记录前一个滚动位置 let beforeScrollTop = 0; function handleScroll() { // 距顶部 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset || window.scrollY; // 可视区高度 var clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 滚动条总高度 var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; // 打印数值 console.table([ { label: "距顶部", value: scrollTop, }, { label: "可视区高度", value: clientHeight, }, { label: "滚动条总高度", value: scrollHeight, }, { label: "距顶部 + 可视区高度", value: scrollTop + clientHeight, }, ]); // 确定滚动方向 let direction = DIRECTION_ENUM.DOWN; if (beforeScrollTop > scrollTop) { direction = DIRECTION_ENUM.UP; } // 通过滚动方向判断是触底还是触顶 if (direction == DIRECTION_ENUM.DOWN) { // 滚动触底 if (scrollTop + clientHeight + threshold >= scrollHeight) { console.log("滚动触底"); } } else { // 滚动到顶部 if (scrollTop <= threshold) { console.log("滚动到顶部"); } } beforeScrollTop = scrollTop; } // window.addEventListener('scroll', handleScroll) window.addEventListener('scroll', throttle(handleScroll, 200)) 这里只是一个例子,请注意,如果想要绝对精度,也就是当滚动条快速滑动的时候也要监听到,那就将延迟设置为0-50内。总结获取距离顶部的距离document.documentElement.scrollTopdocument.body.scrollTopwindow.pageYOffsetwindow.scrollY可视区高度document.documentElement.clientHeightdocument.body.clientHeight滚动条总高度document.documentElement.scrollHeightdocument.body.scrollHeight滚动页面scroll()scrollTo()scrollBy()document.documentElement.scrollY = 100原文链接:https://blog.csdn.net/weixin_48588897/article/details/138413621
2024-08-28 00:15:22

JS 数组中的 filter 方法

1、定义filter()创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。2、语法array.filter(function(currentValue,index,arr), thisValue);3、参数说明返回4、用法filter() 方法用于把Array中的某些元素过滤掉,然后返回剩下的未被过滤掉的元素。5、注意事项1、filter() 不会对空数组进行检测;2、filter() 不会改变原始数组。6、使用实例1.返回数组array中所有元素都大于等于14的元素、返回等于14、返回大于某个值和小于某个值的元素的元素。const array = [14, 17, 18, 32, 33, 16, 40]; const newArr = array.filter(num => num > 14) console.log(newArr);//打印 [17,18,32,33,16,40] // 查找某个值------------------------- const array = [14, 17, 18, 32, 33, 16, 40]; const newArr = array.filter(num => num == 14) console.log(newArr);//打印 [14] //返回大于某个值和小于某个值的元素 const array = [14, 17, 18, 32, 33, 16, 40]; const newArr = array.filter(num => num > 14 && num < 33) console.log(newArr);//打印 [17, 18, 32, 16]2.数组去重操作:对数组array中所有相同的元素进行去重复操作。const array = [2, 2, 'a', 'a', true, true, 15, 17] const newArr = array.filter((item, i, arr) => { return arr.indexOf(item) === i }) console.log(newArr);//打印 [2, 'a', true, 15, 17] //------------------------------------------------------------------------- const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 7, 9,] const newArr = array.filter((item, i, arr) => { return arr.indexOf(item) === i }) console.log(newArr);// 打印 [1, 2, 3, 4, 5, 6, 7, 8, 9]3、数组中保留奇数或者偶数。//保留偶数---------------------------------------- const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const newArr = array.filter((item, i, arr) => { return item % 2 === 0 }) console.log(newArr);// 打印 [2, 4, 6, 8, 10] //保留奇数---------------------------------------- const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const newArr = array.filter((item, i, arr) => { return item % 2 !== 0 }) console.log(newArr);// 打印 [1, 3, 5, 7, 9]4、去掉数组中的假值,比如:空字符串、undefined、null、0、false。const array = [ { id: 3 }, { id: 4 }, { id: null }, { id: undefined }, { id: '' }, { id: 0 }, { id: false } ] const newArr = array.filter(({ id }) => id) console.log(newArr);// 打印 [{ "id": 3 },{ "id": 4 }] //------------------------------------------------------------------- const array = [undefined, null, 3, 5, 'a', false, 0] const newArr = array.filter(item => item) console.log(newArr);// 打印 [3, 5, 'a']5、把对象数组array中的某个属性值取出来存到数组newArr中。const array = [ { name: "a", type: "letter" }, { name: '1', type: "digital" }, { name: 'c', type: "letter" }, { name: '2', type: "digital" }, ]; const newArr = array.filter((item, i, arr) => { return item.type === "letter" }) console.log(newArr); // 打印 [{ "name": "a", "type": "letter" }, { "name": "c", "type":"letter" }]6、filter结合find方法,实现两个数组的补集的解决方法,oldArr的元素newArr中都有,在newArr中去掉所有的oldArr。find() 方法返回数组中满足提供的测试函数的第一个元素的值。这里有四个元素,那么就会返回两个数组元素相等的值,这里取反就返回不相等的值, 不取反的时候因为30的元素不符合,所以不返回30的值。const array = [32, 4, 11, 55, 46, 99, 104, 54, 16, 33, 78, 43, 40] const oldArr = [32, 33, 16, 40, 30] function myfunction() { const result = array.filter(item1 => { //此处取反去掉,将变换元素状态 return !oldArr.find(item2 => { return item1 === item2 }) }) return result } const newArr = myfunction() console.log(newArr); // 取反打印 [4, 11, 55, 46, 99, 104, 54, 78, 43] // 不取反打印 [32, 16, 33, 40] 此处30的元素不符合,所以不返回30的值原文链接:https://blog.csdn.net/a15220216758/article/details/124993673
2024-08-29 16:20:14