Within my Firefox extension I'm trying to keep track when the window is actually the active window. For this, I add the following two listener to the window:
window.addEventListener("deactivate", function(event) { alert("deactivate"); }, false);
window.addEventListener("activate", function(event) { alert("activate"); }, false);
Basically everything works fine. When I toggle between different windows, or minimize/maximize Firefox, the events fire quite as I would expect it. However, both events also fired when I move the window even if it is already active. When I start moving the window, the "deactivate" event is fired; when I stop moving and release the mouse button, the "activate" event is fired. I have no idea how can I detect and ignore this behavior. Intuitively, the window is all the time active.
I tried to check before I handle the "deactivate" event if the mouse button is pressed. However, adding a "click" event listener to the window seem not to include the window's title bar. Anyone any idea how I can distinguish beween "really" de-/activating the window and moving the window? Thanks a lot in advance!
You can use this answer to detect the browser position on the screen. If you do this at the start you can compare if they are changing.
Something like when the page loads:
var x,
y,
win = window;
if(win.screenTop !== undefined) {
x = win.screenleft;
y = win.screenTop;
} else {
x = win.screenX;
y = win.screenY
}
and compare those values to the current values when your events triggers.
(Note that this only works when the position of the window changes)
Related
For my webapp I'm working on a popup element, which is used for menus and similar things. I want to redirect all mouse input on the current page to this popup element when it's visible, however I can get it to work.
I have a tile element which, on mouse hover, shows an image (and highlights the tile). When the user clicks on that image the popup is shown (as a context menu). This works already. When the user moves the mouse outside the tile the hover state is gone, the highlight and also the image disappear, which is not what should happen. Instead I want the visual state unaffected as long as the menu is visible.
So I tried to capture the mouse using Element.setPointerCapture. However, this requires a pointer id, which I don't have. I tried to use onPointerDown on the trigger image, but that didn't do anything.
What's the right way to implement this mouse capture, so that no mouse event is scheduled to any other HTML element, but the popup?
This is what I came up with so far:
private handleTriggerClick = (e: React.MouseEvent): void => {
console.log("mouse");
this.props.trigger?.props.onClick?.(e);
if (this.state.open && this.props.closeOnTriggerClick) {
this.close();
} else if (!this.state.open && this.props.openOnTriggerClick) {
this.open();
e.currentTarget.setPointerCapture(this.pointerId);
}
e.stopPropagation();
};
private handleTriggerPointerDown = (e: React.PointerEvent): void => {
console.log("pointer");
this.pointerId = e.pointerId;
};
where trigger is the image used to show the popup.
I also tried using a mouse move handler on the document, but that didn't work either, probably because of event bubbling where first the deeper elements receive the event before it reaches the document, so it's too late then to prevent default handling or stop propagation.
The Element.setPointerCapture API will only work when the pointer is in its "active button" mode (that is between pointerdown and pointerup or pointercancel).
I guess it's not exactly what you want...
Maybe requestPointerLock would be closer to what you are asking, but it may also be a bit too much (a confirm message would pop-up asking your users if they wish to let your app control their mouse etc.)
So a third way, probably easier, is to append an overlay element with a fixed position that would cover the whole page, you could make it appear also only when your menu is hovered, but without seeing your actual situation, I can only give such a broad advice.
I have a problem with Jquery hover and click on mobile.. Let me explain!
I have square div and, when the mouse is hover it, a new div appear and follow the mouse. You can even click the square div and if so, a new page is opened. The problem now is that, on mobile, I need two click for the new page to be opened, since the first click is read as "hover".
I tried the
$("#mydiv").on('click touchend', function(e)
Actually it works, but with this, if I want to scroll the page on mobile, and I start the swipe on the square div, the new page is opened, which it shouldn't since I didn't click on the square div, just "passed by".
Try using one of those events
https://github.com/benmajor/jQuery-Touch-Events#4-the-events
$('#mydiv').bind('tap', function(e) {
console.log('User tapped #myDiv');
});
As per documentation:
"The event's target is the same element that received the touchstart event corresponding to the touch point, even if the touch point has moved outside that element."
You can see the documentation of touchend also:
https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent
If you start your scroll with the square div then square div touchend event will be fired after the release of that finger even after you move your finger to the other elements.
To solve this problem, you can use these events:
https://github.com/benmajor/jQuery-Touch-Events#4-the-events
If you want to stick with this touchend event then there is a workaround:
Declare a global variable i.e.
var isScroll = false, timer;
Apply touchmove eventhandler on document which will fired for touch devices only, this handler detect whether the document is getting scrolled if yes set the isScroll flag to true that will false after 500ms:
$(document).on("touchmove", function(e) {
isScroll = true;
if(timer) clearTimeout(timer);
timer = setTimeout(function() {
isScroll = false;
}, 800);
})
and insert if condition in your eventHandler:
$("#mydiv").on('click touchend', function(e) {
if(!isScroll) {
//insert your code here;
}
}
I have an application that works like a virtual desktop (icons in a horizontal bar in the bottom). When you click on an icon, a window opens (dynamically created). If you click on another (or the same) icon another window opens 10px down and 10px to the right from the last one, and is moved on the top.
When a window gets created, the function below runs adding a click event to the window. If the window is clicked it gets moved to the top.
Now to the problem. One of the windows contains thumbnails of images. When clicking on an image a new window gets created with the image in full size. I want the new window with the full size image to be placed on top, which doesn't happen because the event (in the moveOnTop function) fires after the new window is created on the thumbnail window (because I clicked that window when I clicked on a thumbnail).
I guess one way to solve this would be if it was possible to prevent the event to be fired if a thumbnail is clicked, though I don't know how. What could otherwise be a good way to solve this? Thanks in advance!
Windows.prototype.moveOnTop = function(){
var container = '#desktop';
$(container).on('click', '.window', function() {
var thisWindow = $(this);
if(thisWindow.next().length > 0){
thisWindow.appendTo('#desktop');
}
});
};
Inside the click event handler for thumbnails you can cancel the the event for other (parent) elements:
$("img.thumbnail").on("click", function(e) {
...
// Finally, prevent the click event from bubbling up to parent elements
e.stopPropagation();
});
See: event.stopPropagation()
That depends on the situation. If both cases are handled by the same event handler, you can simply compare against event.target.
If, on the other hand, you've bound another event handler to the click event of the icon and you're trying to prevent the window's click event from firing when an icon is clicked, you can either let the event handler return false or call event.stopPropagation(), like so:
$('.icon').click(function(event) { // <-- parameter 'event' is automatically passed to handlers
// Open window with icons
event.stopPropagation();
});
NB: from what I can tell, you're still (re-)attaching the click handler to all windows in the moveOnTop function. See my answer to your previous question for a solution.
I have a window that is opened by
var myWindow = window.open(
'popupManager.htm',
'myWindow',
'status=0,toolbar=0,width=500,height=100');
and it will act as a debug window.
inside I want to hook up to windows events on the window.opener and I'm not getting this to work. Both URL's are in the same domain/same website.
I can hook up to DOM elements fine using, for example
$("input[soid=DlgButtonBar_cancelButton]", window.opener.document).bind("click", function() {
alert('Cancel button was pressed!');
window.close();
});
but I want to hook up to the move event (window.onMove) and close event.
tried
window.opener.addEventListener('move', function() { console.log('moving...'); });
with no luck.
what is the trick? using jQuery or simple javascript...
Listening on window events doesn't seem to work. I use this trick to listen to window events (unload in my case):
Create a document element (e.g. span) on the parent document (e.g. the one you want to get events from) :
var $unloader = $('<span style="display:none;" id="unloader"></span>');
$('body').prepend($unloader');
$(window).unload(function(){$('#unloader').click();});
In the opened document (e.g. popout), you can listen to the unload event now masked as a click event:
$("#unloader",window.opener.document).click(unloadEventHandler);
If you need to detect if the unload is a close or a navigation event, you can check the closed property for the parent after a delay:
window.setTimeout(function(){
if(window.opener.closed == true) {
// Close event
} else {
// Navigation event
// window.opener.location to get new location
}
},500);
The risk is in the delay, the closed property is changed after the unload methods and event hooks are executed so if the delay is too short you might get the flag before it is changed and if it's too long, you get unnecessary delays.
I think the move event can be handled similarly, hope this helps. Let me know if there are any possible improvements to this method. Thanks and good luck.
I have an image that I want to have trigger certain behaviors when the mouse is over, I have a mouseover and mouseout method, but if you happen to have your mouse over the image when the page loads, the mouseover method never fires until you leave the image and come back over it.
Is there a way to detect if the mouse is over an element on the fly without the mouse having to be off of the element and then come over the element to trigger the JS mouseover event? Like is there a document.getElementById("blah").mouseIsOver() type function in Javascript?
I believe this is possible without any action from the user. When your page loads, bind the mouseover event to your image and hide your image (i.e. using CSS display:none). Use setTimeout() to show it again in a few milliseconds (10 should be enough). The even should be fired.
If you don't want to cause the 'flick' effect on your image, you may try using some temporary element instead, attaching event to it, and delegating the event onto your image.
I have no idea if this is cross-browser solution, but it worked from my Firefox 3.0 console ;)
You could use the mousemove event. That would trigger anytime the user moves a mouse; so the only instance of the trigger not firing would be if the user does not move the mouse at all, which should be rare.
The only problem with this is that the event would fire anytime the mouse would move over your image, so you would get a LOT of those events while over the component. What you would probably need to do is implement some sort of flag within your method when the event fires. You turn on the flag when the event first fires, and you turn it off when you leave the component.
This is less than ideal, but I think this will probably satisfy your problem scenario. The following is some quick pseudo code on what that solution might look like, I think it should work.
<img src="blah.png" onmousemove="JavaScript:triggerOn(event)" onmouseout="JavaScript:triggerOff(event)"/>
...
<script type='text/javascript'>
var TriggerActive = false;
function triggerOn(e){
e = e||window.e;
if( !TriggerActive){
TriggerActive = true;
// Do something
} else {
// Trigger already fired, ignore this event.
}
}
function triggerOff(e){
e = e||window.e;
if(TriggerActive)
TriggerActive = false;
}
</script>
You can find some great mouse event information including browser compatibility notes here.
Use document.querySelectpor and onload/onready events.
var a = document.querySelector('#a:hover');
if (a) {
// Mouse cursor is above a
}
else {
// Mouse cursor is outside a
}
There is no way to get the mouse coordinates aside from listening for mouse events, namely mousemove, mouseover etc. However, these events are very sensitive in the sense that moving the cursor by just one pixel is enough to trigger them, so having the cursor hover over your image while perfectly still should be somewhat unusual.