In some corporate web application, I have some troubles with the :hover css selector with IE 8 users.
Basically, I have a lot of javascript, and the page sometimes is a bit slow.
Especially, my issue occurs in a sortable table (yes tables suck, but I have to live with it by now).
Within each row, I have a button that performs some operation. The button have :hover css rules to make it highlighted on mouse hover.
But in a specific case, the hover state remains, even if the mouse is no more on the element.
You can see the behavior on jsfiddle (run embbeded version with IE8): http://jsfiddle.net/stevebeauge/K9EGv/24/embedded/result/
To reproduce the problem:
Start draging an element by clicking on the "hover" button.
very quickly, drop the item (even if the drag is not visually started) elsewhere in the list
still very quickly, move your mouse out of the table
The whole operation must be done under 1.5 second.
With this scenario, the initial dragged item is in the hover state, even if the mouse is no more on the button.
Is there a way to "force" refresh of the hover state?
Related
My web page (with vanilla Javascript) accepts files dropped on to it from the native desktop. I want to change the cursor's appearance while dragging, to give users feedback about the progress of their drag (when they're on the drop zone, etc). This is easy if you're dragging an HTML element from within the same page, but I haven't found how to do it when dragging a file or image from elsewhere on the desktop.
I have tried setting a class on the body element and all its descendants (and there are no other cursor styles anywhere) but as you can see (from the attached edited screenshot)
it has no effect - the class and style are applied correctly (see debug tools view in the lower half of the image) but the cursor nevertheless takes its default appearance.
Relevant snippet of CSS:
.no-drop-cursor, .no-drop-cursor * {
cursor: no-drop;
}
and Javascript applies the class to the body element whenever the cursor is on my web page but outside the drop zone.
Is this in fact impossible - or is there some neat way to make it happen?
A couple of things to avoid unnecessary suggestions:
All relevant drag/drop event handlers already do preventDefault();
The actual drag/drop code works just fine, exactly as intended;
I already give visual feedback to users by highlighting the drop zone appropriately as the cursor moves into and out of it, but I would also like the cursor's appearance to change.
Any ideas appreciated, even if it's only a clear explanation of why I can't do that!
Edit 2022-08-16: This earlier question seems to be a duplicate, but received no useful responses.
I like letting my popovers stay open until the user explicitly closes them.
One of the nice features of the new Bootstrap Popovers is that they automatically re-position when the user changes device orientation, scroll or resize the window. They even follow along as the content re-flows - e.g. as a paragraph is wrapped and the element grows or shrinks in length while you resize the window - all the popovers on the screen will keep re-positioning to be near their target.
How does the Popover plugin know that the page is being re-flowed so that it triggers the popover re-positioning?
My webapp is dynamic, user actions cause elements to grow/shrink, toggle on/off, etc. At the moment, when I change the page via code, the popovers get left behind - they don't get re-positioned near their target.
One workaround to this, as a user, is to just scroll the screen a little bit and Bootstrap will re-position the popovers and everything looks right again.
I'm trying to figure out a way to re-position the popovers when I change the page layout via code.
Hence the question: how does Popover re-positioning work (and can I hook into it so I can trigger it automatically).
EDIT: I've just noticed that the popovers will re-position just fine if the "dynamic" content happens to be the Bootstrap navbar collapsing/expanding because of a tap on the navbar-toggler.
There's two parts to this question.
How does popper.js know when to update the popovers?
How does the popover change position?
Answering these backwards:
2: How does the popover change position?
You need the update method of the popover:
$('#element').popover('update')
I've done a quick demo here:
https://jsfiddle.net/pktyptyp/
First, click the green button to open the popover. Then use button 2 to move the popover toggle. Now the toggle and the popover no longer line up. So finally use button 3 to reposition the popover by its toggle.
The docs for this are tucked under the popover methods section here:
http://getbootstrap.com/docs/4.0/components/popovers/#methods
If you wanted to update every popover on your page and not just a specific one, then you could do:
$('[data-toggle="popover"]').popover('update')
How does popper.js know when to update the popovers?
Popper will be subscribing to events like window.scroll and window.resize. You can see this in a bit of their source code:
https://github.com/FezVrasta/popper.js/blob/master/packages/popper/src/utils/setupEventListeners.js
The update method won't be called immediately in that event handler - there'll be something that gets passed back to the Boostrap widget, which in turn will call the popover update method.
I am fairly sure Popper & the Popover widget will not be looking at the position of the individual toggles. This is partly because unless the toggles are positioned, their left/top properties will always be 'auto' so it will be hard to work out if they are moving. Or to put it another way, when the window scrolls, the toggle has not moved within the document, but the popover (which is absolutely positioned) needs updating. So this is a bit of a broad brush - they are looking out for the entire window changing, assuming the popovers are out of position, then triggering more events to update them.
If anyone knows more about this, though, please tell me in the comments!
You have a bit of an advantage in that you know when you change your UI, so you can call 'update' on all the Popovers at will. This to me seems like the ideal approach.
However, if your toggles are absolutely positioned, you could do this a bit more automatically by watching their position. Here's an example with an absolutely-positioned toggle and in this example, the popover moves automatically without the third button click.
https://jsfiddle.net/pktyptyp/1/
I don't know how the logic work behind that because on Bootstrap we use Popper.js to handle that so if you want to understand the logic behind that you can browser this : https://github.com/FezVrasta/popper.js
I am building an audio player in a SPA and have a main player widget that shows the currently playing track along with controls at the bottom of the page. The desired UI is to hide all controls but the play/pause button until the user hovers near the play/pause button. At this point the extra information, seek bar, volume controls etc. will be animated onto the screen.
Excuse my shoddy drawing
I should add that the controls are positioned fixed to the bottom of the screen.
Initially, I tried adding an extra fixed positioned div on top of everything (high z-index) and using that to trigger the hover event. Obviously, this doesn't allow for clicking the buttons below it so I tried pointer-events: none on the element but then no hover event is registered.
I then tried putting the hover region underneath the control elements and adding the hover trigger to both the hover region and the controls. This causes strange behavior when moving the cursor between the hover region and any controls (i.e. to click pause/play).
My next thought is to scrap the hover region HTML element and use a pure JS solution. I could register a mousemove event to the document body and detect when the cursor is within the hover region, triggering control animations. However, I am worried this might cause performance issues as seems a bit heavy.
I hope someone has some input/improvements on the things I have tried or comes up with something I haven't thought of!
BTW: I am using angular2 for the animation if that sparks some bright ideas to use that.
Update 1
Here's a jsFiddle showing the first two attempts. Change the z-index of hover-region to see the effect of it being on top of the play button or below.
I've created a working version for you at http://jsfiddle.net/6wk69fvo/1/. You already did what I was going to suggest, which is to use onmouseenter and onmouseleave.
But rather than just checking the hover area, you also need to check the toolbar area, and then just OR the two values together.
Also note that I put the play / pause button as a child of the hover area. If you don't want to do that, you'd need to create a third check for mouseenter or mouseleave for that div.
You can alter the control's opacity make it visible/invisible. Here is a simple example done in pure html/js to avoid the overhead of setting up an ng2 app, yet, I'm sure you can quickly adapt it to your code.
I have a number of images in my HTML document.
The user triggers some changes (AJAX calls) when clicking on an image or by pressing a key.
To keep track of the latest image (client-side), I use javascript and onmouseover, assigning the image ID to a javascript-variable which in turn is used to fill the AJAX calls.
Everything works well (even it there might be better ways to do it), but sometimes it takes some time to refresh the image. For a moment, it ceases to exist, causing the image next to it to jump left.
This, of course, moves that image underneath the pointer, triggering the mouseover event.
How(?) is it possible to distinguish between a mouseover event caused by mouse-movement from one fired by a layout change?
The short answer is you can't really tell what caused a mouseover event, other than the cursor moved over a new DOM element (or some other things, like a tap on a touch device). A layout change is just something that happens independent of this event.
One possible solution to your actual problem is to avoid the problem altogether by preventing the layout jump. For example, you could use a placeholder element to fill the space while the next image loads.
Alternately, your logic could almost-certainly be made more-robust so as not to depend on something as fragile as this.
I have an application that contains several transitioning elements. These same elements react to mouseenter and mouseleave events. These events are deactivated during transitions to avoid users interacting with elements in transit.
The problem comes in when one of these elements are underneath the mouse when they are made active again. Once the moving elements are no longer moving, they should again register that the mouse is hovering on top of them. But since the mouseenter took place whilst the element was deactivated, the event is not fired once the element is made active once more.
If you then move your mouse off of the element, and then on again, it works fine. This is obviously not very user friendly.
Is there a way to register that the mouse is hovering on an element without moving the mouse?
More information on the elements discussed above:
The elements in question are large divs that contain a lot of content. They are actually pages in the application that I add and remove dynamically. I have a custom scroll bar that shows if the area has focus, and hides if it does not.
As the mouse moves into the page content area, the custom scroll bar shows. Once it moves out, the scroll bars hide again. All events are made inactive whilst the animation is running.
The problem is that is the mouse moves into the page area whilst a page is animating, the the scroll bars do not (and should not) show. Once the animation completes, however, the application should register that the user is hovering inside of the page area without him moving the mouse outside and back inside this space.
Track the position of the mouse using a mousemove event, and test the element at the last known mouse position when you re-enable the behaviour using
document.elementFromPoint(x, y)