1 | // DistillHoverBox
|
2 | //=====================================
|
3 |
|
4 | function DistillHoverBox(key, pos){
|
5 |
|
6 | if (!(key in DistillHoverBox.contentMap)){
|
7 | console.error("No DistillHoverBox content registered for key", key);
|
8 | }
|
9 | if (key in DistillHoverBox.liveBoxes) {
|
10 | console.error("There already exists a DistillHoverBox for key", key);
|
11 | } else {
|
12 | for (var k in DistillHoverBox.liveBoxes)
|
13 | DistillHoverBox.liveBoxes[k].remove();
|
14 | DistillHoverBox.liveBoxes[key] = this;
|
15 | }
|
16 | this.key = key;
|
17 |
|
18 | var pretty = window.innerWidth > 600;
|
19 |
|
20 | var padding = pretty? 18 : 12;
|
21 | var outer_padding = pretty ? 18 : 0;
|
22 | var bbox = document.querySelector("body").getBoundingClientRect();
|
23 | var left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
24 | var width = Math.min(window.innerWidth-2*outer_padding, 648);
|
25 | left = Math.min(left, window.innerWidth-width-outer_padding);
|
26 | width = width - 2*padding;
|
27 |
|
28 | var str = `<div style="position: absolute;
|
29 | background-color: #FFF;
|
30 | white-s
|
31 | opacity: 0.95;
|
32 | max-width: ${width}px;
|
33 | top: ${top}px;
|
34 | left: ${left}px;
|
35 | border: 1px solid rgba(0, 0, 0, 0.25);
|
36 | padding: ${padding}px;
|
37 | border-radius: ${pretty? 3 : 0}px;
|
38 | box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
39 | z-index: ${1e6}" >
|
40 | ${DistillHoverBox.contentMap[key]}
|
41 | </div>`;
|
42 |
|
43 | this.div = appendBody(str);
|
44 |
|
45 | DistillHoverBox.bind (this.div, key);
|
46 | }
|
47 |
|
48 | DistillHoverBox.prototype.remove = function remove(){
|
49 | if (this.div) this.div.remove();
|
50 | if (this.timeout) clearTimeout(this.timeout);
|
51 | delete DistillHoverBox.liveBoxes[this.key];
|
52 | }
|
53 |
|
54 | DistillHoverBox.prototype.stopTimeout = function stopTimeout() {
|
55 | if (this.timeout) clearTimeout(this.timeout);
|
56 | }
|
57 |
|
58 | DistillHoverBox.prototype.extendTimeout = function extendTimeout(T) {
|
59 | //console.log("extend", T)
|
60 | var this_ = this;
|
61 | this.stopTimeout();
|
62 | this.timeout = setTimeout(() => this_.remove(), T);
|
63 | }
|
64 |
|
65 | DistillHoverBox.liveBoxes = {};
|
66 | DistillHoverBox.contentMap = {};
|
67 |
|
68 | DistillHoverBox.bind = function bind(node, key) {
|
69 | if (typeof node == "string"){
|
70 | node = document.querySelector(node);
|
71 | }
|
72 | node.addEventListener("mouseover", () => {
|
73 | var bbox = node.getBoundingClientRect();
|
74 | if (!(key in DistillHoverBox.liveBoxes)){
|
75 | new DistillHoverBox(key, [bbox.right, bbox.bottom]);
|
76 | }
|
77 | DistillHoverBox.liveBoxes[key].stopTimeout();
|
78 | });
|
79 | node.addEventListener("mouseout", () => {
|
80 | if (key in DistillHoverBox.liveBoxes){
|
81 | DistillHoverBox.liveBoxes[key].extendTimeout(250);
|
82 | }
|
83 | });
|
84 |
|
85 | }
|
86 |
|
87 |
|
88 | function appendBody(str){
|
89 | var node = nodeFromString(str);
|
90 | var body = document.querySelector("body");
|
91 | body.appendChild(node);
|
92 | return node;
|
93 | }
|
94 |
|
95 | function nodeFromString(str) {
|
96 | var div = document.createElement("div");
|
97 | div.innerHTML = str;
|
98 | return div.firstChild;
|
99 | }
|
100 |
|
101 | var hover_es = document.querySelectorAll("span[data-hover]");
|
102 | hover_es = [].slice.apply(hover_es);
|
103 | hover_es.forEach((e,n) => {
|
104 | var key = "hover-"+n;
|
105 | var content = e.getAttribute("data-hover");
|
106 | DistillHoverBox.contentMap[key] = content;
|
107 | DistillHoverBox.bind(e, key);
|
108 | });
|