粘性布局之粘底效果(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))是最简最万能的拷贝。

直接操作 Vue data 中不存在的属性导致的 v-model 绑定异常问题

直接操作 Vue data 中不存在的属性导致的 v-model 绑定异常问题

初学Vue遇到的问题,尝试了几个小时才搞明白,大佬应该一眼就能看出什么问题吧……

需要注意,不要直接在JS中操作一个Vue data对象中不存在的属性,如果同时有通过v-model绑定到该对象的不存在的属性时,会出现诡异的行为表现,console中不会报出任何 warnerror

需求是,实现三个复选框,第一个复选框初始为选中状态,一开始写出来是这样的——

HTML
1
2
3
4
5
<div id="app" style="margin: 10px;">
<van-checkbox v-for="box in checkboxes" :key="box.id" v-model="box.selected">
复选框 {{ box.title }}
</van-checkbox>
</div>
JS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
new Vue({
el: '#app',
data () {
return {
checkboxes: [
{ id: 1, title: 'a' },
{ id: 2, title: 'b' },
{ id: 3, title: 'c' }
]
}
},
created () {
this.checkboxes[0].selected = true
}
})

试下效果:

See the Pen vue-v-model-not-work by iMaeGoo (@iMaeGoo) on CodePen.

复选框a的表现显然是异常的,点击不能成功地切换选中状态,而在点击之后再点击其他复选框,才会“有延迟地”切换状态。

阅读更多
CSS 类似 iOS 的毛玻璃动态模糊效果

CSS 类似 iOS 的毛玻璃动态模糊效果

提到网页毛玻璃效果,总结下来有以下2种:

  1. 模糊元素本身
  2. 模糊元素后面的内容

早在之前,1就已经可以通过 CSS3 filter 属性实现,而2一直没有一个好的解决方案。对1的运用,也可以达到2的效果,通过模糊图片的一部分,就可以实现类似 bilibili 导航栏的模糊背景效果 ↓

这样实现的前提是,我们的背景是一个静态的,单一的图片,那么如果我们需要模糊的背景比较复杂呢?仔细观察QQ右栏的标题栏,和下方的应用 Dock,都是 iOS 常见的毛玻璃叠加层效果 ↓

显然模糊元素本身并不能解决所有场景的问题。

阅读更多