Open tanabalu opened 2 years ago
哈哈哈,开通留言板啦
六种断点方式
发现了有趣的断点方式:DOM断点。在控制台 Elements 面板,选中元素后右键,找到 Break On 菜单,在它的耳机菜单中看到有子节点树变更断点、属性变更断点以及元素被移除的断点。
然后在查资料时,才发现是我才疏学浅了,除了普通断点和DOM断点外,还有条件断点、异常断点、URL断点和Event Listener断点。详情见:https://www.shouxicto.com/article/2930.html
【编码】一个很有趣的代码校验的写法,这里的 switch(false)
很有灵性啊!这种写法也值得被推广到更多的校验场景里。
function validate(password: string): string {
let error = '';
switch (false) {
case password.length >= 8:
error = '密码长度不能小于8位';
break;
case password.length <= 16:
error = '密码长度不能大于16位';
break;
case /[0-9]/.test(password):
error = '密码中必须含有数字';
break;
case /[a-z]/.test(password):
error = '密码中必须含有小写字母';
break;
case /[A-Z]/.test(password):
error = '密码中必须含有大写字母';
break;
// ……
}
return error;
}
【写作】拟人化、加上形容词
+ 落叶它静静地铺满了整条街
- 落叶铺满了整条街
【写作】在写论点时要附带有论据
+ 作为朋友,你一直是我追随学习的人,想起高中有段时间想做第一个早读的人,但无论多早你都先坐在了教室。看着你跟哥哥低头交谈……
- 作为朋友,你一直都是我追随学习的人。看看你跟哥哥低头交谈……
Markdown diff 语法的用法:
```diff
+ new
- delete
【阅读】在阅读论述型内容时,不仅要关注他的论点,同时,论据也非常重要。
从论据与论点的关系中,去发现作者的逻辑组织方式,培养自己更好的逻辑思维。假想一下,当有一天你对他人提起这个论点时却找不到论据,这样的论点在你这里是站不住脚的。
另外,终有一天,当你怀疑你自己的时候,这些论据也能帮助你重回正轨。
【Debug】“AuthProvider”表示值,但在此处用作类型。是否指“类型 AuthProvider”
问题在于:该文件是 ts 后缀的文件,无法解析 dom ,需要将文件后缀改为 tsx ,然后警告就消除了。
【编码】使用svg连线
【杂记】本来想在快报的头栏里加入更多个人的元素的,为此我还思虑良久。但在刚刚,一个念头点醒了我,快报是一个公共的透出信息的平台,大家去看它是为了获取更多的信息,增长见识,绝大多数人对编者是个什么样的人不感兴趣。那么,加入个人元素的方向本身就存在着错误。
作为一个技术周刊,真正的着力点应该在于让读者获得更多内容,更加专业,更加平易近人才是真正需要做的事情。
macos系统升级后,git会失效,需要执行 xcode-select --install
命令来重装 git。
【编码】前端异常捕获方案:
window.onerror
捕获语法异常setTimeout
、setInterval
等异步方法,用同步的写法包裹 try
来捕获异步函数中发生的错误window.addEventListener (‘unhandledrejection’,・・・);
捕获未处理的异步 reject
window.addEventListener (‘error’, …)
捕获资源异常fetch
, XMLHttpRequest
来捕获接口状态React
的 ErrorBoundary
异常捕获组件昨晚做了一个梦,梦见我在一座看似是一辆车的诊所里,诊所里的有一张桌子,桌子旁边坐着一个男医生,站着一个女医生。 我说:“我来拿药。” 男医生指了指女医生说道:“上次是她给你看的病,不知道你要拿什么药。不过我看你没什么病,就是嗓子有点问题。” 我深以为然,下了车,离开了。
【编码】发现一个性能优化的技巧:在产品功能上线前几天(7天)先推送资源至客户端(让大多数用户都已经读取过资源),这样基于客户端缓存,产品上线时,可以有效的降低资源加载对首屏展示的影响。
【Debug】我在使用 Antd 的 Tree 组件时,它需要在有限的宽度里展示树型结构,当树型结构横向超出宽度时,需要展示滚动条。
当前的问题是,确实可以出现滚动条,但是只有在文案被极致压缩的情况下才会出现滚动条,文案挤压变形根本无法阅读,体验极差。
分析:从截图看,问题主要出在文案换行了,那么如果不允许文案换行,这个问题就解决了。
解决方案:给文案增加 white-space: nowrap;
属性后,文案不会换行,而 white-space
属性是可以被继承的,所以无需再文案上加上该属性,只要在该组件外围加上该 css 配置即可。
增加后,文案就不会被挤压变形了:
【编码】Typescript 读取 enum 枚举的 key 值和 value 值
// 假设我一个枚举
enum ENUM_TYPE {
ALL = 'all',
SOME = 'some',
LITTLE = 'little'
}
// 获取枚举的 value
type IValue = `${ENUM_TYPE}` // 'all' | 'some' | 'little'
// 获取枚举的 key
type IKey = keyof typeof ENUM_TYPE // 'ALL' | 'SOME' | 'LITTLE'
【编码】正则贪婪匹配与懒惰匹配
贪婪匹配:【.*】,默认即为贪婪匹配 懒惰匹配:【.*?】,后面加上?表示懒惰匹配
【编码】下面这句代码放到控制台,将会执行alert(1)
这段代码,弹出弹窗。
"".constructor.constructor("alert(1)")()
基本原理:首先字符串的constructor是一个字符串的构造函数,而这个构造函数本身就是一个函数,它的constructor构造函数就是 function 的构造函数,所以"".constructor.constructor()
的作用相当于new Function()
。很有意思的代码!!
【编码】将searchURL转换为对象
const params = Object.fromEntries(
new URLSearchParams(window.location.search)
)
// URL: example.com/path?foo=bar&name=futurestudio&num=1
// { foo: 'bar', name: 'futurestudio', num: '1' }
【编码】原来书签栏里也可以执行自定义脚本。参考 Cubox 书签栏快速收藏插件的代码,直接要将这段代码放到书签栏里,点击就可以实现自动收藏文章的功能。
<a href="
javascript:
var url = location.href;
var title = document.title;
var desc = '';
if (document.getSelection) {
desc = document.getSelection();
};
if (desc.toString().length === 0) {
let descTag = document.querySelector('[name=description]');
desc = descTag ? descTag.getAttribute('content') : '';
};
if (desc.length > 500) {
desc = desc.slice(0, 500) + '...';
};
void(
open(
'https://cubox.pro/my/tool/collection?url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&description=' + encodeURIComponent(desc) + '&groupId=' + '&tags=' + '&starTarget=false' + '&editable=false',
'cubox',
'toolbar=no,
resizable=no,
location=no,
menubar=no,
width=300,
height=100',
)
);" class="SettingApps_quickCollect__yrNRf"><span class="SettingApps_quickCollectIcon__qTcZP">★</span>快速收藏</a>
提取你项目中的所有中文字:
const fs = require('fs');
const path = require('path');
// 定义你的项目路径
const projectPath = './src';
// 定义输出文件路径
const outputPath = './output.txt';
// 定义正则表达式来匹配单行、多行注释
const commentRegex = /\/\/.*|\/\*[\s\S]*?\*\//g;
// 定义正则表达式来匹配包含至少一个中文字符的字符串,同时保留其中的英文和数字
const chineseWithEnglishRegex = /[一-龥]+[一-龥a-zA-Z0-9,.!?()();;::]*|[一-龥a-zA-Z0-9,.!?()();;::]*[一-龥]+/g;
// 定义你希望跳过的文件夹数组
const ignoreDirs = ['.umi', '.umi-production', 'assets', 'services'];
// 将找到的中文句子写入到文件
const output = fs.createWriteStream(outputPath, { encoding: 'utf-8' });
// 搜索指定文件类型
const fileTypes = ['.js', '.jsx', '.ts', '.tsx'];
function findChineseText(filePath) {
const content = fs.readFileSync(filePath, { encoding: 'utf-8' });
// 移除注释
const contentWithoutComments = content.replace(commentRegex, '');
// 匹配中文和可能的英文单词
const matches = contentWithoutComments.match(chineseWithEnglishRegex);
if (matches) {
output.write(`File: ${filePath}\n${matches.join('\n')}\n\n`);
}
}
function walkDirectory(directory) {
// 获取目录名,用于检查是否应该跳过
const dirName = path.basename(directory);
if (ignoreDirs.includes(dirName)) {
return;
}
fs.readdirSync(directory, { withFileTypes: true }).forEach((dirent) => {
const resPath = path.resolve(directory, dirent.name);
if (dirent.isDirectory()) {
walkDirectory(resPath);
} else if (fileTypes.includes(path.extname(dirent.name).toLowerCase())) {
findChineseText(resPath);
}
});
}
walkDirectory(projectPath);
output.end(() => {
console.log(`完成!所有含中文字符的短语(保留其中的英文单词)已经被写入到 ${outputPath}`);
});
爬取网页文章并且将其转换为 Markdown 格式:
pip install requests beautifulsoup4 html2text
spider.py
文件:import requests
from bs4 import BeautifulSoup
import html2text
# 定义获取文章内容的函数
def fetch_article_content(url):
try:
# 发送 HTTP GET 请求获取网页内容
response = requests.get(url)
response.raise_for_status() # 如果请求失败,将抛出异常
# 解析 HTML 内容
soup = BeautifulSoup(response.text, 'html.parser')
# 找到类名为 'main-container' 的元素
main_container = soup.find(class_='main-container')
if main_container:
# 使用 html2text 将 HTML 转换为 Markdown
h2t = html2text.HTML2Text()
h2t.ignore_links = False # 将链接转换成 Markdown 链接格式
h2t.ignore_images = False # 将图片转换成 Markdown 图片格式
h2t.ignore_tables = False # 将表格转换成 Markdown 表格格式
return h2t.handle(str(main_container))
else:
return "Article content not found."
except requests.HTTPError as e:
return f"HTTP Error: {e}"
except Exception as e:
return f"An error occurred: {e}"
# 目标网页的 URL
url_to_scrape = 'https://hub.baai.ac.cn/view/33417'
# 调用函数并打印结果
markdown_content = fetch_article_content(url_to_scrape)
print(markdown_content)
spider.py
python spider.py
新知识:接口的入参类型、接口的出参类型跟前端渲染对象并不是同一个实体,它们只是长得很相似而已。
以前总有一种执念,总想着最大限度的复用类型定义,就会在 Typescript 中大量的使用 extends
关键字来对原来的类型做增删改查操作,以满足新的类型设计需求。而这个实现方案在处理接口出参数据和前端渲染数据时又是常用,比如:
接口入参:
interface Params {
id?: string;
name?: string;
pageSize: number;
pageNum: number;
}
接口出参
interface Response {
id: string;
name: string;
description: string;
gmtCreate: string;
gmtModify: strring;
}
前端渲染
interface View {
name: string;
description: string;
gmtCreate: string;
gmtModify: strring;
}
按照过去的习惯,我总会想先构造一个简单类型,然后用 extends 扩展出另外两种类型。但是实际上,它们并不是同一个类型,只是长得有点像而已,过于执着使用基础类型来扩展反而会把代码弄成一团乱麻,要摒弃这个执念!
问题:
在对话场景中,下拉新的聊天记录时,如何保障新拉取到的聊天内容后,页面扔停留在下拉前的原始位置?
附加:如果新拉取的聊天记录里有图片或者其他异步渲染的模块,如何保障?
https://hbuecx.com/post/message/?
温故而知新。