工作两年之余翻起高中写的代码……

工作两年之余翻起高中写的代码……

许久没再打开过的QQ空间突然有了提示,打开看到是母亲在翻我的软件相册,里面是些高中做出来的东西。

学业那么紧张的情况下,有时间接触手机电脑,甚至还写代码,在我们那个年代,绝对不是随便哪个学生都有的经历。

有初中时候写收菜脚本的基础,我对逻辑有了一定的理解并逐渐着迷,但又没有系统的教学,写出来的东西甚是粗糙。那时候学习 VB 仅仅是看一张名为开天辟地的电脑速成光盘,早期甚至都没有宽带网。
不知道如何解析 HTML,就用字符串查找函数;
不知道如何模块化编程,就一个文件写 800 多行;
不知道如何定位异常,就给每一行代码开头加行号;
不知道怎么做安装程序,就写 bat 脚本用 RAR 打自解压包;
不知道怎么读写配置文件,就用基本输入输出 txt;
甚至一开始连缩进都不懂,代码直上直下的……

虽然走过这么多的弯路,还影响了高中学习险些没有考上本科,但收获了许多课堂里学不来的东西。

这月初的时候,我在整理一块老硬盘,把高中写的 班班通助手班班通助手2.0 传到了 Github 上保存。我终究还是怕在硬盘里哪一天它就那样丢失了。

失去理智注意力涣散 的时候,想想曾经为之着迷的自己,至少还是很励志的。

阅读更多

Icarus 夜间模式(实验中)

更新了 Icarus 主题代码,右上角增加了夜间模式切换按钮,是实验中的功能,欢迎体验。

通过向 body 添加名为 night 的 class 实现,状态记在浏览器 localstorage 中。

已知问题:

  1. 样式可能没有全面覆盖。
  2. 夜间模式在低性能浏览器上导致页面响应缓慢,需要优化性能。

目前还没有做成插件,仅在自己的博客使用,后期如果有时间的话,会考虑做成 extension。


更新:已经发布了——

Icarus 2 请参考:如何给 Icarus 增加夜间模式
Icarus 3 请参考:Icarus 夜间模式支持 3.0 了

粘性布局之粘底效果(position sticky, bottom 0)

粘性布局之粘底效果(position sticky, bottom 0)

经常在查资料时访问各种 CSDN 博客会发现,当 屏幕高度 < 左边栏的高度 < 内容的高度 时,滚动屏幕,左边栏会随着内容一同滚动,当滚动到左边栏底部时,左边栏会停止滚动,而内容会继续滚动。

这种设计的优势在于,用户既能够滚动左边栏,又不会在左边栏不够长时,造成页面左侧大片空白的尴尬,这种布局模式,叫做 粘性布局(sticky)

粘性布局在元素满足显示条件时,表现与普通布局没什么不同,但当元素随着页面滚动而无法显示时,会转为 fixed 布局效果,主流浏览器已经全部支持粘性布局(IE不支持)。

通俗一点讲,类似于 Excel 中的“冻结窗格”。

绝大多数网上的教程材料都用 position: sticky; top: 0; 这样的组合来举例,但为了实现 CSDN 左边栏效果,position: sticky; bottom: 0; 似乎不能和想象一样的起作用。

先说结论吧

  1. sticky 的确是无法直接粘底的……
  2. CSDN 使用 JS 动态计算实现,当计算到左边栏底部即将滚上屏幕时,立即对左边栏添加 position: fixed; bottom: 0; 样式,把左边栏定死,延时较为明显,快速上下滚动时能看到闪烁
  3. 我使用 position: sticky; 实现,通过 JS 计算 屏幕高度 - 左边栏高度 得到 top 的值,快速滚动时没有闪烁
阅读更多

Chrome 各版本地址栏显示完整地址(https 和 www)

效果

由于谷歌最近对 Chrome 地址栏改来改去,不同的版本需要对应不同的方法。

Chrome 版本<78

在浏览器输入 chrome://flags/ 回车,找到 Omnibox UI Hide Steady-State URL Scheme and Trivial Subdomains,设置为 Disabled,然后重启浏览器。

Chrome 版本=78

谷歌从 flag 页面砍掉了这个设置,但 flag 还是存在的。

打开 chrome://flags/,78版本已经找不到 omnibox-ui-hide-steady-state-url-schemeomnibox-ui-hide-steady-state-url-trivial-subdomains 了。
按 F12 打开 Console,执行以下命令,然后重启 Chrome。

Console
1
2
3
4
5
6
7
[
'omnibox-ui-hide-steady-state-url-path-query-and-ref',
'omnibox-ui-hide-steady-state-url-scheme',
'omnibox-ui-hide-steady-state-url-trivial-subdomains'
].forEach((f) => {
chrome.send('enableExperimentalFeature', [`${f}@2`, 'true']);
})

代码中 @2 对应的是 Disabled。@0@1 分别对应 Default 和 Enabled。

测试有效的版本:78.0.3904.97
方法来源:ysc3839(https://www.v2ex.com/t/613776

Chrome 版本>78

谷歌彻底砍掉了这两个 flag……

现在安装插件是唯一方法,如果你能够访问 Chrome 网上应用店的话,安装这个插件,无需配置即可显示完整地址:
https://chrome.google.com/webstore/detail/suspicious-site-reporter/jknemblkbdhdcpllfgbfekkdciegfboi
方法来源:MaiKuraki(https://www.v2ex.com/t/588136

如果是 Windows 系统,也可以换用 Chromium 内核的 Edge 浏览器,我已经完全爱上 Edge 啦!

Chromium

IT之家报导,谷歌决定“使URL更易于阅读和理解,并消除对可注册域的干扰”,在Chromium Gerrit中新提交了一个flag标志,未来可在 chrome://flags#context-menu-show-full-urls 中设置开启,届时Chrome浏览器地址栏便可显示完整URL。

嗯,砍了再加回来,绝世好活!

我并没有下载 Chromium 测试这个 flag,未来推出有这个 flag 的正式版后,我可能会会更新这篇博文。

Bitnami MariaDB 重启失败记录

自动部署的 Magento 附带的 MariaDB 镜像第一次启动能够成功,但 stop 之后就无法再次启动。启动命令 docker-compose up -d,重启命令 docker-compose restart

关键 log:

1
2
3
InnoDB: Assertion failure in file /bitnami/blacksmith-sandox/mariadb-10.2.28/storage/innobase/dict/dict0dict.cc line 1467
InnoDB: Failing assertion: table->can_be_evicted
[ERROR] mysqld got signal 6 ;

详细的 stdout 如下——

阅读更多

Windows 下通过 Vagrant 简单搭建 Magento

准备软件

  1. VirtualBox 5.2.8
  2. Vagrant 2.0.1

官网下载安装,比我的新即可,安装路径自选。

创建 Vagrantfile

新建文件夹并创建 Vagrantfile 放在里面,我配置的环境是 Ubuntu 16.04,内存8G,可以换成自己熟悉的环境。
映射端口80,443(Web),3306(数据库),9200,9300(搜索引擎)。

Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.network "forwarded_port", guest: 443, host: 443
config.vm.network "forwarded_port", guest: 3306, host: 3306
config.vm.network "forwarded_port", guest: 9200, host: 9200
config.vm.network "forwarded_port", guest: 9300, host: 9300
config.vm.provider "virtualbox" do |vb|
vb.memory = "8192"
end
end
阅读更多

JS 原生对象与数组拷贝

浅拷贝单层对象

1
2
let obj = { id: 1, title: "1" }
let copyOfObj = Object.assign({}, obj)

深拷贝多层对象

1
2
3
4
5
6
7
let obj = {
id: 1,
title: "1",
tag: ['js', 'javascript'],
category: { id: 1001, title: 'frontend' }
}
let copyOfObj = JSON.parse(JSON.stringify(obj))

浅拷贝简单类型数组

1
2
let arr = [1, 2, 3]
let copyOfArr = [...arr]

深拷贝单层对象组成的数组

1
2
3
4
5
6
7
let arr = [
{ id: 1, title: "1" },
{ id: 2, title: "2" },
{ id: 3, title: "3" }
]
let copyOfArr1 = arr.map((item) => Object.assign({}, item))
let copyOfArr2 = JSON.parse(JSON.stringify(arr))

深拷贝多层对象组成的数组

1
2
3
4
5
6
7
let arr = [
{ id: 1, title: "1", subObj: { name: 'subObj1' } },
{ id: 2, title: "2", subObj: { name: 'subObj2' } },
{ id: 3, title: "3", subObj: { name: 'subObj3' } }
]
let copyOfArr1 = arr.map((item) => JSON.parse(JSON.stringify(item)))
let copyOfArr2 = JSON.parse(JSON.stringify(arr))

总结

不考虑性能的情况下,JSON.parse(JSON.stringify(value))是最简最万能的拷贝。