Working on an alternative solution for an issue I asked about previously here.
Rather than trying to toggle fixed and absolute positioning on the go - calculating and applying the difference & offset between them (which I was unable to figure out how to do), this solution will focus on having the div stay in fixed position the entire time.
While in fixed position, the div is controlled by an EventListener adjusting its position in response to user scrolling to mimic absolute positioning behaviour.
There is currently an issue with my code that results in the div jumping to another y-position sometimes when it is scrolled. How can this be corrected so that it does not do that?
container.style.top = -(window.scrollY - lastMovedPosY - container.offsetHeight) + 'px';
var pinned = false;
var lastMovedPosY = 0;
document.addEventListener('scroll', function(e) {
let container = document.getElementById("container");
if (!pinned) {
container.style.top = -(window.scrollY - lastMovedPosY - container.offsetHeight) + 'px';
}
});
/* ------------------- */
function pin() {
pinned = pinned ? false : true;
let pinnedButton = document.getElementById("pinbutton");
pinnedButton.innerText = pinnedButton.innerText == "PIN" ? "UNPIN" : "PIN";
}
//Make the DIV element draggagle:
dragElement(document.getElementById("container"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
document.getElementById("clicktarget").onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
//lastMovedPosY = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
lastMovedPosY = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
body {
height: 3000px;
background-color: #ccc;
opacity: 0.8;
background: repeating-linear-gradient( -45deg, #333, #444 5px, #333 5px, #333 25px );
}
.positionFixed {
position: fixed;
}
#container {
z-index: 9;
background-color: red;
text-align: center;
border: 2px solid;
width: 300px;
resize: vertical;
overflow: auto;
}
#clicktarget {
height: 100%;
width: 100%;
background: cyan;
user-select: none;
cursor: move;
min-height: 100px;
}
<div id="container" class="positionFixed">
<div id="clicktarget">
Click here to move
<button id="pinbutton" onclick="pin();">PIN</button><br>
</div>
</div>