Document.scrollingElement

参考:

why to use 'html, body' for scrollTop instead of just 'html'

MDN

使用document.scrollingElement控制窗体滚动高度

要监听 root scrollbar 的 scroll event,使用

document.addEventListener('scroll', () => {
// do something...
}, { passive: true, capture: true });

window 也可以,不过通常是用 document。

其它的 document.documentElement,document.body 都不对。

如果要拿 root scrollbar 的 scrollTop,不是用 document.scrollTop 哦。

而是

(document.scrollingElement ?? document.documentElement).scrollTop

Mobile scroll hide address bar & scroll event

手机 scroll 的时候会自动把 address bar 隐藏起来. 但有一个前提条件.

那就是需要用 body / document scroll

如果套了一层 container, 并让 container 负责 scroll, 那么这个 address bar 就不会隐藏了.

 

如果设置 html or body scroll 的效果和没有设置其实是一样的. address bar 依然会隐藏

 

顺便说一下 scroll event

document.addEventListener("scroll", (e) => {
console.log("document", e.target);
});
document.documentElement.addEventListener("scroll", (e) => {
console.log("documentElement", e.target);
});
document.body.addEventListener("scroll", (e) => {
console.log("body", e.target);
});
console.log(document.scrollingElement === document.documentElement); // true

如果 .container 负责 scroll, 那么没有 scroll event 会触发. 只有 .container 元素监听 scroll 才会触发.

如果 body 设置或没有设置 scroll, 那么在 chrome 游览器, document 触发 scroll event.

同时 scrollingElement 是 document.documentElemenet

获取 transform translate

参考: Stack Overflow – How to get value translateX by javascript

CSS Style

transform: translateX(-10%) translateY(-55px);

JavaScript

export function getTranslate(element: Element): { translateX: number; translateY: number } {
const currentTransform = window.getComputedStyle(element).transform;
const matrix = new WebKitCSSMatrix(currentTransform);
return {
translateX: matrix.m41,
translateY: matrix.m42,
};
}

先通过 computedStyle 拿到 matrix, 然后用 CSSMatrix parse. m41, m42 分别是 translateX, Y.  还有其它属性比如 translateZ, scale, rotate 等.

value 是计算后的 number.

注意: 如果使用了 CSS variables 就拿不到了. 结果总是返回 zero.

--translate-x: calc(var(--spacing-4) * -1);
--translate-y: calc(var(--spacing-4) * -1);
transform: translateX(var(--translate-x)) translateY(var(--translate-y));

通常, 如果想用 JS 控制 transform. 用 CSS Variables 是不错的方式. 参考: How to Use CSS Variables for Animation

还有一个比较 modern 的方法是不要使用 transform, 而是直接写 scale, translate, rotate 等 CSS 属性 (但目前支持度还比较低)

keyCode 废弃, 请用 key

已经废弃很多年了, 之前 Angular 为了支持 IE 很多地方还是用 keyCode, 害得我老是混乱...

参考:

MDN – KeyboardEvent.keyCode Deprecated

MDN – KeyboardEvent.keyCode

现在改成使用 event.key 和 event.code。

.key 和 .code 是有区别的哦

第一个是 .key,第二个是 .code。

两者最大的区别是 code 是 unique 的,而 key 不是。

比如,回车键会有两个不同的 code -- "Enter" 和 "NumpadEnter"。

但回车键的 key 只有一个 "Enter"。

再比如 += 号

如果没有按 shift 点击这个键的话

key 是返回值是 "="

有按住 shift 的话,返回值是 "+"

但 code 就不一样,不管有没有按 shift,它都返回 "Equal",我们需要用 event.shiftKey 另外判断是否有按住 shift。

总结:code 比较精确,但相对的操作起来也比较繁琐,而 key 则简单一些。个人习惯优先使用 key 做判断,如果真的要非常精确 (比如要区分出 "NumpadEnter") 才会使用 code。

另外,在 dispatch KeyboardEvent 时,最好三个值都给,因为我们不知道监听的人会用哪一个做判断。

const keyboardEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'NumpadEnter',
keyCode: 13,
});
input.dispatchEvent(keyboardEvent)

Attribute 和 Property 的区别

参考: Stack Overflow – What is the difference between properties and attributes in HTML?

attribute 是声明在 element 上的. 游览器创建 element 对象后会把 attribute 的值过户到 property 里面.

它不总是一一对应的, 而且中间还可能会做点手脚, 比如 input type="abc" 最终 property type 会是 text. 因为 abc 不是合法的 type.

另外它们不总是同步的. 比如 input.id = 'new', 那么 attribute 也会变成 new. 但是 input.value = 'new', attribute 并不会变成 new.

所以要小心使用. 通常我们只用到 property. attribute 比较少会用到的.

Attribute value

三个点

1. value 只能是 string (e.g. '0', 'true' 都是 string)

<div class="target" abc="0" def="true"></div>
console.log(target.getAttribute("abc") === "0"); // true
console.log(target.getAttribute("def") === "true"); // true

2. 没有写等于, 表示 = empty string, 下面是等价的

<div class="target" abc></div>
<div class="target" abc=""></div>

3. 自定义的 attribute 不会映射到 property

console.log((target as any).abc); // undefined

4.没有 attribute 的情况下 element.getAttribute('abc') 返回 null.

Dataset

当我们想把资料记入到 element 上时就可以使用 dataset.

它和 custom attribute 差不多玩法, 只是 prefix 统一 data- 这样就不容易撞, 然后游览器会帮忙影射到 property dataset 里头

<div class="target" data-my-abc="0"></div>
console.log(target.hasAttribute("data-my-abc")); // true
console.log(target.getAttribute("data-my-abc") === "0"); // true
console.log(target.dataset.myAbc === "0"); // true

四点

1. 和 attribute 一样 value 只能是 string

2. dataset.myAbc 用的是 camelCase. 所以它是从 kebab-case 转成 camelCase 哦.

3. dataset.myAbc 如果没有 attribute 的话, 会返回 undefined (和 getAttribute 不同哦, 后者是返回 null)

4. set property dataset.myAbc = 'new value' 会同步到 attrbute 哦.

tabindex

div by default 是不可以被 focus 的.

button by default 就可以被 focus

要想 focus div, 我们可以写 tabindex = -1

这个表示可以 focus 但是不可以 tab

如果要可以 tab 那么是 tabindex = 0

tabindex 的号码可以用来表示 focusable 和 tabable

还有顺序功能. 游览器会从 1 开始 tab to next 然后越来越大, 数字重复就用 parent -> child -> sibling 的顺序 (所以对于一个区块只要分配一个值就可以了) . 最后才去 tabindex 0.

所以修改后的顺序就是

1,1,2,2,2,2,3,4,5,0,0,0.... 这种

display none 和 visibility: hidden 是不可以 focus 的. 然后和 element 被 remove 一样 focus 也是会跳去 body

当从 a element focus to b element 的时候, a 的 blur 会触发, 而这个时候 document.activeElement 是 body 哦.

document.click() 这种模拟 click 的话, 是不会 focus 的哦, 可以再调用 .focus() 就可以了

Focus & Blur

  1. focus 和 blur 事件是不会冒泡的。

    要冒泡可以改用 focusin 和 focusout。

    或者用 focus + capture 提前捕获做处理。

  2. auto focus body

    当 focused 的 element 被 remove from DOM,focus 会自动跳去 focus body。

  3. 触发顺序

    点击一个 button

    mousedown (body) -> focus (button) -> focusin -> mouseup -> click

    (body) 表示 document.activeElement 是 body

    再点击另一个 button

    mousedown (button1) -> blur (body) -> focusout (body) -> focus (button2) -> focusin -> mouseup -> click

    keyboard tab 的顺序也是一样的,把上面的 mousedown 换成 keydown 就可以了。

HTML 常用 encode

online convert tool: HTML Encode Online

&nbsp; 用来实现 multiple space.

new line 参考: Stack Overflow – Insert line break inside placeholder attribute of a textarea?

&quot; double quote "

关于 click, mouse, touch, pointer event

mouse

mouse 是针对滑鼠的 event

mousedown 点下去时触发

mouseup 点下去后放开时触发

mousemove 移动时触发(不管你有没有点下去,只要移动 mouse 就触发了)

touch

touch 是针对触屏的 event

touchstart 和 mousedown 类似,按下去时触发

touchend 和 mouseend 类似,放开时触发

touchmove 和 mousemove 类似,但是它一定是 touching 的时候触发的。(废话触屏一定是要触摸到先丫。。哈哈)

touchcancel 当 touch 出现问题时触发,比如太多手指了,屏幕不支持那么多,于是就会有一些被 cancel 掉。

click

click 在滑鼠和触屏都会触发

mousedown > mouseup > click

touchstart > touchend > click

以前触屏 click 会有一个 delay 300ms,但现在已经没有了。

pointer

mouse event 在触屏是不会触发的。

touch event 在滑鼠也是不会触发的。

但假如我们要支持多种设备,那么就需要监听 mouse 和 touch 两个,这样就很麻烦。

于是就有了 pointer。

pointer 事件在滑鼠和触屏都会触发。

比如 pointermove 在滑鼠等价于 mousemove,在触屏等价于 touchmove。

注意: 游览器的默认行为经常会影响到 pointermove。但不会影响到 touchmove。具体原因我懒的研究了。

pointermove 触发几下就会被中断。

想要掌控多一点的话,除了可以用 event.preventDefault() 之外,也可以在 html, body 加上 touch-action 属性。

body {
// touch-action: none;
touch-action: pinch-zoom pan-y pan-x;
}

none 表示,关闭所有游览器 touch 事件,完全由我们来操作。

pinch-zoom pan-y 指的是只允许游览器处理 pinch-zoom 和 pan-y 事件,其余事件都不要处理。(pinch-zoom 是放大,pan-y 是 scroll)

关于 hover 事件

JavaScript 没有 hover 事件,只有 mouseenter, mouseleave 或者 mouseover, mouseout。

mouseenter, mouseleave 对比 mouseover, mouseout

它们有点类似 focus 和 blur 对比 focusin 和 focusout 的关系。

mouseover, mouseout 有冒泡概念,监听父节点,当子节触发时也会收到。

mouseenter,mouseleave 没有冒泡概念,与子节点无关。

mousemove

mousemove 则一定有冒泡概念,没有没有冒泡的方法。

event.relatedTarget

relatedTarget 可以让我们知道 mouseenter 之前和 mouseleave 之后目标元素是什么。

比如从 divA mouseleave,然后 mouseenter 到 divB,在 divA mouseleave 时 event.relatedTarget 就是 divB,

同样的,在 divB mouseenter 时 event.relatedTarget 就是 divA。

DOM & BOM – 大杂烩的更多相关文章

  1. DOM&BOM笔记

    day01正课:1. DOM概述2. ***DOM树3. *查找 1. DOM概述: DHTML:动态网页技术的统称 DHTML=HTML+CSS+JS 鄙视题: HTML XHTML DHTML X ...

  2. 什么是BOM?,什么是DOM? BOM跟DOM之间的关系

    什么是BOM? BOM是browser object model的缩写,简称浏览器对象模型.是用来获取或设置浏览器的属性.行为,例如:新建窗口.获取屏幕分辨率.浏览器版本号等. 比如 alert(); ...

  3. js初级DOM&BOM知识点总结

    第一章 js的组成DOM BOM ECMAScript javaScript 是一种直译是脚本语言 js语言特点 .脚本编写语言 .基于对象的语言 .简单性 .动态性 .安全性 .跨平台性 C/S是C ...

  4. HTML与DOM BOM javascript

    1.什么是DOM? 简单说就是DOM规定了HTML,XML等的一些文档映射规范,使JavaScript可以根据这些规范来进行获取元素,在元素上进行各种操作,使得用户页面可以动态的变化,从而大大使页面的 ...

  5. JavaScript 之DOM&BOM

    重点来了 : BOM对象 window对象 : 所有浏览器都支持window对象. 概念上讲 : 一个html文档对应一个window对象. 功能上讲 : 控制浏览器窗口的. 使用上讲 : windo ...

  6. 关于dom&bom

    javascript 有三部分构成,ECMAScript,DOM和BOM,根据宿主(浏览器)的不同,具体的表现形式也不尽相同,ie和其他的浏览器风格迥异. 1. DOM 是 W3C的标准:[所有浏览器 ...

  7. JavaScript·DOM,BOM

    YI.DOM 1.创建DOM 2.删除DOM 3.文档碎片 文档碎片可以提高DOM操作性能(理论上) 文档碎片(类似于一个口袋,先将多个元素放在口袋里,放完之后,再将口袋放到最终要插入的元素中): d ...

  8. JavaScript DOM&BOM

    1.DOM含义 D: Document 文档 一份文档就是一棵节点树,每个节点都是一个对象O:Object 对象 JavaScript语言里对象可以分为三种类型: (1)用户定义的对象(user-de ...

  9. JavaScript的组成 | DOM/BOM

    往期回顾 在上一期的<JavaScript的组成 | 核心-ECMAScript >☜里,我们有说到JavaScript 是由三大部分组成,分别是:核心ECMAScript.文档对象模型- ...

  10. DOM&BOM

    文档对象模型(Document Object Model) 来源:文档对象模型(Document Object Model)的历史与20世纪90年代末Netscape Navigator和Micros ...

随机推荐

  1. 分析C语言程序

    1 #include <stdio.h> 2 int main() 3 { 4 puts("C语言"); 5 return 0; 6 } 函数的概念 C语言提供了很多功 ...

  2. Superviso可视化监控进程

    如果您需要同时运行多个 ThinkPHP 命令,可以在 Supervisor 中为每个命令创建一个单独的程序段.以下是示例配置,其中包含两个 ThinkPHP 命令:command1.php 和 co ...

  3. 机器学习:详解是否要使用端到端的深度学习?(Whether to use end-to-end learning?)

    详解是否要使用端到端的深度学习? 假设正在搭建一个机器学习系统,要决定是否使用端对端方法,来看看端到端深度学习的一些优缺点,这样就可以根据一些准则,判断的应用程序是否有希望使用端到端方法. 这里是应用 ...

  4. PHP数组遍历的四种方法

    PHP数组循环遍历的四种方式   [(重点)数组循环遍历的四种方式] 1,https://www.cnblogs.com/waj6511988/p/6927208.html 2,https://www ...

  5. 【ActiveJdbc】04

    一.乐观锁 作者po的乐观锁思想: http://en.wikipedia.org/wiki/Optimistic_concurrency_control 维基百科,墙了看不到 作者要求表字段必须存在 ...

  6. 【转载】 PID原理与参数调试

    原文地址: http://m.elecfans.com/article/1153309.html --------------------------------------------------- ...

  7. PyTorch显存机制分析

    参考: ======================================================= 在pytorch中有几个关于显存的关键词: 在pytorch中显存为缓存和变量分 ...

  8. aarch64架构CPU下Ubuntu系统环境源码编译pytorch-gpu-2.0.1版本

    准备事项: 1. pytorch源码下载: 源码的官方地址: https://github.com/pytorch/pytorch 但是这里我们不能简单的使用git clone命令下载,因为pytor ...

  9. python代码实现将PDF文件转为文本及其对应的音频

    代码地址: https://github.com/TiffinTech/python-pdf-audo ============================================ imp ...

  10. vscode 设置窗口菜单栏显示字体大小

    最近换了一块大些的显示屏,发现vscode的窗口字体有些小了,不是很方便,于是研究了一下如何设置vscode的窗口字体大小. 需要注意的是这里的设置是对窗口字体的而不是编辑器的字体. 1 .  通过主 ...