javascript 杂七杂八
约 784 字大约 3 分钟
2024-12-27
1. 输入法和JS Enter回车提交冲突
<template>
<Input v-model="textarea" class="my-input" rows="4" resize="none" type="textarea" placeholder="请输入对话内容" @keydown.enter.native="keyDown" @input="handleInput"></Input>
</template>
<script setup lang="ts">
const isMac = window.navigator.userAgent.toLowerCase().indexOf('mac') !== -1;
function keyDown(e) {
e.preventDefault();
// mac cmd + enter
// window ctrl + enter
if (isMac) {
if (e.metaKey && e.keyCode === 13) {
textarea.value += '\n';
} else if (e.keyCode === 13) {
sendMessage();
}
} else {
if (e.ctrlKey && e.keyCode === 13) {
textarea.value += '\n';
} else if (e.keyCode === 13) {
sendMessage();
}
}
}
</script>2. 前端 pdf 相关
2.1. html2pdf.js 生成 pdf
tip: 如果生成 pdf,宽度有问题,可以给外层 div 一个固定宽度
function handleDownload() {
if (downloadLoading.value) {
Message.warning('正在下载中,请稍等...');
return;
}
gioClick('下载');
downloadLoading.value = true;
printPdf(
document.getElementById('main-report'), //
'面试押题',
options => {
downloadLoading.value = false;
if (options?.success) Message.success('下载成功');
else Message.error(options?.message || '下载失败');
}
);
}
function printPdf(element, filename, callback) {
if (!element) {
callback({success: false, message: 'Dom 加载失败...'});
return;
}
const rect = element.getBoundingClientRect();
const width = rect.width || 700;
const html2pdf = require('html2pdf.js');
const pdfPromise = html2pdf()
.from(element)
.set({
filename: `${filename}.pdf`,
html2canvas: {useCORS: true, scale: 2, width: width + 100},
jsPDF: {
orientation: 'portrait'
}
})
.save();
const timeoutPromise = new Promise(
(_, reject) => setTimeout(() => reject(new Error('下载超时')), 10000) // 10秒超时
);
Promise.race([pdfPromise, timeoutPromise])
.then(() => {
callback({success: true});
})
.catch(error => {
callback({success: false, message: error.message || '下载失败'});
});
}2.2. html2pdf.js 隐藏div
在 div 上增加属性 data-html2canvas-ignore="true"
3. Array 操作
3.1. 删除数组中指定位置的项
在 JavaScript 中,有多种方法可以。以下是一些常见的方法:
- 使用
splice方法(直接修改原数组):
const array = [1, 2, 3, 4, 5];
const index = 2; // 要删除的索引
array.splice(index, 1);
console.log(array); // 输出: [1, 2, 4, 5]- 使用
filter方法(不改变原数组):
const array = [1, 2, 3, 4, 5];
const index = 2;
const newArray = array.filter((_, i) => i !== index);
console.log(newArray); // 输出: [1, 2, 4, 5]- 使用
slice方法(不改变原数组):
const array = [1, 2, 3, 4, 5];
const index = 2;
const newArray = array.slice(0, index).concat(array.slice(index + 1));
console.log(newArray); // 输出: [1, 2, 4, 5]- 使用
delete操作符(会留下undefined):
const array = [1, 2, 3, 4, 5];
const index = 2;
delete array[index];
console.log(array); // 输出: [1, 2, undefined, 4, 5]- 使用
pop或shift方法(仅适用于删除首尾元素):
const array = [1, 2, 3, 4, 5];
array.pop(); // 删除最后一个元素
console.log(array); // 输出: [1, 2, 3, 4]
const array2 = [1, 2, 3, 4, 5];
array2.shift(); // 删除第一个元素
console.log(array2); // 输出: [2, 3, 4, 5]选择方法时,请根据具体需求和对原数组的影响来决定。
4. 阻止事件冒泡
设置 capture: true 可以让你的事件监听器更早地响应点击,这在构建复杂交互或事件拦截系统中非常有用。
默认是在冒泡阶段触发 element.addEventListener('click', handler);
显式在捕获阶段触发 element.addEventListener('click', handler, { capture: true });
/**
* 阻止事件冒泡,并执行 callback 代码
* @param callback
*/
export function stopPropagation(callback: () => void) {
const doms = [
document.querySelector('.process-out'), //
document.querySelector('.buttons-out'),
];
console.log(`🌧🌧🌧 [lock dom]`, doms);
doms.forEach(dom => {
if (dom) {
dom.addEventListener(
'click',
e => {
e.stopPropagation();
e.preventDefault();
callback();
},
{capture: true} // 用于指定事件监听器应该在 捕获阶段 而不是默认的 冒泡阶段 执行。
);
}
});
}