阅读视图
Step - Invert
小红书一面:长达一个小时的拷打😭
为了不碰Word,程序员必学docxtemplater
深入解析:基于 React 与 Konva.js 实现高级图片编辑功能(附源码解读)
面试之道——手写call、apply和bind
tauri2项目动态添加 Sidecar可行性方案(运行时配置)
从浏览器进程层面理解事件循环
2025 年应该怎样初始化 Angular 项目
一文解决Babel 插件
【开源软件推荐】 so-novel,一个超强的聚合式小说下载工具
📚 前言:网文阅读的困境与解法
你是否曾遇到这样的困扰:想看最新连载小说,要么被迫付费,要么忍受广告横飞的笔趣阁,要么被限制在特定平台的APP中?
虽然市面上已有不少阅读方案,但总有些难以满足的需求:有人嫌弃界面设计太丑,有人吐槽功能不够完善,还有人厌倦了被特定平台限制。在这种情况下,高度可定制化的阅读体验成为了许多书友的终极追求。
今天要介绍的"So Novel"正是为解决这些痛点而生的利器。它能够将全网流行小说(包括连载中和已完本的)一键下载为主流电子书格式,让你可以在任何喜爱的设备上实现真正的离线阅读体验。
🎯 谁适合使用So Novel?
- 想 免费(白嫖)看正版网文 ,又追求 极致阅读体验 的资深书友
- 习惯用手机阅读的iOS用户(由于无法使用"阅读"APP,可通过So Novel下载后导入Apple Books)
- 喜欢在电脑或大屏设备上阅读的Windows、macOS、Linux用户
- 钟爱专业电子书阅读器的发烧友
- 讨厌在线阅读依赖性,习惯将书籍存储在本地的"囤书党"
- 经常处于无网络环境需要离线阅读的通勤党
- 追求"开箱即用",不想折腾复杂配置的普通用户
✨ So Novel 介绍
So Novel是一款交互式小说下载器,真正做到了跨平台、无门槛使用:
- 🖥️ 跨系统支持:windows、maacos、linux皆可使用
- 📦 开箱即用:下载解压后即可使用,无需任何额外配置
- 🔍 多源聚合:内置多个书源,支持聚合搜索,无需手动切换
- 🚀 极速下载:特别优化无限流书源的下载速度
- 📑 多格式支持:可导出EPUB、TXT、HTML(支持翻页)、PDF等格式
- 📚 批量下载:同时下载多部作品,效率翻倍
- 🔄 簡繁转换:内置简繁互转功能,满足不同阅读习惯
如何下载
在 so-novel 官方 Github Releases 下载对应操作系统版本即可:
注:如果访问不到Github或者下载很慢,这里同时也提供给百度网盘的下载链接:
链接: pan.baidu.com/s/1EfH5_nMT…
提取码: xfdm
我这里是 macos intel芯片,下载 sonovel-macos_x64.tar.gz
就可以,M系列芯片的下载 arm64
版本的
安装使用
下载后将压缩包解压
直接将当前目录拖到 终端
里去(windows
版本的解压后有个 exe
文件,直接双击就可以打开)
然后输入如下命令后,按回车
bash ./run-macos.sh
您可能会遇到这样一个无法验证开发者的警告信息,不用管它,点击取消:
点击 系统设置
,找到 隐私与安全性
找到安全性,并改为 APP Store和被认可的开发者
点击仍然允许
再次回到终端,执行上次的命令回车即可打开。
接下来就是按提示输入序号,按回车就行了
需要聚合搜索,输入 q ,按回车,输入书名,按回车:
输入下载序号,按回车:
输入1 下载全本
下载完成后,会自动合并为 epub 格式
合并成功后的 epub
文件位于软件目录下的 downloads
文件夹
导入喜欢的阅读软件,开始享受阅读的乐趣吧!
闲着周末写了一个react vue3双版本的右键菜单插件
JavaScript执行栈和执行上下文
变量声明需谨慎!!!💣这几种声明变量的方式(var、let、const)还有作用域,绝不能含糊!
React 中的 Immutable
redux中为什么要Immutable
《JavaScript语言精粹》读书笔记之第3章:对象Object
小飞悟申明:小编的笔记只针对强者!!!
一、对象字面量 Object Literals
属性名可以是包括空字符串在内的任何字符串。在对象字面量中,如果属性名是一个合法的JavaScript标识符且不是保留字,则并不强制要求用引号括住属性名。所以用引号括住"first-name"是必需的,但是否括住first_name则是可选的。逗号用来分隔多个“名/值”对。
- 合法标识符 :
- 如果属性名是合法的JavaScript标识符且不是保留字,可以不加引号。
- 例如:
const person = {
firstName: 'John',
lastName: 'Doe'
};
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
- 非法标识符 :
- 如果属性名包含特殊字符、空格或不是合法标识符,必须加引号。
- 例如
const person = {
"first-name": 'John',
"last name": 'Doe'
};
二、检索 Retrieval
要检索对象里包含的值,可以采用在[ ]后缀中括住一个字符串表达式的方式。如果字符串表达式是一个字符串字面量,而且它是一个合法的JavaScript标识符且不是保留字,那么也可以用.表示法代替。优先考虑使用.表示法,因为它更紧凑且可读性更好。
stooge["first-name"] // "Jerome"
flight.departure.IATA // "SYD"
运算符可以用来填充默认值:
var middle = stooge["middle-name"] || "(none)";
var status = flight.status || "unknown";
尝试从undefined的成员属性中取值将会导致TypeError异常。这时可以通过&&运算符来避免错误。
flight.equipment // undefined
flight.equipment.model // throw "TypeError"
flight.equipment && flight.equipment.model // undefined
三、引用 Reference
对象通过引用来传递。它们永远不会被复制:
理解对象引用
在JavaScript中,对象是通过引用来传递的,这意味着当将一个对象赋值给另一个变量时,两个变量实际上指向同一个对象。以下是对代码的详细解释:
- 对象引用 :
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
- x 和 stooge 指向同一个对象,因此修改 x 的属性也会影响 stooge 。
- nick 的值为 'Curly' ,因为 x 和 stooge 是同一个对象的引用。
- 多个对象引用 :
var a = {}, b = {}, c = {};
- a 、 b 和 c 分别引用不同的空对象。
- 同一对象引用 :
a = b = c = {};
- a 、 b 和 c 现在都引用同一个空对象。
四、原型 Prototype(简单介绍,后续会细讲)
每个对象都连接到一个原型对象,并且它可以从中继承属性。所有通过对象字面量创建的对象都连接到Object.prototype,它是JavaScript中的标配对象。 原型连接只有在检索值的时候才被用到。如果我们尝试去获取对象的某个属性值,但该对象没有此属性名,那么JavaScript会试着从原型对象中获取属性值。如果那个原型对象也没有该属性,那么再从它的原型中寻找,依此类推,直到该过程最后到达终点Object.prototype。如果想要的属性完全不存在于原型链中,那么结果就是undefined值。这个过程称为委托。
- 这里仅是定义,后续会详细讲
刚开始有点难理解很正常,建议先看看blog.csdn.net/flyingpig20…
五、反射 Refelection
- 用typeof操作符来确定属性类型很有帮助。
typeof flight.number // 'number'
typeof flight.status // 'string'
typeof flight.arrival // 'object'
typeof flight.manifest // 'undefined'
- 在JavaScript中,原型链上的属性(如 toString 和 constructor )可能会产生值,但这些值通常是函数,可能并非我们需要的。以下是两种处理这些不需要的属性的方法:
typeof flight.toString // 'function'
typeof flight.constructor // 'function'
-
检查并丢弃函数值 :
- 在程序中检查属性值是否为函数,如果是则丢弃。
- 适用于需要动态获取对象信息且仅关注数据的场景。
-
使用 hasOwnProperty 方法 :
- hasOwnProperty 方法用于检查对象是否拥有独有的属性(不检查原型链)。
- 示例:
flight.hasOwnProperty ('number'); // true flight.hasOwnProperty ('constructor'); // false
- 适用于需要区分对象自身属性和继承属性的场景。 通过这两种方法,可以更精确地处理对象属性,避免不必要的函数值干扰。
六、枚举Enumeration
for in
语句的总结
for in
语句用于遍历对象的所有属性名,包括原型链中的属性。为了过滤掉不需要的属性,可以使用 hasOwnProperty
方法或 typeof
来排除函数。
示例 1:过滤函数属性
var name;
for (name in another_stooge) {
if (typeof another_stooge[name] !== 'function') {
document.writeln(name + ': ' + another_stooge[name]);
}
}
示例 2:按特定顺序遍历属性
var i;
var properties = ['first-name', 'middle-name', 'last-name', 'profession'];
for (i = 0; i < properties.length; i += 1) {
document.writeln(properties[i] + ': ' + another_stooge[properties[i]]);
}
总结:for in
语句遍历对象属性时,属性顺序不确定。如果需要特定顺序,可以使用数组存储属性名,并通过 for
循环遍历。
七、删除Delte
删除对象属性的总结
delete
运算符用于删除对象的属性,但它不会影响原型链中的属性。如果删除的对象属性存在于原型链中,删除后原型链中的属性会“透现”出来。
示例
const stooge = {
nickname: 'Curly'
};
const another_stooge = Object.create(stooge);
another_stooge.nickname = 'Moe';
console.log(another_stooge.nickname); // 'Moe'
delete another_stooge.nickname;
console.log(another_stooge.nickname); // 'Curly'(来自原型链)
解释
-
another_stooge
对象继承了stooge
对象的nickname
属性。 - 通过
delete
删除了another_stooge
自身的nickname
属性后,原型链中的nickname
属性(值为'Curly'
)会显示出来。
通过这个示例,可以更好地理解delete
运算符的作用及其对原型链的影响。
关键点
-
删除属性:
delete
删除对象自身的属性。 -
原型链:
delete
不会影响原型链中的属性。 - 透现属性:如果删除的属性存在于原型链中,删除后原型链中的属性会显示出来。
八、减少全局变量污染 Global Abatement
减少全局变量污染
在JavaScript中,全局变量(var)会削弱程序的灵活性,应尽量避免使用。最小化全局变量污染的一种方法是创建一个唯一的全局变量作为应用的容器,将所有全局性资源纳入该名称空间下。
示例
var MYAPP = {};
MYAPP.stooge = {
"first-name": "Joe",
"last-name": "Howard"
};
MYAPP.flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
通过将全局资源集中在一个名称空间下,可以显著降低程序与其他应用程序、组件或类库之间的冲突风险,同时提高代码的可读性和维护性。但方法不止一种,ES6推出了let,const,在后面章节将会详细介绍,先看下区别:
let 、var 和const的区别
let和const 与var有什么区别
let和const 是es6的新语法,在函数预编译的时候会进行变量提升,这样在变量还没有赋值的时候就可以进行访问。
但是let和const不会,而且let和const遇到{}会形成块级作用域,并且let和const在声明之前是不能访问的,也不能访问
外部具有相同名字的变量因为会形成暂时性死区。这就是let、const和var的区别。
let和const的区别
它们两个的区别主要在let是声明变量,而const是声明常量的。
结语:
本文简单讲了下JavaScript中对象操作的核心概念,包括对象字面量、属性检索、原型链、反射、枚举、删除操作以及减少全局变量污染等关键点。现阶段建议读者继续深入了解下原型链和代理模式,后续小编还会奉上精彩好文!!!
前端实习踩过的坑之CSS系列
【前言】
时间过得真的很快,作为25届毕业生的我即将结束在南京接近6个月的实习。现在处于投简历背八股找工作状态,分享下我在这次充实的实习之旅中遇到的问题和解决方案,在梳理所学知识的同时也能帮助和我一样的前端新人。
1️⃣第一个坑不要太熟悉哦
没错,它就是外边距塌陷问题,我解决这个问题也很简单粗暴,
解决方法: 自己算一下外边距,尽量只设置一个边距
2️⃣渐变色边框导致边框圆角失效
很多朋友都遇到过使用渐变色边框的时候导致圆角失效,那么怎么解决呢?直接上代码截图 效果图:
解决方法: 使用 background-clip 实现 设置两层渐变
border: 1px solid transparent;
border-radius: 20px;
background-image: linear-gradient(
54deg,
#fa7332 0%,
#ed395f 34%,
#ea2837 100%
),
linear-gradient(rgba(249, 162, 156, 1) 0%, rgba(255, 129, 122, 0.43) 100%);
background- origin: border-box;//使图片完整展示
background- clip: content-box, border-box;
//第一个表示裁剪至内容区值,第二个表示裁剪至边框取值
3️⃣图片叠加问题
效果图:
解决方法: 绝对定位和z-Index
.swiper_item_cover {
position: relative;
width: 160.6px;
height: 170px;
.swiper_item_cover_1 {
position: absolute;
z- index: 2;
top: 0;
left: 0;
width: 106px;
height: 170px;
}
.swiper_item_cover_2 {
position: absolute;
z- index: 1;
top:25px;
right: 0;
width: 77px;
height: 134px;
}
}
4️⃣子元素继承父元素的透明度
解决方法: 利用rgba 间接设置透明度
5️⃣兄弟元素的默认行为导致层级覆盖
原因: 如果兄弟元素没有设置position,默认情况下,它的position的值是static。 static元素不参与堆叠上下文 ,因此它们的z-index默认值是auto,这意味着它们会在所有absolute定位元素之上。
解决方法: 给另一个兄弟元素设置 position:relative
6️⃣文本溢出显示省略号
解决方法:
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;/*修改这个数字可以变成多行省略*/
line-clamp: 1;/*这个也要改,scss中可以用@mixin封装成一个方法*/
scss封装示例
@mixin ellicpsisN($lineCount) {
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;//弹性盒模型
-webkit-line-clamp: $lineCount;//弹性盒模型方向垂直//弹性盒模型方向垂直
-webkit-line-clamp: 1;//限制显示的行数
}
//用法
@include ellicpsisN(1);
7️⃣自定义滚动条的样式
UI给图滚动条样式要调整,别急,它来啦
解决方法:
//设置滚动条的宽度高度和背景颜色
::-webkit-scrollbar {
width: 6px;
height: 8px;
background- color: #ebeef5;
}
//设置滚动条滑块的阴影和背景颜色
::-webkit-scrollbar-thumb {
box- shadow: inset 0 0 6px rgba(0, 0, 0, .3);
-webkit-box- shadow: inset 0 0 6px rgba(0, 0, 0, .3);
background- color: #ccc;
}
//设置滚动条轨道的阴影圆角和背景颜色
::-webkit-scrollbar-track{
box- shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border- radius: 3px;
background: rgba(255, 255, 255, 1);
}
8️⃣ 通知弹窗内部自定义html样式
效果图
解决方法:
const handleClickEmployee = (row) => {
const h = this.$createElement;
this.$notify({
title: '提示',
message: h(
'i',
{ style: 'color: teal' },
'This is a reminder'
),
});
};
//利用elment-plus 的组件
ElNotification({
title: 'Title',
message: h('i', { style: 'color: teal' }, 'This is a reminder'),
})
9️⃣ 利用i标签和elment-plus来快速渲染图标
官网上有更多图标可以选,这是几个使用示例哦
解决方法:
🔟移动端项目禁用点击高亮和文本选择
解决方法:
body {
-webkit-tap-highlight- color: transparent;//禁用点击高亮
outline: 0;//移除默认轮廓线
user-select: none;//禁用文本选择
-webkit-user-select: none;
-webkit-text-size-adjust: 100%;//调整文字大小为100%
width: 100%;
}
篇幅限制,本期前端新手容易遇到的CSS坑分享到这里!这几天会逐步更新完这个系列,欢迎大家留言和指导~