lennonover


  • 首页

  • 归档

  • 标签

HTML 章节与大纲

发表于 2019-08-21

HTML4

HTML 4 用文档中章节和子章节的概念去描述文档结构,一个章节由一个包含着标题元素(h1-h6)的 div 元素表示。

HTML div 元素(<div> elements)并不强制性地定义一个章节。一个 HTML 标题元素( HTML Heading Element)的出现就足以意味着新的章节。

所以就造成如下问题:

  • 定义语义性章节的 <div> 元素的用法,如果没有为 class 属性赋以特殊的值,使生成自动生成大纲的算法变得不可能
  • 并多个文档是困难的
  • HTML4 中,所有的章节都是文档大纲中的一部分。但是文档并不总是这样。文档可以包含那些不是大纲的特殊章节, 但是与文档有关的,就像广告块和解释区域。
  • 因为在 HTML4 中任何的部分都是文档大纲的一部分, 没有办法产生与网站相关而不是与文档相关的节段,比如 logos,menus,目录或版权信息和法律声明。

HTML5

  • HTML5 在自动生成大纲算法的过程中去掉了 div 元素(<div>),并新增了一个元素,section 元素(<section>)

  • 新引入的元素(<article>、<section>、<nav> 和 <aside>)合并多个文档

    • article(页面结构) 页面中独立的结构它可能是论坛帖子、杂志或新闻文章、博客、用户提交的评论、交互式组件,或者其他独立的内容项目例如一个页面有文章和评论区可以用两个 article 。
      -​​ 通常包括标题( <h1> - <h6> 元素)。
      • 素嵌套使用时,则该元素代表与外层元素有关的文章。例如,代表博客评论的 <article> 元素可嵌套在代表博客文章的 <article> 元素中。
      • 可能包含一个或多个 <section>。
    • section(文档) 表示一个包含在 HTML 文档中的独立部分,它没有更具体的语义元素来表示,一般来说会有包含一个标题,例如 h1-6 相关的级别只在一个 section 节段中起作用,每个 section 独立。
      • 如果元素内容可以分为几个部分的话,应该使用 <article> 而不是 <section>。
      • 不要把 <section> 元素作为一个普通的容器来使用,这是本应该是<div>的用法(特别是当片段(the sectioning )仅仅是为了美化样式的时候)。 一般来说,一个<section>应该出现在文档大纲中。
    • nav 表示页面的一部分,其目的是在当前文档或其他文档中提供导航链接。导航部分的常见示例是菜单,目录和索引。
    • aside 表示一个和其余页面内容几乎无关的部分,被认为是独立于该内容的一部分并且可以被单独的拆分出来而不会使整体受影响。
  • HTML5 引入 aside 元素 <aside> 使得这样的节点不会插入到主纲要中例如广告。

  • HTML5 引入了三个特殊的节段 元素: 包含链接集合的 nav 元素 <nav> , 例如目录, 包含网站相关信息的 footer 元素 <footer> 和 header 元素 <header> 。

QRCode 二维码生成

发表于 2019-06-24

使用

1
<div id="ele"></div>
1
2
3
4
5
6
7
8
9
var ele = document.getElementById('ele')
new QRCode(ele, {
text: 'www.yuewen.com',
width: 86,
height: 86,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});

模糊识别 correctLevel

更高的级别可以识别更模糊的二维码,但会降低二维码的容量。如果生成的二维码不会被破坏,建议使用低识别等级。

等级 最大模糊面积
L(低级) ≤7%
M(中级) ≤15%
Q(四分之一) ≤25%
H(高级) ≤30%

默认是 QRCode.CorrectLevel.M

模糊识别等级也会影响二维码容量(当然版本也会影响)

编码模式 L(低级) M(中级) Q(四分之一) H(高级)
数字 7089 5596 3993 3057
数字+字母 4296 3391 2420 1852
字节 2953 2331 1663 1273
汉字 1817 1435 1024 784

关于生成二维码识别率不高

  • 二维码图片过小会影响识别率

  • 本身 canvas 在绘图时,会有像素模糊,可以通过放大倍数,在二维码生成阶段可以生成 2 倍大小、然后通过 css 设置还原设计稿大小

  • 字符串比较长,就会加大二维码的像素复杂度,通过转换短连接缩短二维码长度

  • 可以通过给二维码设置边框来提高识别率

其他

更多 api qrcode

js 中四种相等

发表于 2019-05-19

在ES2015中有四种相等算法

ecma规范定义算法规则
7.2.10 SameValue
7.2.11 SameValueZero
7.2.12 SameValueNonNumber
即术语同值、同值零、同值非零

  • 抽象相等 ==
  • 严格相等 ===,用于
    • Array.prototype.indexOf
    • Array.prototype.lastIndexOf
  • 同值零(SameValueZero),用于
    • Map
    • Set
    • String.prototype.includes
    • ArrayBuffer构造函数
    • TypedArray构造函数
  • 同值(SameValue),用于
    • Object.js()

定义

ECMA中SameValue比较规则

  • 类型不一样,返回false
  • 类型为number时
    • 都为NaN,返回true
    • x为+0,y为-0时,返回false
  • 类型不是number时,return SameValueNonNumber()
    1
    2
    3
    4
    5
    NaN === NaN // false
    Object.is(NaN, NaN) // true

    -0 === +0 // true
    Object.is(-0, +0) // false

ECMA中SameValueZero比较规则

  • 类型不一样,返回false
  • 类型为number时
    • 都为NaN,返回true
    • x为+0,y为-0时,返回true
  • 类型不是number时,return SameValueNonNumber()
    1
    2
    3
    4
    5
    6
    7
    8
    const foo = new Map()
    foo.set(0, '0') // Map(1) {0 => "0"}
    foo.set('0', 'zero') // Map(2) {0 => "0", "0" => "zero"}
    foo.get(0) // 0
    foo.get('0') // zero
    var arr = [1, 2, NaN];
    arr.indexOf(NaN); // -1
    arr.includes(NaN); // true

SameValue与SameValueZero的差别在于数值类型时+0和-0,保证 +0和-0 不再相同

ECMA中SameValueNonNumber比较规则

  • 为Undefined,返回true
  • 为Null,返回true
  • 为String,则比较这2个字符串的码点
  • 为Object,则比较是否指向同一个堆地址

JavaScript提供三种不同的值比较操作:

  • ==
  • ===
  • Object.is

Object.is的行为方式与===相同,但是对于NaN和-0和+0进行特殊处理

1
2
3
4
5
NaN === NaN // false
Object.is(NaN, NaN) // true

+0 === -0 // true
Object.is(+0, -0) // false

可以看到Object.is采用的SameValue算法,而全等可以看作是SameValueZero排除NaN的情况,因为全等操作符认为 NaN 与其他任何值都不全等,包括它自己。

移动端键盘表现

发表于 2019-04-17

键盘弹出的表现

头部及中间输入框处于正常的文档流,底部元素 fixed bottom;头部处于正常的文档流,输入框脱离文档流,底部元素 fixed bottom。

  • IOS(12.1.4)
    ios1.jpg
  • Android(8.0)
    android1.jpg

IOS 页面高度始终不变,页面可以滚动,底部元素被遮挡,基线不变;
Android 页面高度减少,页面可以滚动,fixed 元素的 bottom 属性的基线为键盘;

键盘事件

键盘弹出

  • IOS(12.1.4)

    1
    2
    3
    4
    5
    // 监听输入框的 focus 事件
    const input = document.getElementById('input');
    input.addEventListener('focus', () => {
    console.log("弹出")
    }, false);
  • Android(8.0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 监听输入框的 focus 事件
const input = document.getElementById('input');
input.addEventListener('focus', () => {
console.log("弹出")
}, false);

// 监听 webview height 的变化
const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.addEventListener('resize', () => {
const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (resizeHeight < originHeight) {
console.log("弹出")
}
}, false);

键盘收起

  • IOS(12.1.4)

    1
    2
    3
    4
    5
    // 监听输入框的 blur 事件
    const input = document.getElementById('input');
    input.addEventListener('blur', () => {
    console.log("收起")
    }, false);
  • Android(8.0)

1
2
3
4
5
6
7
8
// 监听 webview height 的变化
const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.addEventListener('resize', () => {
const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (resizeHeight >= originHeight) {
console.log("收起")
}
}, false);

ios2.jpg
android2.jpg

其他已知的一些问题

在上文键盘事件 IOS 测试中有个很明显的差别是页面头部的 起点读书 不见了,见下图:
jianpan.jpg
从上图可以发现,当聚焦 input 输入框时候 ios 版本会被整体上推而且键盘收起试并不会恢复具体事例可以查看 运领这篇,也给出了相关解决方案用 JS 记住位移收起时恢复。

网页中文排版-持避头尾

发表于 2019-03-13

一个小 bug

企业微信20190308023948-min.png

从上图可以看书逗号没有规避在行首,在我影响中文排版会有避头尾的规则不应该出现。为了确保准确性我们再来翻一遍 unicode 断行算法 Unicode 规范不仅是给字符安放了码位、制定了编码规则,还制定了大量与文字编码相关的规范并收在附件内,是规范不可缺少的组合部分。。

LB13 Do not break before ‘]’ or ‘!’ or ‘;’ or ‘/’, even after spaces.
LB19 Do not break before or after quotation marks, such as ‘ ” ’.
LB21 Do not break before hyphen-minus, other hyphens, fixed-width spaces, small kana, and other non-starters, or after acute accents.
LB22 Do not break between two ellipses, or between letters, numbers or exclamations and ellipsis.

翻译下也就是

  • LB13
    在 ‘]’、‘!’、‘;’、‘/’ 之前不能断行,即使这些字符跟在空格后面。因此,此规则实质上此条规定了分隔号(/)需要避头;
  • LB19
    引号的前、后均不能断行。也就是说常用的蝌蚪引号(“ ”)默认是既要避头也要避尾。
  • LB21
    在连字符、其他连字符、定宽空格、小写假名等字符前面不能断行,中文的连接号避头。
  • LB22
    两个省略号之间,以及字母数字叹号与省略号之间不能断行。也就是说,省略号不仅不能中间断开,而且要避头。

那为什么会出现前面那个 bug , 原来是同事使用了 word-break:break-all;

word-break:break-all

这个属性会把单词强制断开,为了实现中日韩排版里偶尔需要牺牲西文连字而定制的,不能保证中文的避头尾的正常使用。

word-wrap:break-word

CSS3 也已经明确要将 word-wrap 改为 overflow-wrap 。
这个属性会把单词断开,而且会尽可能地保持避头尾,也尽可能避免中途断开,例如解决超长网址。

企业微信20190308042958.png

网页中文排版-标点悬挂

发表于 2019-03-08

标点悬挂是优秀中文排版里的一个“充分非必要”条件,一些的电子书排版引擎,实现了这功能,就被誉为“排版设计最好的电子书”。网页环境下对字体排印的高级特性的支持非常有限,但是查特性发现 Safari 一枝独秀:
33.png

hanging-punctuation

none | [ first || [ force-end | allow-end ] || last ]

CSS属性指定了标点符号应该放在文本句子的开头还是结尾。悬挂标点符号可能被放在线框外。

  • none
    No character hangs.
  • first
    显示元素的第一个格式化行开头的括号或引号。
  • last
    显示元素的最后一个格式化行结尾的括号或引号。
  • force-end
    显示行结尾处的句号或逗号。
  • allow-end
    如果预先没有其它适合的来适应的,则在行尾显示句号或逗号。

  • 示例:

企业微信20190308020440.png

可以完美的实现标点悬挂,接下我们来看看呢兼容性情况:

企业微信20190308020617.png

看兼容就知道要开心的使用是不可能的。但是怎么会没轮子 Han

这个汉字标准格式库完美实现了中文排版的各种需求。

JS Number 安全整数范围

发表于 2019-02-23

在公司海外产品书籍详情页会出现部分页面无法打开问题,查找到是因为异步获取 book id 加载报错导致才发现这个最大元凶的 js 的安全整型范围溢出导致。

JS Number 安全整数范围

JS 中所有的数字类型,存储都是通过 8 字节 double 浮点型 表示,能够精确表示,使用算数运算的没有很大即:

Math.pow(2, 53) - 1 // 9007199254740991

而我们的超大书封 id 早就大于这个安全范围,所以才会导致加载失败。

H5 video 自动播放

发表于 2019-02-12

移动端

ios

从 ios 11 以后的版本,以下:

  • 无音频源的 video 元素 允许自动播放
  • 禁音的 video 元素允许自动播放
  • 如果 video 元素在没有用户手势下有了音频源或者变成非禁音,会暂停播放
  • video 元素屏幕可见才开始播放
  • ideo元素不可见后停止播放

参考链接

Android

只有移动端 chrome 53 以上需要同时对 video 设置 autoplay 和 muted(是否禁音),才允许自动播放; 安卓的 FireFox 和 UC 浏览器支持任何情况下的自动播放; 安卓的其他浏览器不支持;

参考链接

PC 端

Safari 浏览器

Safari 10 后带音频的视频和音频默认禁止自动播放

Chrome 浏览器

禁音的视频依旧可以播放,带声音的视频会根据:

  • 用户在媒体上停留时间超过了 7秒以上
  • 音频必须是展示出来,并且没有静音
  • 与 video 之间有过交互
  • 媒体的尺寸不小于 200x140

来决定能否自动播放

关于全屏播放

大家创意 H5 活动的时候背景有的时候是用的视频,但是在点击播放或者通过 API video.play() 触发播放时,会强制以全屏置顶的形式进行播放。这样 video 的层级会很高,所以在 video 元素之上,无法显示其他的元素,也就没有了交互,这是让人崩溃的!

  • 基于 webkit 内核的移动端浏览器

只需在 video 标签加个 playsinline 属性

补充:
对于 ios 如果仍有个别版本的 ios 会唤起播放器,可以引用一个库 iphone-inline-video

补充:

对于 ios 如果仍有个别版本的 ios 会唤起播放器,可以引用一个库 iphone-inline-video

对于在 QQ 和微信环境内
使用 qq.com 域名可以解决(亲测可以)
x5-video-player-type=”h5”属性
加了这个属性后视频上层可以有其他 dom 元素出现了

  • 对于在 QQ 和微信环境内

使用 qq.com 域名可以解决(亲测可以)
x5-video-player-type=”h5”属性
加了这个属性后视频上层可以有其他 dom 元素出现了

关于去除播放控件

  • android 对于在 QQ 和微信环境内

腾讯在浏览器里做了一些配置使用 qq.com 域名就没有问题了,我们平时的活动如果有涉及到视频的都会启用 qq.com 域名。

  • 也可以放大视频顶到视窗外面

补充:
对于 x5-video-player-type="h5" 属性播放控件也隐藏了

Js 几种循环的比较

发表于 2019-01-27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const TEST_SIZE = 10000000;
// 常用
let arr1 = (new Array(TEST_SIZE)).fill(1);
let target1 = [];
let iStart1 = (new Date()).getTime();
for (let i=0; i < arr1.length; i++) {
target1.push(arr1[i]);
}
let iEnd1 = (new Date()).getTime();
console.log('for:' +(iEnd1 - iStart1)+'ms');

// 取 len
let arr11 = (new Array(TEST_SIZE)).fill(1);
let target11 = [];
let iStart11 = (new Date()).getTime();
let len = arr11.length;
for (let i=0; i < len; i++) {
target11.push(arr11[i]);
}
let iEnd11 = (new Date()).getTime();
console.log('for-len:' +(iEnd11 - iStart11)+'ms');

// 倒叙
let arr12 = (new Array(TEST_SIZE)).fill(1);
let target12 = [];
let iStart12 = (new Date()).getTime();
for (let i = arr12.length; i--;) {
target12.push(arr12[i]);
}
let iEnd12 = (new Date()).getTime();
console.log('for-re:' +(iEnd12 - iStart12)+'ms');

// 将取值与判断合并,通过不停的枚举每一项来循环
let arr13 = (new Array(TEST_SIZE)).fill(1);
let target13 = [];
let iStart13 = (new Date()).getTime();
for (let i = 0, a; a = arr13[i]; i++) {
target13.push(a);
}
let iEnd13 = (new Date()).getTime();
console.log('for-a:' +(iEnd13 - iStart13)+'ms');

// forEach
let arr2 = (new Array(TEST_SIZE)).fill(1);
let target2 = [];
let iStart2 = (new Date()).getTime();
arr2.forEach(function(item){
target2.push(item);
});
let iEnd2 = (new Date()).getTime();
console.log('forEach:' +(iEnd2 - iStart2)+'ms');

// map
let arr3 = (new Array(TEST_SIZE)).fill(1);
let target3 = [];
let iStart3 = (new Date()).getTime();
arr3.map(function(item){
target3.push(item);
});
let iEnd3 = (new Date()).getTime();
console.log('map:' +(iEnd3 - iStart3)+'ms');

// while
let arr4 = (new Array(TEST_SIZE)).fill(1);
let target4 = [];
let iStart4 = (new Date()).getTime();
let index = 0;
while(index < arr4.length) {
target4.push(arr4[index]);
index++
}
let iEnd4 = (new Date()).getTime();
console.log('while:' +(iEnd4 - iStart4)+'ms');

// for in
let arr5 = (new Array(TEST_SIZE)).fill(1);
let target5 = [];
let iStart5 = (new Date()).getTime();
for (let obj in arr5) {
target5.push(arr5[obj]);
}
let iEnd5 = (new Date()).getTime();
console.log('forin:' +(iEnd5 - iStart5)+'ms');

结果

测试环境
机器 iMac (Retina 5K, 27-inch, Late 2015) 10.13.6 (17G65)3.2 GHz Intel Core i5
node v8.11.3
chrome 71.0.3578.98(正式版本) (64 位)
firefox 64.0 (64 位)
safair

结果

  • 谷歌浏览器中 ES6+ 的循环语法会普遍比传统的循环语法慢

  • 不管是 for 循环还是 forEach v8 里面都差不多

  • 对于 “枚举” 循环

    数组中应当避免查找空值或者是超出范围的值,这样会导致在原型链中的向上查找,很耗性能。这种循环方式会把所有的元素取出,并不停的迭代下一个,直到出现 undefined 或 null ,这样就出现的向上查找的情景。

  • 对于 提前取数组长度也就是方法二

    实际数组的 length 在每次循环中都会重新读区,并不会提前计算好,而是 v8 引擎最大限度的优化了对象取值的性能。

2018总结

发表于 2019-01-19
  • React
  • 前端在交互、视觉上更多的探索
  • 技术水平的提升:宽度和深度
  • 技术类的书籍很多都开了头但没能读完 18 年能坚持读完

首先先看看 2017 年的立的 flag,现在看看好宽泛啊:

  • react
    用 react 全家桶单独开发过项目也算是完成当初期望,但是下半年主要公司都花在 vue 上,这是始料不及的。

  • 在用户体验方面
    目前在项目做作了了许多前端方面的最佳实践达到预期目标

  • 前端水平
    明显感觉没有进步很大相对于前面两年,目前也分析了原因主要是下半年换工作到了上海加入了理想的团队反而有所放松。

  • 读书
    是看了好多书嗯非技术的

工作

很高兴张鑫旭老师的内推加入了一个很棒很有爱的前端团队,工作内容的变化,行业的转变也带来了一些挑战,当然也很快融入进去。
从软件公司到互联网公司的转变,真正做到直面用户也给了我在用户体验方面有很大的提升。下半年主要的技术栈是 vue ,真香警告! vue 做的真的是太有好了,每每发出 wc 还可以这样。

今年的文章写得太少了,社区方面也是。

2019

今年最大的 flag 就是可以生活和工作处理好!还有要学会演讲,因为团队分享是老是感觉力不从心, PPT 也是,当时完全忽略了这种技术以外的软技能,来到这边之后才发现。

1234…7
lennonover

lennonover

一丿口石砳磊

70 日志
28 标签
© 2022 lennonover
由 Hexo 强力驱动
主题 - NexT.Muse