How to detect that the mouse is above: before or after: after part of an element

I have this CSS for defining selection areas where the user can either delete a section before or after existing sections.

.section:before, .section:after { content: "[insert here]"; height: 64px; line-height: 56px; width: 100%; display: block; border: 3px dashed #aaa; } 

Using JavaScript + JQuery is a listener that detects an element under the mouse:

 elem.on('drop', function(e) { e.preventDefault(); var container = $(elem[0].elementFromPoint(e.clientX, e.clientY)); }); 

However, container will be the same element for: before and: after case.

How can I find out if a user has fallen before or after a section?

+5
source share
4 answers

It is really possible.

(Although, as others have said, perhaps not the best idea)

Assuming that the content is stacked one on top of the other: before โ†’ content โ†’ after

We can calculate the drop point with respect to the container, and then based on the height of the generated content, which we can determine if the item was reset in the zone before or after.

And yes, javascript can actually access CSS properties for pseudo elements .

This is done using Window.getComputedStyle()

Syntax: (from MDN )

 var style = window.getComputedStyle(element[, pseudoElt]); 

pseudoElt Optional

A string indicating the correspondence of a pseudo-element. Must be omitted (or null) for regular elements.

So, for example, to get the height of the generated content in front of the section (let's call it "target"):

 window.getComputedStyle(target, ':before').height 

Here is a snippet of the demo:

 var elem = document.getElementById("el"); var target = document.getElementById("target"); var targetHeight = parseFloat(window.getComputedStyle(target).height); var beforeHeight = parseFloat(window.getComputedStyle(target, ':before').height); var afterHeight = parseFloat(window.getComputedStyle(target, ':after').height); elem.addEventListener("drag", function(e) { document.body.classList.remove('dropped'); }); target.addEventListener("dragover", function(e) { this.textContent = "dragging over section"; document.body.classList.add('dragging-over'); addBeforeAfterClasses(e); }); target.addEventListener("dragleave", function(e) { document.body.classList.remove('dragging-over'); this.textContent = "section"; e.currentTarget.style.background = "none"; }); target.addEventListener("drop", function(e) { document.body.classList.add('dropped'); addBeforeAfterClasses(e); this.textContent = "successfully dropped!"; }); function addBeforeAfterClasses(e) { var dropOffsetTopWithRespectToContainer = e.clientY - target.offsetTop; if(dropOffsetTopWithRespectToContainer <= beforeHeight) { document.body.classList.add('before'); } else { document.body.classList.remove('before'); } if(dropOffsetTopWithRespectToContainer > targetHeight - beforeHeight) { document.body.classList.add('after'); } else { document.body.classList.remove('after'); } } target.ondrop = drop_handler; target.ondragover = dragover_handler; function drop_handler(e) { e.preventDefault(); } function dragover_handler(e) { e.preventDefault(); } 
 .section { margin: 10px; position: relative; } .section:before, .section:after { content: "[insert here]"; height: 64px; line-height: 56px; width: 100%; display: block; border: 3px dashed #aaa; } .dragging-over.before .section:before { content: "[drop into before]"; border-color: green; } .dragging-over.after .section:after { content: "[drop into after]"; border-color: green; } .dropped.before .section:before { content: "[dropped into before]"; background-color: green; color: white; } .dropped.after .section:after { content: "[dropped into after]"; background-color: green; color: white; } .elem { width: 20px; height: 20px; border-radius: 50%; background-color: maroon; margin: 0 20px; display: inline-block; } 
 <div id="target" class="section">section</div> <span>drag me:</span> <div id="el" draggable="true" class="elem"></div> 

Codepen Demo

+1
source

::before and ::after are css pseudo-elements that javascript doesn't know about. For javascript, both of them are their parent element.

You can use real html elements for this.

+3
source

: before and: after are not part of the DOM, so they are not available for any Javascript.

However, the only solution I can come up with is to calculate the height of the section and then compare it with the x and y coordinates to determine if it was deleted before or after.

+2
source

I think you cannot manipulate the ::before and ::after pseudo-elements, since technically there is no DOM and therefore is not available for any JavaScript.

+2
source

Source: https://habr.com/ru/post/1274457/


All Articles