网页事件之约 0.2.0
此包为浏览器(及能供同义事列之宿主)中之豫言客立统一之候点:界面事、页面消息、定时、事件流、请求、编译、可见性、联机、历史与关闭,皆入同一先进先出之列;客以一阻塞之术等待网页事件取下一事,而后自行分派。又立订阅界面事件:客于订时预定“同步之断”(止默认、止传播、按键之律),宿主于原生回调中当场行之,盖豫言惟能事后处事,不能改此次事之默认。客依此包,诸术皆须备,阙一则拒装。
零点二点零较零点一点零惟增不减(六术之签名不变):订阅界面事件之策略癸象增三字段——选择器(惟于合某 CSS 选择器之元素生事并行止默认等同步之作)、带属性(事之载带合者之若干属性)、带矩形(载带合者之位置矩形);事之载相应增目标标识、属性、矩形三字段。又明以定时、事件流、请求、编译四类之事,各归其包:[网页定时](../网页定时/规范.文言.md)、[网页事件源](../网页事件源/规范.文言.md)、[网页请求](../网页请求/规范.文言.md)、[网页编译](../网页编译/规范.文言.md)。
事列
宿主为每客器立一列。每事有类,列中依至之序而排,宿主予每事一单调递增之序(自一始)。类取下列定集:
| 类 | 义 | 源 | | --- | --- | --- | | 界面 | 点击、输入、变更、提交、键盘、组字、焦点、滚动、dialog 之 cancel 与 close 等 DOM 事 | 本包订阅界面事件;网页界面包之旧式隐听 | | 消息 | 当前文档中“豫言”首之客消息 | 网页消息包 | | 定时 | 一次或周期定时期至 | 网页定时包 | | 事件流 | 服务端推送(SSE)之事:打开、成批之消息、错误 | 网页事件源包 | | 请求 | 非阻塞网页请求之成或败 | 网页请求包 | | 编译 | 本地编译之进(成批)与果 | 网页编译包 | | 可见性 | 页面可见之变(visibilitychange) | 本包订阅界面事件 | | 联机 | 联机之变(online、offline) | 本包订阅界面事件 | | 历史 | 历史之遍(popstate、hashchange) | 本包订阅界面事件 | | 关闭 | 宿主闭列 | 宿主 | | 宿主 | 低层宿主库之原始事(动画帧、空闲回调、工作线程、广播频道、套接字、公开操作、文树变动等) | 宿主库;客通常不用 |
事件流、请求、编译、定时四类之事,其字段与生事之时,各由其包定之;此包惟定其共用之列、序、背压与取法。
背压与弃
- 每类各有独立之列限,默认一千零二十四,可以设置网页事件队列上限调为一至六万五千五百三十六;宿主创建时亦可传初限。
- 某类之列满,则新事至而弃该类最旧之事,并计其数;他类不受影响。读取网页事件丢弃数返自宿主启以来所弃之总数,读取网页事件类型丢弃数返某类所弃之数。所弃之事遗序之缺口,客可由此知失而复同步。
- 「宿主」类为例外:为免失待答之公开操作,其满则拒新事而报错,不弃旧事(守旧宿主库之行)。
- 合并:高频之事(scroll、resize、mousemove、pointermove、touchmove、wheel、dragover、selectionchange)默认相并——同一订阅、同一目标标识之事若紧接列尾,则新事就地代旧事,不占新位,亦不计为弃。订阅策略之合并可易其默。
- 批事:事件流与编译之进度,宿主合为批事(详情中带批数组,见网页事件源、网页编译二包),并配背压以保不失;界面与消息之事不合批。
与旧术之系
网页界面包之等待界面事件与网页消息包之等待网页消息仍在,而改为依类自同一列取事:前者惟取界面类,后者惟取消息类,他类之事原样留于列,不被吞。同一客器可混用等待网页事件与此二旧术;混用则同一事惟被取一次,先呼者先得。底层宿主库之等待浏览器事件(原始癸象)仍取任意类之下一事,惟供旧客续行,新客不当与此包混用。
诸术
等待网页事件(无参,返文)
阻塞至列中有事,返下一事(不分类,依至之序)之癸象文。宿主闭后,每呼皆返 {"类型":"关闭","订阅号":0,"名称":"关闭"}。此术可挂起,客不得由此得原生文树之物。
事之癸象为对象,含下列字段;各类之事惟填相关之字段,余者省之:
| 字段 | 类型 | 义 |
| --- | --- | --- |
| 类型 | 文 | 上表之一,恒有 |
| 序 | 整数 | 宿主所予之序,恒有(关闭之事除外) |
| 订阅号 | 整数 | 生事之订阅号;旧式隐听与宿主自生之事为零,定时之事为定时号 |
| 标识 | 文 | 触发元素之标识,无则空文(界面类恒有) |
| 名称 | 文 | 事名(click、keydown、visibilitychange 等;消息为消息名;定时为“定时”;关闭为“关闭”) |
| 操作键 | 文 | 触发元素及其祖先(止于订阅之目标,含目标自身)中最近之 data-yy 属性值;无则省 |
| 目标标识 | 文 | 惟订阅策略带选择器时现:原始事目标之标识,无则空文(是时“标识”乃合者之标识) |
| 属性 | 对象 | 惟订阅策略带带属性时现:合者所有之、所请之属性(名至文);无者省之,值逾四千零九十六 UTF-16 码元者省之 |
| 矩形 | 对象 | 惟订阅策略带带矩形时现:合者之 getBoundingClientRect(),取整后之 {"左":整数,"上":整数,"右":整数,"下":整数}(视口坐标) |
| 值 | 文 | 目标为 input、textarea、select 时之现值;值逾六万五千五百三十六 UTF-16 码元则省而带 "值过长":true(当改用网页界面之读取节点值);口令之框(type=password)与 scroll、mousemove 等无值之事不带 |
| 选中 | 爻 | 目标为 checkbox 或 radio 时之 checked(旧式隐听之事恒带值与选中) |
| 键 代码 | 文 | 键盘事之 key 与 code |
| ctrl meta alt shift | 爻 | 键盘与鼠标事之修饰键 |
| 重复 | 爻 | 键盘事之 repeat |
| 组字中 | 爻 | 键盘事之 isComposing;input 事之 isComposing;compositionstart、compositionupdate 为真,compositionend 为假 |
| 按钮 | 整数 | 鼠标事之 button |
| 已阻止默认 | 爻 | 宿主于原生回调中已否对此事施 preventDefault(界面类恒有) |
| 可取消 | 爻 | 仅当订阅欲阻止默认而事不可取消时出现,恒为假 |
| 详情 | 任意癸象 | 见下表 |
| 详情错误 | 文 | 惟消息类:详情逾一 MiB 或非有效癸象,则详情为 null 而带此字段 |
详情之形:
| 事 | 详情 |
| --- | --- |
| input | {"输入类型":inputType,"数据":data 或 null} |
| compositionstart、compositionupdate、compositionend | {"数据":data} |
| focus blur focusin focusout | {"关联标识":relatedTarget 之标识或空文} |
| scroll | {"顶":整数,"总高":整数,"可视高":整数}(目标为文档则取滚动元素) |
| dialog 之 cancel、close | {"返回值":returnValue} |
| 可见性 | {"可见":爻} |
| 联机 | {"联机":爻} |
| 历史之 popstate | {"网址":现址,"状态":state 之癸象化或 null}(state 不可癸象化或逾六十四 KiB 则 null) |
| 历史之 hashchange | {"旧网址":文,"新网址":文} |
| 消息 | 消息之癸象详情 |
| 定时 | {"种类":"一次"或"重复","标记":文,"时刻":整数} |
| 宿主 | 原始事之对象 |
订阅界面事件(目标、事名、策略,返订阅号整数)
参数依次为目标、事名、策略之癸象文,返订阅号(正整数)。
- 目标:页中既有元素之标识,或保留字“文档”“窗口”(故标识为“文档”或“窗口”之元素不可为目标)。目标元素须于订时已在;元素后被替去,则订阅随之失效。
- 事名:ASCII,
[A-Za-z][A-Za-z0-9_.:-]*,至多六十四字。visibilitychange 生可见性类,online、offline 生联机类,popstate、hashchange 生历史类,余生界面类。“豫言”首之消息名不可于此订,当用网页消息包。 - 委托:目标之下任一后代所触之同名事皆生事,标识为触发元素之标识(无则空文),操作键为最近带 data-yy 之祖先(含自身)之值。故动态所生之钮不必有标识,但带 data-yy 即可。不冒泡之事(focus、blur、scroll、close、cancel、load、error、toggle、invalid、mouseenter、mouseleave、pointerenter、pointerleave)宿主一律于捕获相听之,亦可委托。
- 同目标同事名可订多次,每次得异订阅号,各自生事。
- 订阅总数至多二百五十六。目标阙、事名或策略不合、数逾限,则发豫言事故(客可捕之);败之订阅不留痕迹。
策略为对象,诸字段皆可省;有未识之字段或类型不合,一律报错,免笔误默被忽略:
| 字段 | 类型 | 义 |
| --- | --- | --- |
| 阻止默认 | 爻 | 于原生回调中施 preventDefault()(事可取消时);不得与被动同为真 |
| 停止传播 | 爻 | 施 stopPropagation() |
| 停止同处 | 爻 | 施 stopImmediatePropagation()(同目标后续之听者亦不得见) |
| 捕获 | 爻 | 于捕获相听(不冒泡之事恒捕获) |
| 被动 | 爻 | 被动之听;scroll、wheel、touchstart、touchmove 无上三动作时默认被动 |
| 合并 | 爻 | 是否并紧邻之同源事,默认惟高频事为真 |
| 一次 | 爻 | 首事之后自撤订阅(该事仍送达) |
| 仅命中 | 爻 | 有键规则时,惟命中之事入列 |
| 键规则 | 数组 | 至多三十二条,见下;惟施于 keydown、keyup、keypress |
| 选择器 | 文 | CSS 选择器(选择器之列亦可),至多五百一十二字,订时验之,不合则报错;见下“选择器之滤” |
| 排除选择器 | 文 | CSS 选择器,至多五百一十二字,订时验之;原始事目标(含自身)落于合之之元素内,则此次事被忽略:既不投,亦不行任何同步之作;见下“选择器之滤” |
| 带属性 | 数组 | 至多八个属性名([a-z][a-z0-9:_-]*,至多六十四字,不得以 on 首,不得为 style、srcdoc),不得重;事之载带属性 |
| 带矩形 | 爻 | 真则事之载带矩形 |
无键规则则阻止默认、停止传播、停止同处施于该订阅之每事。有键规则则动作惟于某规则命中时行:三动作字段一不给者,命中即阻止默认(承宿主库“键盘阻止默认”之义);给其中任一,则惟行所给之动作。
键规则为对象,同条诸件为“且”,诸条为“或”;字段:
| 字段 | 义 |
| --- | --- |
| 键 | 与 event.key 同;单字母不分大小写(l 亦合 L)。键与代码至少给一 |
| 代码 | 与 event.code 同 |
| ctrl meta alt shift | 布尔;省则不与匹配,给则须与事同 |
| 含组字 | 布尔;默认假:输入法组字之间(isComposing 或 keyCode 为 229)之键不命中,免坏输入法;真则组字之间亦合 |
| 仅选区为空 | 布尔;真则输入框内或页上有选中之文时不命中(如惟无选区时拦 Ctrl+C) |
| 仅目标标识 | 文;事之目标须为该标识之元素本身或其后代 |
| 仅当属性 | 对象 {"标识":标识,"属性":名,"值":文或 null}:该元素之属性须等于所给值;值为 null 表该属性不存在;hidden、disabled、readonly、open、checked、selected 等布尔属性以 "true"(在)与 "false"(不在)表之 |
约中所重:诸同步之件皆写于订时;键规则、止默认与止传播于宿主之原生事回调中当场判而行之,豫言得事时,此次事之默认早已定,事后不能改。欲依运行时之状而变拦截,客当撤订而重订,或用仅当属性,使宿主读页中属性之现值。
浏览器之实:dialog 之 cancel,浏览器惟于页已得用户激活时许取消;否则事不可取消,preventDefault 无效,是时事之载带可取消为假、已阻止默认为假。
选择器之滤(零点二点零):策略带选择器,则宿主于原生回调中先行“委托之合”,而后论余事:
- 取事之原始目标(若为文本节点则取其父元素);目标非元素(如 scroll 之目标为文档)则不合。
- 取“最近合者”m = 自原始目标向上(含自身)第一个合选择器之元素,且必在订阅之界内(订阅目标为元素,则 m 须为该元素或其后代;订阅目标为“文档”或“窗口”,则不限)。
- 无 m:此次事既不投,亦不行止默认、止传播、止同处——原生之事不受此订阅所扰。
- 有 m:照常察键规则而行其作;事之载中凡涉“目标元素”之字段——标识、操作键(自 m 向上求 data-yy,止于订阅之界)、值、选中、属性、矩形——皆取 m(focus 类事详情中之关联标识,仍为 relatedTarget 之标识,不受影响);原始目标之标识,由目标标识报之。
典型之用:订阅界面事件(“文档”,“click”,{"捕获":true,"选择器":".豫菜单, .豫导航 [data-lang], a[href]","阻止默认":true,"停止同处":true,"带属性":["href","data-lang"]})——惟拦导航之链与语言之钮,得所点之链之 href,页上他点击丝毫不受扰;订阅界面事件(“文档”,“mouseover”,{"选择器":".类型引用[title]","带属性":["title"],"带矩形":true})——惟悬于带标题之引用乃生事,并带回标题与位置,以置浮层。选择器之语法误,订时即报;选择器与键规则可并用(先选择器,后键规则)。
排除选择器(零点二点零):策略带排除选择器,则先察原始目标(文本节点取其父元素):其自身或某祖先合此选择器(closest,不限订阅之界),则此次事被忽略,而后方行上文选择器之合。用以表“点于某域之外”——如收起下拉之面板:订阅界面事件(“文档”,“click”,{"排除选择器":".文件目录"}),惟点落于 .文件目录 之外乃生事。(选择器所用者为“最近合者”,不能表“之外”::not(...) 会上溯而合 body。)
无选择器,则带属性、带矩形施于原始目标本身(目标为元素时)。带属性所读乃属性(getAttribute,原样之文)而非 DOM 之属性;type=password 之输入框上名 value 之属性不带出。
取消订阅界面事件(订阅号)
撤订阅,并去其未取之事。订阅号无效或已撤则无事。已被等待网页事件取去之事不受影响。
读取网页事件丢弃数、读取网页事件类型丢弃数
见“背压与弃”。类名不在上表则后者返零。
设置网页事件队列上限(类、上限)
定某类之列限,一至六万五千五百三十六;类名不在上表或限越界则发事故。调低其限,则多出之旧事于该类下一新事至时被弃而计之。
限额与败之类
| 项 | 限 | | --- | --- | | 列限(每类) | 默认一千零二十四,可配一至六万五千五百三十六 | | 订阅 | 界面订阅至多二百五十六,消息订阅至多一百二十八(见网页消息之约) | | 键规则之条数 | 至多三十二 | | 事名之长 | 至多六十四字 | | 事中之值 | 至多六万五千五百三十六 UTF-16 码元,逾则省而标之 | | 消息详情 | 至多一 MiB |
败之类:违约之调用(目标阙、事名或策略不合、订阅逾限、列限越界、类名无效)发豫言事故,辞为华言;列满非败,依上文弃而计之;宿主闭非败,等待返“关闭”之事。
跨宿主之一致
- 事依宿主所收之序而排,同一订阅号之事保其先后。
- 序于宿主实例内单调而增;弃惟发于列首(最旧)之向,不乱余事之序。
- 键规则之匹配、操作键之搜与委托之规须合此文;字段之缺省与省略须一致,客当视缺失之字段为“不适用”。
- 不能供同步拦截之宿主不得自称具此包。
一致性之例
- 订“容器”之 click;点击容器内无标识、带
data-yy="打开:7"之钮中之 span;等待网页事件返:类型为“界面”、标识为空、操作键为打开:7。 - 订“文档”之 keydown,策略
{"键规则":[{"键":"Enter","shift":false}]};派发 Enter,则 dispatchEvent 一返,事之 defaultPrevented 即真;派发 Shift+Enter 则假;二者之事皆送达,已阻止默认依次为真、假。 - 界面列限设为五,连点二十次而不取事:列中留最新五事,读取网页事件丢弃数为十五,所留事之序相连而大于十五。
- 客正阻塞于等待界面事件时,一页面消息至:消息留于列,其后等待网页消息(或等待网页事件)取之;界面事至,则等待界面事件返之。
- 订“文档”之 click,策略
{"捕获":true,"选择器":"a[href]","阻止默认":true,"带属性":["href"]};点击<a href="/x"><span>字</span></a>中之 span:事至,标识为 a 之标识(可空)、目标标识为 span 之标识、属性为{"href":"/x"},且 dispatchEvent 一返,defaultPrevented 即真;点页上寻常之钮:无事,defaultPrevented 为假。 - 订阅策略
{"选择器":"button["}:订时发事故,宿主不留任何监听。 - 订“文档”之 click,策略
{"排除选择器":".文件目录"}:点.文件目录内之任一后代无事;点页上他处有事(标识等仍取原始目标)。
界
此包不定:网络请求、定时器之造与撤、SSE 之联、本地编译(分属网页请求、网页定时、网页事件源、网页编译诸包,惟借此包之事类);不供跨窗、跨工之事;不供“事后止默认”;不向客露原生事对象或文树之柄;不保高频之事(滚动、指针移动)逐一送达(默认并之);触屏、拖放、剪贴之 paste 之载字段,留待后版。