popup定位引擎popper.js介绍
https://medium.com/@FezVrasta/popper-js-v1-5e8b3acd888c
https://survivejs.com/blog/popper-interview/
本文译自popper.js作者的一篇博客
在过去,我为了在web app中更好地定位我的tooltips和popover,我会花几个小时写同样的一段代码,不断进行微调。每次我开始一个新的项目,总会根据不同的环境对定位有不同的需求。这种繁琐直到我用emberjs开发一个大型应用时达到极致,这个项目中由于比较烂的UX设计决定,几乎她想在每个元素上都支持hover出现一个popover!
在这个大项目中,我们开始使用bootstrap3的tooltip,并不断地通过hack代码来实现新的功能。
在这个大项目中,一个重要的需求是:不允许将tooltip元素移动到body元素的直接儿子,因为如果这样的话,我们的代码就会broken.
几乎经过一年的项目开发并且维护我们的定制化实现,我决定使用Tetcher,因为他貌似非常强大和稳定。。不幸的是,玩了几个小时后,发现他有一个重要的缺陷或者说限制:他会自动地修改dom节点,将popper移动到body的儿子位置。他会增加一些classes并且增加一些inline style,而这你几乎无法控制!
于是我又到github上花了很多时间去查找有没有备选的方案,但是我最终一无所获。难道是没有人需要一个类似的library?或者还没有人能够比较好的抽象出来并实现一个可以单独发布的lib?
我决定花一个周末的事件重写我们自己项目中使用的定位engine,这就是popper.js的又来。
在v0.x时代,popper仅仅是一个js文件,谢了几个函数,聚焦在保持lib小巧轻量级。我希望popperjs能够有很好的扩展性,所以我决定使用middleware system.主要的想法是:计算元素的位置并且允许middleware来根据特定的需求来修改这个位置。
比如:一旦我们有了popper的position,并给了一些边界约束,那么modifier就可以检查popper是否会overflow并且自动反转位置以确保popper不会被视窗cut off.
在工作了一段时间 后,我发现我们需要更好的代码结构以便更好地能够维护使用他,这就是v1.0版本发布的初衷。
为了管理好代码,我决定切换到es6模块上来。我引入了rollup作为code bundler并使用babel作为transpiler,我也将自动化测试引擎从一个无头的chrome setup切换到saucelabs cross-browser test suite上来。
在开发过程中,我决定各个功能模块一级modifier/middleware都放到他们自己的文件中,这样能在Libray中重用。
update流程:
我也重构了整个update流程,也就是每次popper需要更新元素的位置时需要调用的代码。
这个update process会在每一frame都被调用,也就是说大概60fps,这样能够保证位置修改的流畅连贯。为了实现这个连贯流畅的目标,整个update process的代码必须简练,并且尽可能地避免直接访问dom.下面是其工作流程

React, Vuejs等第三方view library的集成
我必须考虑为了支持react或者vuejs需要做些什么,由于这些view library都会直接做dom操作,那么popperjs应该做什么设计的思考呢?v1.0将所有的dom操作都集中到一个modifier中,applyStyle
这将允许使用vuejs,react的用户简单地disable掉applyStyle并且替换为vuejs,或者react兼容的函数。
Popper.js是如何工作的?
popper.js使用一个reference element(通常是一个button或者一个link)和一个popper element(任何你需要position的元素),popper.js找到这两个元素的common offset parent,计算reference element相对于这个parent的位置,然后产生出一个坐标集用于设置popper元素的position.就这么简单。
最困难的地方在于必须考虑到一些边界条件,比如跨浏览器的兼容性,box model的能力,必须考虑scrollable element等。简单的用法:
new Popper(referenceElement, popperElement)
这段代码将会把popperElement放置到referenceElement的下发。而且,通过这段代码,你就可以访问所有的内置功能。
1. 如果referenceElement非常靠近了viewport的底部,那么popperElement将会被定位放置到referenceElement的上面,否则会出现popper部分不可见的问题;
2. 如果这两个元素位于两个不同的parents,那么popper.js也将会对这种情况考虑周全,也能很好的定位放置popper元素。
3. 它能够有效地处理scrollable elements和页面的resize场景.
Popper.js和其他类似的解决方案有什么不同呢?
主要的不同点在于该库不需要直接操作dom。这有两个好处:1.他不需要将popper节点移动到另外的context中,比如body的儿子,2.这样很容易将popper.js集成到react,angular,vuejs等view library中。你可以像下面的代码一样轻松地将dom manipulation delegate给vuejs:
new Popper(referenceElement, popperElement, {
modifiers: {
applyStyle: { enabled: false },
updateReactData: {
order: 900,
fn(data) {
this.setState({ data });
return data;
}
},
},
});
上面的代码中,我们关闭了内置的applyStyle modifier,并且定义了我们客制化的modifier,该函数代理获取计算出来的popper坐标而将坐标输出到react组件中。
既然你具有了关于popper.js的所有knowledge,那么你就可以对popper element施加任何你想要的样式。
你可能注意到我的定制modifier返回data对象。这个对象是必须的,因为其他的modifier可能会在这个custom modifier之后执行,它们也需要使用这个data对象。这种链条方式的调用使得popper.js非常易于扩展。你可以注入任何定制化的函数在存续modifer之前或者之后运行,或者关闭部分modifer,或者修正其他的modifer的行为,而这只需要通过修改这个data对象数据就可以了。
popup定位引擎popper.js介绍的更多相关文章
- 模板引擎doT.js介绍及如何判断对象为空、如何嵌套循环···
doT.js 灵感来源于搜寻基于 V8 和 Node.js ,强调性能,最快速最简洁的 JavaScript 模板函数 引入 javascript 文件: <script type=" ...
- JavaScript模板引擎Template.js使用详解
这篇文章主要为大家详细介绍了JavaScript模板引擎Template.js使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 template.js 一款 JavaScript 模板引 ...
- Fixflow引擎解析(一)(介绍) - Fixflow开源流程引擎介绍
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- 利用开源HTML5引擎lufylegend.js结合javascript实现的五子棋人机对弈
前言 本文主要介绍利用开源引擎 lufylegend.js开发基于Html5的游戏--五子棋,主要叙述其详细开发过程. 游戏规则 玩过五子棋的都应该知道五子棋的规则,这里就简单介绍其规则. 1 ...
- 模板引擎mustache.js
Javascript模板引擎mustache.js详解 阅读目录 1. 从一个简单真实的需求讲起 2. mustache的用法 3. mustache的思想 4. {{prop}}标签 5. {{ ...
- node.js介绍和npm的使用
Node.js介绍 打开Nodejs英文网:https://nodejs.org/en/ 中文网:http://nodejs.cn/ 我们会发现这样一句话: 翻译成中文如下: Node.js 是一个基 ...
- Node.js 介绍及安装
Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.本文详细介绍了No ...
- HTML5游戏开发引擎Pixi.js新手入门讲解
在线演示 本地下载 这篇文章中,介绍HTML5游戏引擎pixi.js的基本使用. 相关代码如下: Javascript 导入类库:(使用极客的cdn服务:http://cdn.gbtags.com) ...
- 1. vue.js介绍
1. 什么是vue.js Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助 ...
随机推荐
- PHP中 LFI Local File Include,本地文件包 漏洞
在allow_url_include=On就是远程文件包含了,假设这里为off,那就只能本地包含了. 1. 包含上传文件 只要目标服务器支持上传,不管是jpg,txt,gif等都可以,在其 ...
- javascript字符串拼接
var c='../Project/SelectPerson.aspx?personList='+'"'+personListValue+'"' X('Window2').x_sh ...
- C/C++ -- Gui编程 -- Qt库的使用 -- Qt窗体的类型状态布局
-----工程WindowTest----- 1.-----窗体类型type.cpp----- #include <QtGui> int main(int argc, char * arg ...
- 9-lvs-lvs集群-及keepalived健康检查
注意: 配置前需要将上一篇的配置都清除掉 ifconfig eth1: down service ipvsadm restart nginx作为请求分发服务器时, 有健康检查机制, 挂了的服务器不会在 ...
- 面试题22:有序数组生成不同结构BST
对于一个含有n个数的有序数组1~N,能够产生多少种不同结果的二叉搜素树BST? 如何生成这些不同结构的BST? 有序数组如何生成平衡二叉搜索树? class Solution { public: in ...
- [HAOI 2015]树上染色
Description 题库链接 给出一棵 \(n\) 个节点的树,边有权值.让你将树上 \(k\) 个点染黑,剩余 \(n-k\) 个点染白.染色后记一种染色方案的价值为黑点间两两距离和以及白点间两 ...
- 求两个Linux文本文件的交集、差集、并集
一.交集 sort a.txt b.txt | uniq -d 二.并集 sort a.txt b.txt | uniq 三.差集 a.txt-b.txt: sort a.txt b.txt b.tx ...
- awk去重以某列重复的行
[root@localhost cc]# cat 2.txt adc 3 5 a d aa 3 adfa d ba 3 adf 去重第一列重复的行: [root@localhost cc]# cat ...
- .net mvc Razor 三元运算判断赋值 ?:
预期效果: 当Model中的Age数字列值为0时,不显示该值. <input type="text" class="form-control onlyPositiv ...
- 以中间件,路由,跨进程事件的姿势使用WebSocket
通过参考koa中间件,socket.io远程事件调用,以一种新的姿势来使用WebSocket. 浏览器端 浏览器端使用WebSocket很简单 // Create WebSocket connecti ...