I'm doing something similar here where I need to record where an element was drag and dropped on the page. I can store some data of the drop location in a database, in order to pull it out and place the element back where it was dropped. The only requirement is that I want the dropped element to be as close as possible to the element on which it was dropped, on all screen sizes.
Due to the responsive nature of the modern web, elements can move to completely different locations depending on screen size.
My solution is to ignore all DOM selectors, and instead simply record where the element is in the DOM tree by recording a child index on every 'layer' of the DOM, all the way down to to the element in question.
I do this by traversing up the DOM tree from the event.target
element, looking at currentNode.parentNode.children
to find which child index my currentNode
inhabits. I record that in an array, which I can then use to index all the way back down the DOM tree to find my element. I also save the dropped elements offset as a percentage, in case the dropzone element has changed pixel size.
Here's my cut down code:
var rect = mouseEvent.target.getBoundingClientRect()
// get position of mouseEvent in target as a percentage so we can be ok if it changes size
var xpos = Math.floor(mouseEvent.offsetX / rect.width * 100)
var ypos = Math.floor(mouseEvent.offsetY / rect.height * 100)
// traverse backwards up the dom tree, recording this 'branch' of it as we go:
var curEl = mouseEvent.target
var tree = []
while(curEl.parentNode){
for( var i = 0; i < curEl.parentNode.children.length; i ++ ){
var curChild = curEl.parentNode.children[i]
if( curChild === curEl ){ // i is our child index
tree.unshift(i) // unshift to push to the front of the array
break
}
}
curEl = curEl.parentNode
}
And then in order to find my node again, I simply traverse back down the dom:
var curEl = document
for(var i = 0; i < tree.length; i ++){
curEl = curEl.children[tree[i]]
}
All I save to the database is the tree
array (a flat array of integers - how can you get smaller?) and my x and y offsets!