Vooral waarom de ene keer als ik op een input veld klik de popup onder dat veld verschijnt en de andere keer niet. Het lijkt erop dat JS voor zichzelf begint en dat zou heel bijzonder zijn.
In het attach label laadt JS twee keer een input veld.
Dat heb ik JS verteld, dus dat doet ie dan ook braaf.
JS laadt twee objecten, voor elk input veld een, in het array instances.
Met het statement 'let inst = tp.instances[id]', krijgt 'inst' het laatst geladen object.
'inst.target.addEventListener('click', () => { tp.show(inst) })' is een klik op het laatst geladen object en dat krijg ik dan ook te zien. Niks bijzonders precies zoals ik dat verwacht.
Wat ik niet begrijp is dat een klik op het eerst geladen object soms(!) ook werkt.
Hoe kan JS weten dat ik op dat input veld heb geklikt?
Magic, of doet JS soms gewoon wat hij wil?
Of, en dat is waarschijnlijker, begrijp ik gewoon niet wat er gebeurd.
Kan, wil iemand hier wat licht over laten schijnen?
Als het helpt, maak ik even een fiddleltje.
HTML
<!DOCTYPE html>
<html>
<head>
<title>Javascript Test Popup</title>
<!-- (A) LOAD CSS & JS -->
<link href="test-popup.css" rel="stylesheet">
<script src="test-popup.js"></script>
</head>
<style>
.test-popup-wrapper {width: 700px;display: flex;justify-content: space-evenly;}
.test-popup {position:relative;top: 170px;left: 180px;}
#popup-one:focus {background-color: coral;}
#popup-two:focus {background-color:chartreuse;}
.test-input {height: 60px;border: 2px solid red;}
.test-input input[type=text] {font-size: 3.0em;;}
</style>
<body>
<!-- (B) HTML FIELD -->
<div class="test-popup-wrapper">
<div class="test-popup">
<label for="popup-one">Popup one:</label>
<input class="test-input" type="text" id="popup-one"/>
</div>
<div class="test-popup">
<label for="popup-two">Popup two:</label>
<input class="test-input" type="text" id="popup-two"/>
</div>
</div>
<!-- (C) ATTACH -->
<script>
tp.attach({ target: document.getElementById("popup-one")});
tp.attach({ target: document.getElementById("popup-two")});
</script>
</body>
</html>
JS
let tp = {
init: () => {
tp.tPop = document.createElement('div')
tp.tPop.classList.add('popup-wrapper')
document.body.appendChild(tp.tPop)
// ADD TEST POPUP INNERHTML
tp.tPop.innerHTML =
`
<h1>Here we can do all kinds of stuff.</h1>
<br>
<button id="tp-set" onclick="tp.set()">Kies</button>
`
}, // init: ------------------------------
instances: [],
attach: (opt) => {
console.log("opt: ", opt)
// output:
// Object
// bottom: 282
// left: 548
// sPos: "top: 282px; left: 199px;"
// target: <input id="popup-one"></input>
// and again for <input id="popup-two"></input>
opt.target.readOnly = true;
opt.target.setAttribute("autocomplete", "off")
const targetElem = opt.target.getBoundingClientRect()
opt.target.left = Math.floor(targetElem.x)
opt.target.bottom = Math.floor(targetElem.bottom)
console.log("opt.target: ", opt.target)
// attach is executed twice; for each call on attach.
// output:
// <input class="test-input" type="text" id="popup-one" readonly autocomplete="off">
// <input class="test-input" type="text" id="popup-two" readonly autocomplete="off">
let id = tp.instances.length
// HERE WE PUSH THE OPT OBJECTS TO INSTANCES ARRAY
tp.instances.push(opt)
// WHEN WE HAVE TWO INPUT FIELDS, INST CONTAINS THOSE
// TWO OBJECTS.
// 'ID' POINTS TO THE LAST OBJECT LOADED.
let inst = tp.instances[id]
// GET LEFT & BOTTOM POSITION OF THIS INSTANCE
inst.left = opt.target.left + 10
inst.bottom = opt.target.bottom + 10
tPos = 'top: ' + inst.bottom + 'px;'
lPos = 'left: ' + inst.left + 'px;'
inst.sPos = tPos + ' ' + lPos
// ON CLICK ON THIS INSTANCES TARGET FIELD, SHOW POPUP
inst.target.addEventListener('click', () => { tp.show(inst) })
}, // attach: ------------------------------------
show: (inst) => {
// POSITION THIS INSTANCES TARGET FIELD
tp.tPop.setAttribute('style', inst.sPos)
tp.tPop.classList.add('show')
}, // show: ---------------------------------------
// SET SELECTED STUFF AND CLOSE POPUP
set: () => {
tp.tPop.classList.remove('show')
},
} // tp ---------------------------------------------
document.addEventListener("DOMContentLoaded", tp.init)