安装docker插件 + v2ray 映像

注意:X86 架构的 CPU 支持 docker,ARM 架构的 CPU 不支持 docker

在群辉套件中心搜索 docker 并安装

打开 docker,搜索 v2ray,双击下载 v2ray/official 即可

选择刚刚下载的映像,点击启动

输入容器名称,点击高级设置

在高级设置中勾选启用自动重新启动和创建桌面快捷方式

在卷中添加文件夹,装载路径为 /etc。需要提前在file station 中创建好 docker/v2ray 文件夹

在网络中勾选 使用与 Docker Host 相同的网络

其他默认,点击应用

点击下一步

向导完成后运行此容器 取消选中(因为还没有配置文件)。点击应用

v2ray 客户端配置文件

可以用gui客户端中配置好服务器,直接导出客户端配置文件为 config.json,我使用的是 v2rayN

编辑 config.json, 修改 listen 为 0.0.0.0, protocol 为 http,port 随意,也可以不改

在 v2rayN 程序文件夹中 找到 geoip.dat geosite.dat 文件

在刚刚创建的 docker/v2ray文件夹中在创建一个 v2ray 文件夹,将 config.json geoip.dat geosite.dat 三个文件放进去

我的部分 config.json 配置

{
"inbounds": [
{
"tag": "proxy",
"port": 10808,
"listen": "0.0.0.0",
"protocol": "http",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"settings": {
"auth": "noauth",
"udp": true,
"ip": null,
"address": null,
"clients": null
},
"streamSettings": null
}
]
}

最后启动刚刚创建好的 docker 即可

连接

到这了只是在群辉中安装了 v2ray 客户端,并配置了服务器,还需要手动连接代理,在群辉中,你需要在 控制面板-网络-常规-代理服务器 中添加代理

如果你的其他设备想要连接也需要相同的方式手动配置代理

在 win10 设置中,如下图所示位置,代理方式只支持 http 代理(这就是为什么上步中要把protocol改为http)地址为你群规的ip,端口就是上步中设置的端口,配置完之后保存即可

手机中同理,在无线中配置代理

如果你想实现只需连接家里无线就可以直接实现科学上网,你需要在路由器中做一些配置,可以参考下文【待整理】

css

文字溢出省略号显示

/* 强制一行内显示文本 */
.single-line {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* 强制最多三行显示文本 */
.multi-line {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 强制三行显示 */
overflow: hidden;
text-overflow: ellipsis; /* 不是必须 */
}

让 div 宽度自适应文字内容

.fit-width {
width: fit-content;
}

opacity:0、display:none、visibility:hidden

opacity:0display:none,若父节点元素应用了 opacity:0display:none,无论其子孙元素如何挣扎都不会再出现在大众视野
而若父节点元素应用 visibility:hidden,子孙元素应用 visibility:visible,那么其就会毫无意外的显现出来

max-width 优先级高于行内样式加 !important

<style>
div {
max-width: 50px;
}
</style>
<div style="width: 100px !important;"></div>

div 的宽度为 50px

使用 CSS 网格定义 main 和 aside 元素

CSS 网格可用于定义布局中的 main 部分和 aside 部分,这是 CSS 网格的绝佳用途。问题是,即使 aside 是空的,它的高度也会和 main 的高度相等。

要修复这个问题,可以让 aside 元素与其父元素的起点对齐,这样它的高度就不会扩展了。

.wrapper {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: 20px;
}

/* align-self 将会让 aside 元素与其父元素的起点对齐。 */
aside {
grid-column: 1 / 4;
grid-row: 1;
align-self: start;
}

main {
grid-column: 4 / 13;
}

使用 display: inline-block 时奇怪的空隙

给两个或两个以上的元素设置 display: inline-block 或者 display: inline ,将会导致它们之间产生一个微小的空隙。代码中的换行和缩进(连续空格)被渲染成了一个空格造成的

通过给父元素设置 font-size: 0 可以简单地解决这个问题。

交互式 HTML 元素的字体不生效

给整个文档设置字体的时候,字体并不会应用于诸如 input, button select 和 textarea 这些元素上。默认情况下,它们并不会继承文档字体,因为浏览器给它们应用了系统字体。

要修复这个问题,直接给他们设置字体属性:

input,
button,
select,
textarea {
font-family: your-font-name;
}

css 调试

将代码添加到浏览器的控制台运行,页面上所有元素的轮廓都会显示出来。

https://gist.github.com/addyosmani/fd3999ea7fce242756b1

;[].forEach.call($$('*'), function (a) {
a.style.outline = '1px solid #' + (~~(Math.random() * (1 << 24))).toString(16)
})

压缩或拉伸图片

用 CSS 调整一张图片的大小时,如果纵横比与图片的宽高不一致,则图片会被压缩或拉伸。

解决方法很简单:使用 CSS 的 object-fit。它的功能和给背景图片设置 background-size: cover 类似。

img {
width: 100%;
height: 100%;
object-fit: contain;
/* object-fit: cover; */
}

object-fit 语法参考
https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit

object-fit 属性由下列的值中的单独一个关键字来指定。

取值
contain 保持长宽比,以长边填充
cover 保持长宽比,以短边填充,多余的会被裁减掉
fill 完全填充,会拉伸
none 保持其原有的尺寸
scale-down 内容的尺寸与 none 或 contain 中的一个相同,取决于它们两个之间谁得到的对象尺寸会更小一些。

滚动条样式

::-webkit-scrollbar {
width: 8px;
height: 8px;
}

/* -webkit-scrollbar-thumb 滚动条手柄 */
::-webkit-scrollbar-thumb {
}
::-webkit-scrollbar-thumb:hover {
}

/* -webkit-scrollbar-track 滚动条轨道 */
::-webkit-scrollbar-track {
}
/*滚动条上半边或左半边*/
::-webkit-scrollbar-track-piece:start {
}

/* -webkit-scrollbar-button 滚动条的轨道的两端按钮 */
/*滚动条上边或左边按钮*/
::-webkit-scrollbar-button:start {
}

/* -webkit-scrollbar-corne 垂直滚动条和水平滚动条相交的地方 */
::-webkit-scrollbar-corner {
}

卡券样式

.coupon {
width: 300px;
height: 100px;
position: relative;
background: radial-gradient(circle at right bottom, transparent 10px, #ffffff 0) top right / 50% 50% no-repeat, radial-gradient(circle at left bottom, transparent 10px, #ffffff 0) top left / 50% 50% no-repeat, radial-gradient(circle at right top, transparent 10px, #ffffff 0) bottom right / 50% 50% no-repeat, radial-gradient(circle at left top, transparent 10px, #ffffff 0) bottom left / 50% 50% no-repeat;
filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.2));
}

阴影效果

气泡阴影

.tip {
width: 100px;
height: 30px;
line-height: 30px;
border: 1px solid rgb(245, 129, 127);
border-radius: 4px;
position: relative;
background-color: #fff;
filter: drop-shadow(0px 2px 4px rgba(245, 129, 127, 0.9));
}
.tip::before {
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 10px 10px;
border-color: transparent transparent #fff transparent;
position: absolute;
top: -10px;
left: 0;
right: 0;
margin: auto;
z-index: 2;
}

.tip::after {
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 10px 10px;
border-color: transparent transparent rgb(245, 129, 127) transparent;
position: absolute;
top: -11px;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}

三角形阴影

.shadow-triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 0 50px 50px 50px;
border-color: transparent transparent rgb(245, 129, 127) transparent;
filter: drop-shadow(10px 0px 10px rgba(238, 125, 55, 0.5));
}

缺圆投影

.circle-square {
width: 100px;
height: 50px;
line-height: 50px;
background: radial-gradient(circle at bottom right, transparent 20px, rgb(245, 129, 127) 15px);
filter: drop-shadow(2px 2px 2px rgba(238, 132, 66, 0.9));
}

1px 边框

/* 方式1 */
.border:before {
content: ' ';
box-sizing: border-box;
position: absolute;
pointer-events: none;
width: 200%;
height: 200%;
left: 0;
top: 0;
-webkit-transform: scale(0.5);
transform: scale(0.5);
transform-origin: 0 0;
border: 1px solid #ccc;
}

/* 方式2 */
.border:before {
content: ' ';
box-sizing: border-box;
position: absolute;
pointer-events: none;
top: -50%;
right: -50%;
bottom: -50%;
left: -50%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
border: 1px solid #ccc;
}

记住密码之后,输入框变色问题

谷歌浏览器使用如下方式解决

input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
-webkit-text-fill-color: #ededed !important; // 自动填充文字颜色
-webkit-box-shadow: 0 0 0px 1000px white inset !important; // 使用内阴影覆盖,这个内阴影一定要大,要不然盖不住
}

火狐浏览器无效

自定义封装 vue 指令,实现 select 下拉框滚动加载

封装 v-loadmore 指令

Vue.directive('loadmore', {
bind(el, binding) {
// 获取 element-ui 定义好的 scroll 盒子
const target = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
target.addEventListener('scroll', function() {
// scrollHeight 获取元素内容高度(只读)
// scrollTop 获取或者设置元素的滚动高度
// clientHeight 读取元素的可见高度(只读)
const flag = this.scrollHeight - this.scrollTop <= this.clientHeight
if (flag) {
binding.value()
}
})
}
})

使用

<el-select
v-loadmore="loadMore">
<el-option></el-option>
</el-select>

<script>
export default {
methods: {
loadMore () {
if (this.loadingMore == false) {
this.loadingMore = true
return
}
if (this.currentPage > this.totlaPage) {
return
}
// 获取数据
this.getData()
}
}
}

使用 vue-infinite-scroll

github 地址:https://github.com/ElemeFE/vue-infinite-scroll

安装

npm i vue-infinite-scroll

使用

// # main.js
import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)
<ul v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
<li v-for="(item, index) in moveRecord" :key="index"></li>
</ul>

<script>
export default {
methods: {
loadMore () {
this.busy = true;

setTimeout(() => {
for (var i = 0, j = 10; i < j; i++) {
this.data.push({ name: count++ });
}
this.busy = false;
}, 1000);
}
}
}

element-ui el-scrollbar 组件

https://github.com/ElemeFE/element/blob/dev/packages/scrollbar/src/main.js

<el-scrollbar style="height: 200px">
<ul>
<li>zs</li>
...
</ul>
</el-scrollbar>
.el-scrollbar__wrap {
overflow-x: hidden;
}

微信小程序的 API 都是回调函数,一不小心就是回调地狱。我们可以用 Promise 封装下

const Promisify = f => {
return (arg = {}) => {
return new Promise((resolve, reject) => {
arg.success = res => {
resolve(res)
}
arg.fail = res => {
reject(res)
}
f(arg)
})
}
}

// 使用
const Request = Promisify(wx.request)
const Login = Promisify(wx.login)
Login().then(res => {
if (res.code) {
Request({ url: 'text.php' }).then(res => {
console.log(res)
})
}
})

相关问题

wx.request 经 Promise 封装后,如何拿到requestTask

iconfont 选择好需要使用的图标,将代码下载,解压后找到 iconfont.css 修改名称为 iocnfont.wxss 放到项目中即可

使用: Font class 方式

<icon class="iconfont icon-xxx"></icon>

将无效的字体引用删除,只保留 base64 引用

@font-face {
font-family: 'iconfont';
src: url('data:application/x-font-woff2;charset=utf-8;base64,...') format('woff2');
}

Font class 方式不支持使用彩色图标,且 symbol 方式也无法使用,因为 iconfont.js 中含有操作 dom 的代码,会报错 Cannot read property ‘getElementsByTagName’ of undefined

如果想引入彩色图标

https://github.com/iconfont-cli/mini-program-iconfont-cli

官方文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html

# 初始化
npm init
# 安装包
npm install [package]

打开开发者工具,在本地设置中,勾选使用 npm 模块,
安装完之后 点击开发者工具中的菜单栏:工具 –> 构建 npm

会额外生成一个miniprogram_npm 目录 是开发者工具构建 npm 时生成的,可以理解为小程序版的 npm 包。

在需要的地方引入,以 regenerator 为例

// 引入 regenerator-runtime
const regeneratorRuntime = require('regenerator-runtime')

旧文章害死人

研究了半天,突然发现开发工具在 1.02.1904282 以及之后版本中,增加了增强编译已支持 Async/Await 语法

2019-05-08更新日志第一条

已下内容已过期(文章刚发布一小时)

微信小程序中原生支持 async await 语法,前提是需要关闭 ES6 转 ES5 后

在开启 ES6 转 ES5 后 async 函数无法使用,可以使用 regenerator 包来解决。新版本的 regenerator 在小程序中无法使用,会报如下错误:
regenerator

原因是 regenerator 包更新了 Function 函数,具体可参考:
https://github.com/facebook/regenerator/pull/369
https://github.com/facebook/regenerator/commit/063f14ef7f01bb29830e3f17e9ef151e7a5cb2f3

可以直接使用老版本来解决这个问题,或者修改源码,把 Function 改回去

直接使用老版本

npm install regenerator@0.13.1

如果使用了 npm 模块,之后在需要使用 async 语法的 js 中直接引入即可

const regeneratorRuntime = require('regenerator-runtime')

如果没有使用 npm 模块,不能直接 require 包名,需要将包提取出来,并引入完整路径

const regeneratorRuntime = require('../../libs/regenerator-runtime')

参考:微信小程序中使用 npm 包

去年开始国内无法正常访问 wordpress.org, 一直显示 429 Too Many Requests 错误,所以在我们使用 wordpress 程序的时候会发现无法在线安装主题或者插件,甚至无法更新 WP 版本。

WordPress 官网打不开原因可以参考:https://www.hostloc.com/thread-597678-5-1.html

情况大致是因为:

wordpress.org 受到了中国大陆流量的攻击,导致 WordPress 的 CDN 提供商屏蔽了中国大陆的流量,大陆用户访问插件主题商城等服务时报 429 错误。

这里推荐一款插件:WP-China-Yes

此插件将全面替换 WordPress 访问官方服务的链接为高速稳定的中国大陆节点,以此加快站点更新版本、安装升级插件主题的速度,并彻底解决 429 报错问题。

插件是开源的

发布地址:https://www.ibadboy.net/archives/3204.html
下载地址:https://github.com/wp-china-yes/wp-china-yes/releases

使用:

下载并安装插件后直接启用即可,无需设置,插件会自动接管所有 WP 访问境外服务器的流量。
插件不会更改你的 WordPress 程序,若不想使用大陆加速节点,直接停用插件即可。

常见问题:
插件/主题更新缓慢甚至超时
这种情况在大型包更新的情况下偶尔会出现,原因是第一次访问资源,云存储中还未有相应的镜像,再试一次就会好了。

2020-03-19
真机调试报错 r.Canvas is not a constructor
原因:canvas 2d 和 webgl 暂不支持真机调试,请直接使用真机预览,真机预览模式下使用 vConsole 调试

基础代码(使用 Canvas 2D 接口)

Component({
data: {
ctx: '',
image: ''
},
methods: {
onLoad: function(options) {},
onReady: function() {
const query = wx.createSelectorQuery()
query
.select('#sign')
.fields({ node: true, size: true })
.exec(res => {
console.log(res)
const canvas = res[0].node
const ctx = canvas.getContext('2d')
console.log(ctx)

const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)

ctx.lineWidth = 4 //线条的宽度
ctx.strokeStyle = '#333' //线条的颜色
ctx.lineCap = 'round' //定义线条开头和结尾处的形状
ctx.lineJoin = 'bevel' // 线条与线条之间的连接方式,该属性有三个属性值:miter(默认值,尖角),bevel(衔接),round(圆角)。
this.setData({
ctx: ctx
})
})
}
}
})

实现手写效果

使用 catchtouchmove 绑定,默认会阻止页面跟着滑动

<canvas type="2d" id="sign" bindtouchstart="bindtouchstartHandler" catchtouchmove="catchtouchmoveHandler"></canvas>
bindtouchstartHandler(e) {
if (e.type != 'touchstart') return false
let ctx = this.data.ctx
//开始本次绘画
ctx.beginPath()
//画笔起始点
ctx.moveTo(e.touches[0].x, e.touches[0].y)
},
catchtouchmoveHandler(e) {
let left = e.currentTarget.offsetLeft
let top = e.currentTarget.offsetTop
let pageX = e.touches[0].pageX
let pageY = e.touches[0].pageY

let ctx = this.data.ctx
//根据鼠标路径绘画
ctx.lineTo(pageX - left, pageY - top)
//立即渲染
ctx.stroke()
}

使用 bindtouchmove,需要单独处理页面跟着滚动的问题

给 canvas 绑定 bindtouchmove=”touchmoveHandler” 然后绑定空的 catchtouchmove 事件catchtouchmove="preventTouchmove" 或者直接 catchtouchmove="ture"

<canvas type="2d" id="sign" bindtouchstart="bindtouchstartHandler" bindtouchmove="bindtouchmoveHandler" catchtouchmove="preventTouchmove"></canvas>
bindtouchstartHandler(e) {
if (e.type != 'touchstart') return false
let ctx = this.data.ctx
//开始本次绘画
ctx.beginPath()
//画笔起始点
ctx.moveTo(e.touches[0].x, e.touches[0].y)
},

// bind绑定的事件
bindtouchmoveHandler (e) {
let ctx = this.data.ctx
//根据鼠标路径绘画
ctx.lineTo(e.touches[0].x, e.touches[0].y)
//立即渲染
ctx.stroke()
},
preventTouchmove () {}

保存到相册

wx.canvasToTempFilePath(Object object, Object this)
https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.canvasToTempFilePath.html

 // 把当前画布指定区域的内容导出生成指定大小的图片。 canvas2d不需要使用draw方法
canvasToTempFilePath() {
return new Promise((resolve, reject) => {
const query = wx.createSelectorQuery()
query
.select('#sign')
.fields({ node: true, size: true })
.exec(res => {
// console.log(res)
const canvas = res[0].node
wx.canvasToTempFilePath({
x: 0,
y: 0,
fileType: 'jpg',
canvas: canvas,
success(res) {
console.log(res.tempFilePath) // 文件临时地址 可以保存到相册或上传
resolve(res.tempFilePath)
}
})
})
})
},

// 保存本地
saveToAlbum() {
this.canvasToTempFilePath().then(file => {
wx.getSetting({
success(res) {
// 如果没有则获取授权
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
wx.saveImageToPhotosAlbum({
filePath: file,
success() {
wx.showToast({
title: '保存成功'
})
},
fail() {
wx.showToast({
title: '保存失败',
icon: 'none'
})
}
})
},
fail() {}
})
} else {
// 有授权直接保存
wx.saveImageToPhotosAlbum({
filePath: file,
success() {
wx.showToast({
title: '保存成功'
})
},
fail() {
wx.showToast({
title: '保存失败',
icon: 'none'
})
}
})
}
}
})
})
}

WordPress 在升级程序、主题、插件时,都会先切换到维护模式,也就是显示 ‘Briefly unavailable for scheduled maintenance. Check back in a minute’,如果升级顺利,也就几秒左右就恢复正常;但是如果由于网速不佳等原因导致升级中断,WordPress 就会一直停留在维护模式,不论前台还是后台。

如何解决这个问题呢?

马上通过 FTP 登录你的网站,删除 WordPress 根目录下的 .maintenance ,刷新网页即可。