Get item below another item in JavaScript - javascript

If you have a document full of absolute positioned items and you set a document click handler (document.onclick = handler). Is it possible to get all objects that share the mouse position? i.e. two div boxes overlapped, not only the top one

Use the following algorithm:
find out the x and y coordinates of mouse.
Use document.elementFromPoint, add returned element to array.
Hide that element using display:none
Go to 2 until returned element is document.body
Display all hidden elements.

Related

Vue draggable with elements that change height upon being dragged

I have a Vue3 app with vue-draggable and I have a list of sortable cards which possibly contain long text inside. To make dragging easier, I want to hide the text contained in the cards and only show their title when one is being dragged. This makes it easier to drop the card into the right position.
In order to achieve this, the elements which I want to hide inside of the cards while one is being dragged are given a CSS class hidden-while-dragging and the whole collection receives a class dragging while an item is being dragged. This is achieved by setting a boolean variable to the correct value upon receiving the events start and end and conditionally setting the class on the whole <draggable> element. Then I have this CSS rule:
.dragging .hidden-while-dragging {
display: none;
}
This works fine except for one case: if I drag an element and, upon dragging, the height of the parent container changes (due to the disappearing of the content inside of the cards), I am not able to drag the item: it instantly gets dropped in place, and no end event is emitted, so for example the collection keeps the class dragging.
Afterwards, I am able to drop the element once again: the issue doesn't occur this time, because no change in height occurs, and after I drop the element, everything goes back to "normal".
I made this repo in order to have a reproducible example: https://github.com/samul-1/vue-draggable-bug-demo
Here's a codepen as well: https://codepen.io/samul-11/pen/mdjKvZa try and drag the first or last element and you'll see the issue.
You can observe the height of the #app element changing when dragging an element. An interesting thing is that this only happens if dragging the first or third item in my example, not the second. So apparenly the issue is with elements at the edge of the parent.
Is this a bug with the library or is there a way around it?

Drag and Drop Element into a Container fails with too many elements

I'm trying to use Drag and Drop to move <li> elements from one <ul> to another <ul>. I've got it working up to a point. My problem is I can't "drop" a <li> element when it's over another <li> element in my <ul> container. So when I fill up the visible portion of my container I can no longer drag and drop.
This CodePen demonstrates my problem.
not sure exactly what you are trying to achieve, if you want the drop target
to enlarge to accomodate, then be sure you set the CSS style on the target
with a text size using px definitions instead of pt specs.
then each time a drop occurs add to your drop routine to increase the size
of the drop target by the pixel height of 1 line of text. so it grows by 1 on
every drop, or the height is equal to lineHeight x (numElements + 1)
always leaving you room for 1 more drop
if you are trying to maintain a fixed size of the drop target, ie, you dont want
to move other elements down the page, take the above mentioned drop target
and put it inside a fixed size div with scrollable properties.
that way you have a drop element that can grow as described above,
but the fixed div constrains the screen real estate so the drop target doesnt
take up more space than you want
I solved my issue. I had to comment out an if statement in my handleDragOver function that was checking if the event.target was the dropzone element. I also changed my handleDrop function to use event.currentTarget instead of event.target

jQuery .scrollTop() not scrolling to li elements as expected

I essentially have an unordered list of list items in a div that doesn't scroll to the next element properly. I'm just trying to have a button to scroll up and down the list.
While the code does scroll, it doesn't match up with the li elements. After every click, it scrolls up a little bit, then down on the next click. I've tried walking the DOM and verifying the element it is scrolling to is an li element, but didn't see the issue.
I have the following jsfiddle:
http://jsfiddle.net/YD9s5/9/
The elements are:
A scrolling div with an id of photos-div
An unordered list with an id of photos-li (whoops, leaving it for now)
List items with incrementing ids of photo-li-X where X is a number
The code being used to scroll the div is:
$('#photos-div').scrollTop($('#photo-li-' + i).offset().top);
The i variable is being incremented, as you can see.
The problem is that .offset() gets the position of an element relative to the entire document, and that position is constantly moving up. So once you've scrolled to item 1, it returns the .offset().top that item 1 currently has in the document, which is now where item 0 used to be.
Add console.log( $('#photo-li-0').offset() ); to the top of your scrollToElement() function and you'll see what I mean. Notice that the top offset keeps decreasing, quickly moving into the negative numbers as it moves off the top of the document.
The fix is to take the difference between the offset of $('#photo-li-'+i) and $('#photo-li-0') (or the container $('#photos-li') itself) and scroll to that instead:
var newpos = $('#photo-li-' + i).offset().top - $('#photo-li-0').offset().top;
$('#photos-div').scrollTop(newpos);
http://jsfiddle.net/mblase75/x4hQP/ (incorporates other improvements)
It appears that .offset() only measures from the top of the document. You are interested in how far the element is from the top of #photos-div. Here's a working version where I track the position in the div manually. Notice in the console that when I log the value of .offset() it's relative to the document rather than the scrolling div.
Seems that there should be a way to do this without carrying the position of that div in state. Working on it...
Here's my more programatic solution.

selecting an element on mouse click overlapped by another transparent div

I am working on a dashboard where user can drag and drop elements to create html pages.Now,he can have multiple images using an image component.We have managed to calculate the z-index of the images and they can be adjusted using up-down keys.
Issue:
The issue we are facing is when we select a image component we attach a dotted layer above it for helping the user to easily drag and resize it.If the user places the images as shown in the image below
we are not able to select the inner image again because the z-index of the selection div(the one with the blue dots) is(has to be) the highest(highest bcoz we have to use it for all components).So if I try to select the inner image now it cannot be selected.How can I handle the situation? For reference it works on this site as expected.
I believe we have get the element under the parent when it is clicked.But not sure how!We are using javascript,jquery to handle the events.
You can use JavaScript or jQuery to get the position of the inner image, and when the user clicks on the outer image, check to see whether the mouse position lies within the range of the smaller image. The range can be calculated with the position, width, and height of the inner element.
To get the element's position: use jQuery .offset() or .position() (The former is relative to the document, the latter to the parent).
To get the mouse position: http://docs.jquery.com/Tutorials:Mouse_Position
You could consider hiding the masking element quickly in order to gather the coordinate for your underlying element, when done, you could re enable visibility for the masking element. Use document.elementFromPoint() in order to get the DOM item from mouse coordinate.
An example:
http://jsfiddle.net/s94cnckm/14/
Alternatively you can use The CSS property pointer-events: none; on the masking element.
Related:
https://developer.mozilla.org/de/docs/Web/CSS/pointer-events
How to detecting a click under an overlapping element?

The expand-off-the-screen problem

I'd like to have elements on my page that expand on mouseover events. That's working great already, but when the elements are too close to the edge of their containing div, parts of the expanded section aren't visible (or show up outside the container).
How can I calculate a corrected position that would put the expanded element completely within the div? The expanding elements can have an arbitrary size, and so can the surrounding div.
If this code is static you can simply manually set the width of the containing and the contained div manually with CSS. However, if size of the containing div is variable based upon content you may want to use javascript (I like jQuery) to grab the width of the containing div and use that value as the final expand point of the contained div.
$('.contained_element').css("width", $('.container_element').width());
that jQuery will set the width of the contained element to the width of the containing element. jQuery's $(element).width(); can be used to grab the width of any element and use that value elsewhere in your code.

Categories

Resources