移动端适配 - IOS 高版本无法下载之 navigator.share 使用
在生产环境中,leader 发现了这样一个问题,在生产环境中,部分 IOS 用户在使用 chrome 时,无法正常下载,点击下载按钮时,没有反应,图片无法正常存储到用户手机上,经过排查后发现基本存在与 ios 15 版本以上
前因之前我们的网站一直主打的是pc端浏览器的使用,但是现在移动端访问网站的用户,也占有一定比例,为了使这一部分能够正常使用,所以针对移动端浏览器访问的时进行了一定的适配和功能调整,以保证用户正常使用,文件下载采用的 file-saver 的 saveAs 方法来下载文件。在线上环境也正常运行了一年的时间
现象针对 Android 用户基本上都能正常下载,但是针对 IOS 15 版本以上的用户,在使用 chrome 时无法正常下载,在针对竞品进行调研后发现他们使用的是 navigator.share 方法,调用浏览器的分享功能来保证能正常下载
使用 navigator.share在 MDN 上是这样介绍的 Navigator.share() 方法通过调用本机的共享机制作为 Web Share API 的一部分。但是由于这是一个实验性的功能,所以浏览器兼容版本比较高, ...
基于 electron 实现一个记录用户粘贴历史记录应用程序 之 基础环境搭建
之前一直使用 utools 工具中的 剪贴板,感觉这个功能十分好用,不用在费劲的去寻找自己之前copy 的记录,十分的方便
但是由于几个月前收费了,本着能白嫖就付钱的心理,所以就没有继续使用了。
最近偶然想要做一下这个功能,也可以学习一个 electron 和 vue3 的新知识
环境搭建可以参考一下这个文章,这里有完整的搭建流程。
但是由于各个电脑的环境以及node, electron 等版本不一样的,所以还是会有一些不同,我只在这里简单的记录一下,并标注一下不同之处
环境
插件
版本
node
v16.14.0
yarn
v1.22.19
vue
v3.2.45
@vitejs/plugin-vue
4.0.0
electron
22.0.0
electron-builder
23.6.0
electron-devtools-installer
3.2.0
rimraf
3.0.2
typescript
4.9.3
vite
4.0.0
vite-plugin-electron
0.10.4
vite-plugin-elect ...
TypeScript 高级类型
TypeScript 有许多高级类型,方便系统更好判断代码是否存在不合理的点,也更方便用户来排查错误和编写代码,下面介绍一些常用的高级类型,这些高级类型在日常开发中可能没有机会用到,但是了解一下对我们并没有任务坏处
交叉类型交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性
相当于混入(mixin),在新的类型中,可以拥有合并的所有类型中的成员
使用 & 来表示交叉
123456789101112131415161718192021222324252627function extend<T, U>(first: T, second: U): T & U { let result = <T & U>{}; for (let id in first) { (<any>result)[id] = (<any>first)[id]; } for (let id in s ...
css 选择器
选择器
例子
例子描述
.class
.intro
选择 class=”intro” 的所有元素。
.class1.class2
.name1.name2
选择 class 属性中同时有 name1 和 name2 的所有元素。
.class1 .class2
.name1 .name2
选择作为类名 name1 元素后代的所有类名 name2 元素。
#id
#firstname
选择 id=”firstname” 的元素。
*
*
选择所有元素。
element
p
选择所有 <p> 元素。
element.class
p.intro
选择 class=”intro” 的所有 <p> 元素。
element,element
div, p
选择所有 <div> 元素和所有 <p> 元素。
element element
div p
选择 <div> 元素内的所有 <p> 元素。
element>element
div > p
选择父元素是 <di ...
hexo 常用命令语句
创建一个博客到指定文件夹1hexo new page --path [folder-path]/[blog-name]
create leetcode 练习(专用)1npx hexo new page --path handredday/leetcode/day-101-2283
web - H5 移动端适配问题
IOS 移动端适配唤起键盘输入时,页面底部的输入框无法浮动到键盘上方参考文章
这个出现的原因主要是 IOS 和 Andriod 的 适配不同
Andriod 的情况比较好理解。软键盘弹出后,实际webview被挤压了,变短了,相当于浏览器变小了,变成 原本高度 - 软键盘高
IOS 发布了 8.2 版本之后,与androids的不同,软键盘弹出,并不是挤压webview,webview的高度不会发生变化,而软键盘更像是一个悬浮在weview上的东西,并不会影响webview的实际高度,是“盖”上去的。这样就造成了我们目前所看到的情况,输入框被键盘遮挡,无法看到用户输入的内容
所以可以看到,我们在IOS上聚焦某个输入框,是会自动让页面发生滚动,以展示聚焦的输入框,此时页面的滚动,实际上是webview自身发生了移动。
这里可以采用的方法有两种
第一种是用户聚焦于输入框的时候,设置window 或者页面区域主动向上方滚动一定距离(例如软键盘高度),当用户失去焦点时,在滚动回原来的位置
第二种是改变 输入框所在元素的高度,使得输入框能够正常显示出来,当用户失去焦点时,在还原回原来的高度
12 ...
一些不常用的事件监听方法
documentselectionchange可以获取到点击的文字所在元素对象及点击或者选中文字起始位置和结束位置
应该是只针对 文字,我点击图片没有触发时间,点击文字时间正常触发12345678910111213141516171819202122// addEventListener versiondocument.addEventListener('selectionchange', () => { console.log(document.getSelection()); /** * anchorNode: text * anchorOffset: 4 * baseNode: text * baseOffset: 4 选中起始位置 * extentNode: text 选中起始元素 * extentOffset: 4 选中结束位置 * focusNode: text 选中结束元素 * focusOffset: 4 * isCollapsed: true * rangeCount: 1 * t ...
vue3 状态管理工具 - pinia
Vue3 出来都有一年多了,生态系统相对来说都慢慢变得完善起来了,像针对 vue2 的 vue-router 路由组件,vuex 状态管理工具都开始适应 vue3 了
这里就介绍 针对 vue3 的状态管理工具 vuex5 又叫 pinia
与 vuex4 和 vuex3 对比
mutations 不再存在。他们经常被认为是 非常 冗长。他们最初带来了 devtools 集成,但这不再是问题。
无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
不再需要注入、导入函数、调用函数、享受自动完成功能!
无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
不再有 modules 的嵌套结构。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。
没有 命名空间模 ...
React Hooks - 自定义hooks
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React
react hooksuseEffectuseEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力
它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途
在使用时我们传递一个数组,useEffect 会在数组内的数据发生变化时重新执行
useEffect 函数需返回一个清除函数,清除函数会在组件卸载前执行。另外,如果组件多次渲染(通常如此),则在执行下一个 effect 之前,上一个 effect 就已被清除
12345useEffect(() => { return () => { // ...
vue3 组合式Api setup
什么是组合式API组合式API 主要是为了把相同的逻辑关注点收集在一起,使得逻辑处理更加清晰和方便。
针对 vue2 的组件选项来说,(data, computed, methods, watch)等组件存在,导致我们在修改同一个逻辑关注点的之后需要不停地跳转相关的代码块,代码碎片化,使得我们理解和维护复杂组件变得困难。
在 vue3组件中,这个位置称为 setup
这个是 Vue3 新增的一个选项 setup 选项会在组件被创建之前执行,一旦 props 解析完成,setup 就会被作为 组合式Api 的入口,也就是说 setup 执行的时机要比 vue2 的 beforeCreate 要早,此外 setup 中应避免使用 this 且因为调用发生在 data,computed,methods 之前,所以无法在 setup 中获取
既然 setup 中无法获取到 data,computed 中的内容,那么我们怎么创建和监控变量变化,且组件内能获取到呢?
setup 接收 props 和 context
props 是父元素传递过来的 props
context 是当前组件实例上下文 ...