#js #dom #parsing 提问: DOM 里如何拿到 <h1>~<h6> 标题树?
假设所有 heading 都在
和解析 #Python, yaml 的缩进实质相同,我给两种方法(递归层宽、Int栈循环)
输出类似
算法对输入数据的抽象有点问题,关键点两个:
1. 何时解析一个子节点(上面 "## b")
2. 获取头部深度及建设每层
和 Python 解析的主要区别在于:
1. 在解析非 <hN> 项时不需要取其深度
2. 没有 : 后无换行的“单行简写”(可选 : layout) 的说法
但是我们仍然会写兼容 Python 缩进解析的代码,用抽象层掩盖 DOM 的对非 <hN> 元素深度(因无此概念)的不处理。
畸形的基础抽象:
0. 实现最大的要点是:仅需过一遍,但内部元素皆可能“跌破”两层嵌套,需要级联化处理层结束的逻辑、终末项的实际属从层;
此外第一层是特殊的——它无需 heading 开头,但内部模式和前者一致。
1. 建设每层子树结构不需要提供函数值,统一存储形式允许完后重赋值即可
2. 可以提供
递归层宽: #js #code
(补充:算法我都写出来了,调试了很久,待会贴链接)
Int栈算法:
其实就是比较骚的循环显式栈化重写
本身也不是什么复杂的算法(真正“复杂”的在于如何设计高性能、易组合的复用架构),分词器层面处理就只能用栈,然后业界主流实现是转化成 internal 的 END 词条然后交给 yacc 一样的状态机,把嵌套结构解析第二遍。
老ParserKt 的实现是 LayoutPattern (不如 fastparse 的
以上
假设所有 heading 都在
document.body.children
里和解析 #Python, yaml 的缩进实质相同,我给两种方法(递归层宽、Int栈循环)
输出类似
["# a", e2, e3, ["## b", ee2], e5]
这种算法对输入数据的抽象有点问题,关键点两个:
1. 何时解析一个子节点(上面 "## b")
2. 获取头部深度及建设每层
[head, *items]
的函数和 Python 解析的主要区别在于:
1. 在解析非 <hN> 项时不需要取其深度
2. 没有 : 后无换行的“单行简写”(可选 : layout) 的说法
但是我们仍然会写兼容 Python 缩进解析的代码,用抽象层掩盖 DOM 的对非 <hN> 元素深度(因无此概念)的不处理。
畸形的基础抽象:
var lastHDepth = 0/*当前文段层深度*/;实现的一些细节:
const RE_HTAG = /H(\d+)/g
, isHeading=(e) => RE_HTAG.test(e.tagName)
, getHeadingDepth=(e) => { var n=parseInt(RE_HTAG.exec(e.tagName)[1]); lastHDepth=n+1; return n; }
, getElementDepth=(e) => lastHDepth;
0. 实现最大的要点是:仅需过一遍,但内部元素皆可能“跌破”两层嵌套,需要级联化处理层结束的逻辑、终末项的实际属从层;
此外第一层是特殊的——它无需 heading 开头,但内部模式和前者一致。
1. 建设每层子树结构不需要提供函数值,统一存储形式允许完后重赋值即可
2. 可以提供
onXXX()
函数值检查缩进深度步进是否合法递归层宽: #js #code
(补充:算法我都写出来了,调试了很久,待会贴链接)
Int栈算法:
其实就是比较骚的循环显式栈化重写
本身也不是什么复杂的算法(真正“复杂”的在于如何设计高性能、易组合的复用架构),分词器层面处理就只能用栈,然后业界主流实现是转化成 internal 的 END 词条然后交给 yacc 一样的状态机,把嵌套结构解析第二遍。
老ParserKt 的实现是 LayoutPattern (不如 fastparse 的
" ".rep(indent+1).map(_.len).flatMapX(new Layout(i).factor.rep(1, sep = ("\n"+" "*i))
)
方便),写第一遍看起来易用性还不好;当然,这是个泛用 #algorithm ,功能根本不止解析人类易读嵌套结构。以上
GitHub
ParserKt/ParserKt
Naive one-pass recursive descent, scannerless parser framework for Kotlin - ParserKt/ParserKt
duangsuse::Echo
#js #web #DontKnow DOM 小提示! 😘 1. with(e.parentNode){ insertBefore(e1, e); removeChild(e) }可以用 e.replaceWith(e1) 替换 2. e.remove() 等于 e.parentNode.removeChild(e) 3. children, firstChild, prevElementSibling 不会获取到 text node 而 childNodes, parentNode, nextSibling…
#html #dom #API #doc #dontknow
https://duangsuse-valid-projects.github.io/Share/HTMLs/school/ 🌝新写了个弹球动画,我真是 HIGH 到不行,赛高哩HIGH哒≈
https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats
还有之前的剪贴板我也查了
[在线Html编辑器粘贴过滤技术详解(一)_weixin_33910460的博客-CSDN博客](https://blog.csdn.net/weixin_33910460/article/details/89910701)
[JavaScript如何获取粘贴事件的剪贴板数据(跨浏览器)? - 问答 - 云+社区 - 腾讯云](https://cloud.tencent.com/developer/ask/186776)
另外在找的时候我发现一个 1k star 的 JS DOM 变动静态库,思想挺有意思的,不用 MutationObserver 和 NodeIterator,TreeWalker (
https://github.com/muicss/sentineljs
然并暖,到 DevTools events/debugger 面板看看 DOM Events 的归类就能发现有一大堆 DOM 变动的事件支持嵌套次序🌚
稍有常识的人不难看出,如果我们的 API 继续前进,类似的魔法还能有价值吗?
https://duangsuse-valid-projects.github.io/Share/HTMLs/school/ 🌝新写了个弹球动画,我真是 HIGH 到不行,赛高哩HIGH哒≈
https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats
还有之前的剪贴板我也查了
document.querySelectorAll("[contenteditable]").forEach(e=>e.onpaste=(ev)=>{ e.execCommand("paste",false,ev.clipboardData.getData("text/plain")); })
[在线Html编辑器粘贴过滤技术详解(一)_weixin_33910460的博客-CSDN博客](https://blog.csdn.net/weixin_33910460/article/details/89910701)
[JavaScript如何获取粘贴事件的剪贴板数据(跨浏览器)? - 问答 - 云+社区 - 腾讯云](https://cloud.tencent.com/developer/ask/186776)
另外在找的时候我发现一个 1k star 的 JS DOM 变动静态库,思想挺有意思的,不用 MutationObserver 和 NodeIterator,TreeWalker (
document.createXXX(e).nextNode()
) 什么的,而是利用了自定义 @keyframes
的事件 animationStart 。 API 类似 inotify , on(selector,op) 这样https://github.com/muicss/sentineljs
然并暖,到 DevTools events/debugger 面板看看 DOM Events 的归类就能发现有一大堆 DOM 变动的事件支持嵌套次序🌚
$0.addEventListener("DOMSubtreeModified",console.log); $0.getRootNode().body.setAttribute("contenteditable","")
Share
School
🐕 duangsuse’s shared files(e.g. productive software projects, documents)
#日常精神分裂 #DOM #game #js
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint 不一样-_-|| 这次要手写 2D 游戏引擎碰撞检测部分,除了基础的加速度和碰撞方向检测;老实说都是数理密集算法
A: (不考虑与边界矩形的碰撞)我想到了三种方法做纯圆球的碰撞检测,首先是遍历球表算距离……
B: 没用!这样相当于每个配对你都要检测一次,要知道这个游戏后期会有 20 来个的,为保证不穿模,每一帧都计算?!
A: 那我参考整体动量,间隔毫秒或者帧号判断呢?
B: 都说了会穿模了
A: 第二种方法,参考物体的运动方向延长线,看交点,每对 ab,ba 缓存下只算一次
这种方法也可以用来优化一个物体不动的碰撞,或可预判碰撞发生时间,有变再 cancel 重算
B: 好啊,你怎么取射线和圆的交集?
A: 第三种方法,其实理论上只有画特效需要用到 canvas ,其它的尽量用 DOM 元素,就可以利用浏览器的既有算法,我知道有个 Element.nearest(selector) ,这样每对物体检测一次 d(p1,p2)<(r1+r2) 就够了;对边框是特例,只要对所有物体增加 x,y in clientRect.innerDist(r) 就可以了
B: 是个可取的方法,你不会用框架吗,整个游戏只有 ellipse collision 和 gravity 、force ,再简单点就只有放球和贴图,碰撞只是换贴图+增长,球与上框碰撞结束而已。
A: 嫌大了。 DOM 已经足够强大,何须更多修饰? 高射炮打蚊子
B: 好了,谈谈复用问题吧,假设你不用框架,却又写了个用途单一的正圆碰撞检测算法…… 我猜测应用部分是这样的:
gameOver() 的条件也可以换成在放球和最近球的碰撞检测 避免每个都判断
A: 我相信关于代码复用和框架组织,咱会有办法的!
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint 不一样-_-|| 这次要手写 2D 游戏引擎碰撞检测部分,除了基础的加速度和碰撞方向检测;老实说都是数理密集算法
A: (不考虑与边界矩形的碰撞)我想到了三种方法做纯圆球的碰撞检测,首先是遍历球表算距离……
B: 没用!这样相当于每个配对你都要检测一次,要知道这个游戏后期会有 20 来个的,为保证不穿模,每一帧都计算?!
A: 那我参考整体动量,间隔毫秒或者帧号判断呢?
B: 都说了会穿模了
A: 第二种方法,参考物体的运动方向延长线,看交点,每对 ab,ba 缓存下只算一次
这种方法也可以用来优化一个物体不动的碰撞,或可预判碰撞发生时间,有变再 cancel 重算
B: 好啊,你怎么取射线和圆的交集?
A: 第三种方法,其实理论上只有画特效需要用到 canvas ,其它的尽量用 DOM 元素,就可以利用浏览器的既有算法,我知道有个 Element.nearest(selector) ,这样每对物体检测一次 d(p1,p2)<(r1+r2) 就够了;对边框是特例,只要对所有物体增加 x,y in clientRect.innerDist(r) 就可以了
B: 是个可取的方法,你不会用框架吗,整个游戏只有 ellipse collision 和 gravity 、force ,再简单点就只有放球和贴图,碰撞只是换贴图+增长,球与上框碰撞结束而已。
A: 嫌大了。 DOM 已经足够强大,何须更多修饰? 高射炮打蚊子
B: 好了,谈谈复用问题吧,假设你不用框架,却又写了个用途单一的正圆碰撞检测算法…… 我猜测应用部分是这样的:
gameStart() = rateLimit(waitPutBall, 4000)
onEach(ball)
limitInRect(world.rect.innerMinus(ball.r), ball) // 模拟边框碰撞体
if ball.p.y<yTopline: gameOver()
waitPutBall()
ball = newBall(randPick(cfg.sizes), randPick(cfg.colors))
ball.y = yTopline; ball.g = cfg.weight
onmousemove = ev=> ball.x=ev.x
onmousedown = ()=> world.attach(ball) // 球开始下落
onCollide(a,b)
a.r += b.r
a.onChange()
b.remove()
gameOver() 的条件也可以换成在放球和最近球的碰撞检测 避免每个都判断
A: 我相信关于代码复用和框架组织,咱会有办法的!
#statement #functional #js #GUI #dom
再说 Reactive... 等等这不是 Rx 类框架的招牌吗٩(๑`н´๑)۶ 看来 -ive 的词性都容易后宫起火啊草。
React 用 functional MEMO 提升控件更新性能根本就是弱智措施, memo 即备忘录,用 hash 表实现函数输入输出对应的缓存,这样对类似 Text 的控件,同输入多次调用不产生额外计算和内存开销,应用在树 render() 上时相当于自动实现 shouldComponentUpdate() ,尽量复用旧的渲染结果,对树遍历减少重建操作量,相当于仅重建了真正变更的控件。
经典版暴露 shouldUpdate 已经很没水平了,说好的面向 state 编程呢?在我看来这个 Reactive 所做的就是「把所有控件的所有变量暴露到一个 state 里方便读写操作」,那么凭什么程序员要操心什么 update 啊 memo 啊,记得很像 还有 SMUV(state,message,update-event,view)模型,实际上根本不能便利地 handle 多少东西,就是个秀儿。
当然,其实真正的 relational 编程也是这样,关系式 state/var/eq/both/either 靠 enumerate&filter 可以解出 x+1=2 这样的线性方程,甚至能得出 a+b=9 的所有可能性,只是需要 interleave([a,b]) 两个变量先后递增构造 state 迭代,然后 unify 一下同步恒等关系(双向版变量引用)而已
可是这和 DOM 有多大关系?比如我有个
其实渲染 Main 的时候连给子控件注入其路径都不需要!也不需要专门分析 DOM diff 的哪个 tag 哪个 attr 还是 text ,直接拿住自己的 HTMLElement 的引用就够完成全部 update 了,所以说搞那么复杂?
要是想兼容 haml 或者 E4X 内联 XML ,直接做个中部翻译成 el 调用就行,反正 DOM 元素动态创建最好是 createElement ,逃不开运行时开销。
想实现控件属性事件到 update 代码的方法很简单,因为 js ref(a.prop) 并不会传入 a 相关的信息,编译期把 op(ref(a.prop)) 变成 refAddRel(a,"prop",v=>op(v)) 就可以了,这种方法换成处理全部代码,引用处 a.prop=x 自动更新就变成上面那个 框架S 的实现方法,接口上是兼容的,只不过 refAddRel(o,k,op) 从 defineProperty 变成编译期打监听表。
变形方法很简单,walk 到 FCall 节点记作基点,如果是 op(ref(o.prop)) 就把基点变成 refAddRel 的调用,如果是 ref(v) 这种不知道 receiver 的情况就请换 Array [v] 报错,反正框架函数可以随便加没必要特别支持 a=ref() 这些语法,兼容的少,反而更优雅。
再说 Reactive... 等等这不是 Rx 类框架的招牌吗٩(๑`н´๑)۶ 看来 -ive 的词性都容易后宫起火啊草。
React 用 functional MEMO 提升控件更新性能根本就是弱智措施, memo 即备忘录,用 hash 表实现函数输入输出对应的缓存,这样对类似 Text 的控件,同输入多次调用不产生额外计算和内存开销,应用在树 render() 上时相当于自动实现 shouldComponentUpdate() ,尽量复用旧的渲染结果,对树遍历减少重建操作量,相当于仅重建了真正变更的控件。
经典版暴露 shouldUpdate 已经很没水平了,说好的面向 state 编程呢?在我看来这个 Reactive 所做的就是「把所有控件的所有变量暴露到一个 state 里方便读写操作」,那么凭什么程序员要操心什么 update 啊 memo 啊,记得很像 还有 SMUV(state,message,update-event,view)模型,实际上根本不能便利地 handle 多少东西,就是个秀儿。
当然,其实真正的 relational 编程也是这样,关系式 state/var/eq/both/either 靠 enumerate&filter 可以解出 x+1=2 这样的线性方程,甚至能得出 a+b=9 的所有可能性,只是需要 interleave([a,b]) 两个变量先后递增构造 state 迭代,然后 unify 一下同步恒等关系(双向版变量引用)而已
可是这和 DOM 有多大关系?比如我有个
class Main: DUI() { fun view() = el("il", withNone, Counter(0)) }
class Counter(var n): DUI() {
fun view() = elDiv(withNone, elText(ref(this.n)))
fun inc() { n+=1 }
}
其实渲染 Main 的时候连给子控件注入其路径都不需要!也不需要专门分析 DOM diff 的哪个 tag 哪个 attr 还是 text ,直接拿住自己的 HTMLElement 的引用就够完成全部 update 了,所以说搞那么复杂?
要是想兼容 haml 或者 E4X 内联 XML ,直接做个中部翻译成 el 调用就行,反正 DOM 元素动态创建最好是 createElement ,逃不开运行时开销。
想实现控件属性事件到 update 代码的方法很简单,因为 js ref(a.prop) 并不会传入 a 相关的信息,编译期把 op(ref(a.prop)) 变成 refAddRel(a,"prop",v=>op(v)) 就可以了,这种方法换成处理全部代码,引用处 a.prop=x 自动更新就变成上面那个 框架S 的实现方法,接口上是兼容的,只不过 refAddRel(o,k,op) 从 defineProperty 变成编译期打监听表。
变形方法很简单,walk 到 FCall 节点记作基点,如果是 op(ref(o.prop)) 就把基点变成 refAddRel 的调用,如果是 ref(v) 这种不知道 receiver 的情况就请换 Array [v] 报错,反正框架函数可以随便加没必要特别支持 a=ref() 这些语法,兼容的少,反而更优雅。
#project https://tttttt.me/dsuse/16954
https://tttttt.me/dsuse/16970 https://tttttt.me/dsuse/16975 elm-lang.org
🤔咱先去写个关系式 state ,再去从 infsw 写起吧…… 不对,可以先去写个 line,insert,百叶窗的文本动画
https://tttttt.me/dsuse/16970 https://tttttt.me/dsuse/16975 elm-lang.org
🤔咱先去写个关系式 state ,再去从 infsw 写起吧…… 不对,可以先去写个 line,insert,百叶窗的文本动画
Telegram
duangsuse::Echo
#日常精神分裂 #DOM #game #js
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint…
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint…
#statement #dev #design 编程者像舞蹈编排者一样,就是什么时候做什么事情而已。 什么时候是指外部输入和环境变化带来的事件入口及传播;什么事情是指对数据的处理与判断。 编程就是总结物上之事的客观规律并加以主观控制,实际一步就是美感地设计代码/项目的结构和利用下层接口。程序的设计和科学一样,只要习惯了所处的这个死板的「世界」,明白目标的流程和时序/存储关键点、灵活复用代码,无论看起来多么复杂或强大的程序都能按部就班地设计出来!
#functional 程序序列 生成/归纳 ,比如对第一次/第一项的特殊处理或重复语句
数据序列 操作/绑定 恒等关系
嘛,很多方法,我能说出它在编程领域的技巧名,但却不知道它具体是什么,都是经验,甚至赋技巧模式以名字本身也是经验
#math 编程相对于数学最好的一点就是懂把重复的规律提取为常见易懂的子程序
Rect 要是带算法可视化的副作用就更好🤔 #cg #statics 觉得建模易扩展十分有必要! #DOM Rect 还带 x,y 的就很灵性,其实是 Area 吧
#net 想想写局域网聊天测试,tcp recvfrom 和 sendto 两 buf ... 不,其实是两方的 recv buf ,没有主动方或从动方
#relational 关系式, 不是我读一次你,而是我与你相关,双向的关系 (双边 setter )
不过这个不算真关系式…… 但关系式的内心不止是求一个满足等式的变量表 state , React 这些自动更新的、甚至数据库查询都算关系式。
#game #python 想弄个真心话大冒险,当然游戏逻辑本身太简单了,作为 web 应用应该要 9patch 背景图(工具?)和动画什么的
fs:scan/read/save 9patch async-quest-loop xhr-gists&files expand[a,b] listanim
#windows 同学居然做出一个 winform 还是啥的 C++ form+table 『疫情登记表』…… 回头也想做一个
#web #js push&update, form Date, table sort/filter/select, export, grid-opto
#functional 程序序列 生成/归纳 ,比如对第一次/第一项的特殊处理或重复语句
数据序列 操作/绑定 恒等关系
嘛,很多方法,我能说出它在编程领域的技巧名,但却不知道它具体是什么,都是经验,甚至赋技巧模式以名字本身也是经验
#math 编程相对于数学最好的一点就是懂把重复的规律提取为常见易懂的子程序
r.stepCount(nStep).zipWithNext().reduceWithLeft(y) { (acc,x,yL)
Rect(x,0,x+r.step,avg(yL,y(x))).area
}
(求和曲边梯形面积 定积分)Rect 要是带算法可视化的副作用就更好🤔 #cg #statics 觉得建模易扩展十分有必要! #DOM Rect 还带 x,y 的就很灵性,其实是 Area 吧
#net 想想写局域网聊天测试,tcp recvfrom 和 sendto 两 buf ... 不,其实是两方的 recv buf ,没有主动方或从动方
#relational 关系式, 不是我读一次你,而是我与你相关,双向的关系 (双边 setter )
不过这个不算真关系式…… 但关系式的内心不止是求一个满足等式的变量表 state , React 这些自动更新的、甚至数据库查询都算关系式。
#game #python 想弄个真心话大冒险,当然游戏逻辑本身太简单了,作为 web 应用应该要 9patch 背景图(工具?)和动画什么的
fs:scan/read/save 9patch async-quest-loop xhr-gists&files expand[a,b] listanim
datasets=dict(enumerate(basename(fp,".txt") for fp in listdir()))
selBanner=" ".join(f"{k}{v}" for k,v in datasets.items())
while(1) print(randPick(datasets[input(selBanner)]))
#windows 同学居然做出一个 winform 还是啥的 C++ form+table 『疫情登记表』…… 回头也想做一个
#web #js push&update, form Date, table sort/filter/select, export, grid-opto
#bilibili
#dom http/s 等的 origin 策略对新worker api影响挺大的
http://mmm.page 啊,拖放设计分享,年轻人就是好啊
https://github.com/krlvm/AcrylicMenus #win #hack 透明菜单
https://tttttt.me/dsuse/17169 伪 Mac 👇2
#dom http/s 等的 origin 策略对新worker api影响挺大的
http://mmm.page 啊,拖放设计分享,年轻人就是好啊
https://github.com/krlvm/AcrylicMenus #win #hack 透明菜单
https://tttttt.me/dsuse/17169 伪 Mac 👇2
mmm.page
mmm.page — Your Corner of the Internet
Websites don't have to be so cookie cutter. Make a website that feels uniquely you in under five minutes.
#dom h t m l 开 发(大嘘
xslt设计还不如 json schema
世界之大无奇不有,xml 数据库🌚太好了 css你支持下 graphQL 就没用啦
比起XPath的API,还是 jsonpath语法上也,更得人心吧
xslt设计还不如 json schema
世界之大无奇不有,xml 数据库🌚太好了 css你支持下 graphQL 就没用啦
比起XPath的API,还是 jsonpath语法上也,更得人心吧