improve onblur (did not work in all browsers), cleanup - jscancer - Javascript crap (relatively small)
HTML git clone git://git.codemadness.org/jscancer
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 24a8497f1f0b9734fb410110bf817966e228040e
DIR parent 1d3b222c38a79a8c0e1823b30ac5f7c8eb28a0a1
HTML Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri, 27 May 2016 19:27:12 +0200
improve onblur (did not work in all browsers), cleanup
Diffstat:
M autocomplete/README | 6 +++---
M autocomplete/TODO | 5 -----
M autocomplete/complete.js | 102 ++++++++++++++++---------------
3 files changed, 56 insertions(+), 57 deletions(-)
---
DIR diff --git a/autocomplete/README b/autocomplete/README
@@ -8,8 +8,8 @@ FEATURES
--------
- Small:
- - Filesize: +- 4.6KB, +- 2.2KB minified, +- 1KB GZIP'd.
- - Lines: +- 160, not much code, so hopefully easy to understand.
+ - Filesize: +- 4.7KB, +- 2.3KB minified, +- 1KB GZIP'd.
+ - Lines: +- 162, not much code, so hopefully easy to understand.
- No dependencies on other libraries like jQuery.
- (Graceful) fallback to HTML5 datalist if Javascript is disabled.
- Filtering values: case-insensitively, tokenized (separated by space).
@@ -32,7 +32,7 @@ See example.html and style.css for an example. A stylesheet file style.css
is also included.
An input should have the classname "autocomplete" set with the attribute
-data-list="idoflist". The id should be of the datalist:
+list="idoflist". The id should be of the datalist:
<datalist name="nameoflist" id="idoflist">
<option>Item 1</option>
DIR diff --git a/autocomplete/TODO b/autocomplete/TODO
@@ -1,6 +1 @@
- improve README and documentation.
-
-WONTFIX?
-- IE 11-: clicking scrollbar in dropdown calls onblur event of input box
- in < IE Edge. Javascript / IE event handling is retarded. Will accept a
- simple solution if it doesn't make the code too complex.
DIR diff --git a/autocomplete/complete.js b/autocomplete/complete.js
@@ -1,80 +1,80 @@
-function autocomplete_init(oel) {
- var attrlist = oel.getAttribute("list"), ellist = document.getElementById(attrlist);
+function autocomplete_init(input) {
+ var attrlist = input.getAttribute("list"), ellist = document.getElementById(attrlist);
if (attrlist === null || ellist === undefined)
return;
- oel.removeAttribute("list");
- oel.autocomplete = "off";
- var odropdown = document.createElement("div"),
- oitems = [],
- omouse = true, // enable mouse event handling.
- osel = null;
- odropdown.className = "autocomplete-dropdown";
- odropdown.style.left = String(oel.offsetLeft) + "px";
+ input.removeAttribute("list");
+ input.autocomplete = "off";
+ var dropdown = document.createElement("div"),
+ items = [],
+ mouse = true, // enable mouse event handling.
+ cursel = null;
+ dropdown.className = "autocomplete-dropdown";
+ dropdown.style.left = String(input.offsetLeft) + "px";
var autocomplete_match = function(s) {
var matches = [], tok = s.toLowerCase().split(" ");
- for (var i = 0; i < oitems.length; i++) {
+ for (var i = 0; i < items.length; i++) {
var fc = 0;
for (var k = 0; k < tok.length && fc < tok.length; k++) {
var f = false;
- for (var j = 0; j < oitems[i].search.length && fc < tok.length && !f; j++)
- for (var l = 0; l < oitems[i].search.length && !f; l++)
- if (oitems[i].search[l].indexOf(tok[k]) != -1)
+ for (var j = 0; j < items[i].search.length && fc < tok.length && !f; j++)
+ for (var l = 0; l < items[i].search.length && !f; l++)
+ if (items[i].search[l].indexOf(tok[k]) != -1)
f = true;
if (f)
fc++;
}
/* all tokens (separated by space) must match. */
if (fc == tok.length)
- matches.push(oitems[i]);
+ matches.push(items[i]);
}
return matches;
};
var autocomplete_render = function(m) {
- var p = odropdown.parentNode;
- var dd = odropdown.cloneNode(false);
+ var p = dropdown.parentNode;
+ var dd = dropdown.cloneNode(false);
for (var i = 0; i < m.length; i++)
dd.appendChild(m[i].el);
- p.replaceChild(dd, odropdown)
- odropdown = dd;
+ p.replaceChild(dd, dropdown)
+ dropdown = dd;
};
var autocomplete_show = function(status) {
- odropdown.className = "autocomplete-dropdown " + (status ? "visible" : "");
+ dropdown.className = "autocomplete-dropdown " + (status ? "visible" : "");
};
var autocomplete_setsel = function(el) {
- if (osel)
- osel.className = "";
- if ((osel = el))
+ if (cursel)
+ cursel.className = "";
+ cursel = el;
+ if (el)
el.className = "sel";
};
for (var i = 0, ec = ellist.children; i < ec.length; i++) {
var div = document.createElement("div");
div.innerHTML = ec[i].innerHTML;
- // NOTE: mousedown triggers before onblur.
div.onmousedown = function() {
- oel.value = this.textContent;
+ input.value = this.textContent;
autocomplete_show(false);
};
div.onmousemove = function() {
- if (omouse)
+ if (mouse)
autocomplete_setsel(this);
};
- oitems.push({ el: div, search: (div.textContent.toLowerCase() || "").split(" ") });
+ items.push({ el: div, search: (div.textContent.toLowerCase() || "").split(" ") });
}
- oel.onkeydown = function(e) {
- omouse = false;
+ input.onkeydown = function(e) {
+ mouse = false;
switch (e.which) {
case 13: // return
- if (osel)
- this.value = osel.textContent;
+ if (cursel)
+ this.value = cursel.textContent;
autocomplete_show(false);
case 27: break; // escape
case 33: // page up.
case 34: // page down.
case 38: // arrow up
case 40: // arrow down
- var sel = osel, dd = odropdown, dc = odropdown.children;
+ var sel = cursel, dd = dropdown, dc = dropdown.children;
// if last and down arrow switch to first item, if first and up arrow switch to last item.
if (dc.length) {
@@ -88,7 +88,7 @@ function autocomplete_init(oel) {
sel = dc[0];
}
}
- if (osel && (e.which == 33 || e.which == 34)) {
+ if (cursel && (e.which == 33 || e.which == 34)) {
var n = sel.offsetHeight ? (dd.clientHeight / sel.offsetHeight) : 0;
if (e.which == 33) { // page up.
for (; n > 0 && sel && sel.previousSibling;
@@ -111,12 +111,12 @@ function autocomplete_init(oel) {
}
}
};
- oel.oninput = function() {
+ input.oninput = function() {
var m = autocomplete_match(this.value);
// check if selection is still active in matches.
- if (osel) {
+ if (cursel) {
var hassel = false;
- for (var i = 0; i < m.length && !(hassel = (m[i].el === osel)); i++)
+ for (var i = 0; i < m.length && !(hassel = (m[i].el === cursel)); i++)
;
if (!hassel)
autocomplete_setsel(null);
@@ -130,25 +130,29 @@ function autocomplete_init(oel) {
}
autocomplete_show(!!m.length);
};
- oel.onkeyup = function(e) {
- omouse = true;
+ input.onkeyup = function(e) {
+ mouse = true;
// return key or escape was not pressed.
if (e.which == 13 || e.which == 27)
autocomplete_show(false);
};
- oel.onblur = function() {
- autocomplete_setsel(null);
- autocomplete_show(false);
- };
- oel.onfocus = oel.onclick = function() {
+
+ var focuschange = function(e) {
autocomplete_setsel(null);
- var m = autocomplete_match(this.value);
- if (m.length)
- autocomplete_render(m);
- autocomplete_show(!!m.length);
- odropdown.scrollTop = 0; // reset scroll.
+ if (e.target === input) {
+ var m = autocomplete_match(input.value);
+ if (m.length)
+ autocomplete_render(m);
+ autocomplete_show(!!m.length);
+ dropdown.scrollTop = 0; // reset scroll.
+ } else {
+ autocomplete_show(false);
+ }
};
- oel.parentNode.insertBefore(odropdown, oel.nextSibling);
+ document.addEventListener("focus", focuschange, false);
+ document.addEventListener("click", focuschange, false);
+
+ input.parentNode.insertBefore(dropdown, input.nextSibling);
}
var els = document.getElementsByClassName("autocomplete");