I have a real-time app where I am animating certain elements on the screen back and forth upon certain websocket-enabled events firing (e.g event "moveLeft" and event "moveRight"). When the user visits another browser tab and returns after many of these events have fired, they see the entire sequence of animation carry out (using .animate() upon each event firing) even though they are no longer relevant to the user. What I would like instead is for the animations to effectively happen while the user is tabbed away so that when they revisit the tab, they see the current world state and simply miss all those animations that were triggered while in another browser tab.
I can't seem to find any documentation on this issue; it bears similarity to the solution where you need to call .stop() before animating other mutually exclusive things so that you get don't a buildup after excessive mouseover events, but that is not really applicable here. Any tips would be greatly appreciated.
There is a similar question here: slideshow goes crazy if you tab away
In your case, since websockets trigger the animations, one solution could be to watch if the window has focus and only trigger the animations when it's in focus.
Related
I'm setting up an introduction to using Javascript in Adobe Animate HTML5 Canvas for a course I teach. Honestly I haven't done any work in that myself but I've done a bit of Actionscript gaming as well as some Javascript programming outside of Animate, so I'm not entirely clueless.
Part of the exercise is to have a button that opens a URL. It does, but it opens many tabs of it. I'm nto sure how to limit it so it only opens one tab of the URL.
Here's my code. Thanks for your help:
this.urlBtn.addEventListener("mousedown", openPage.bind(this));
function openPage(event) {
window.open('http://www.cartoonthunder.net/', '_blank');
}
mousedown fires while the mouse is down over the element, so it'll happen repeatedly.
Use click instead and it should only fire once.
Is there a cross browser event that can be used to show a message to the user returning to their web page?
For example, a user has ten applications or tabs open. They get a new notification from our app and I show a notification box. When they switch to our tab I want to begin our notification animation.
The activate event is common on desktop applications but so far, on the window, document and body, neither the "activate" or "DOMActivate" do anything when swapping between applications or tabs but the "focus" and "blur" do. This event works but the naming is different and the events that should be doing this are not.
So is the right event to use cross browser or is there another event?
You can test by adding this in the console or page and then swapping between applications or tabs:
window.addEventListener("focus", function(e) {console.log("focused at " + performance.now()) } )
window.addEventListener("blur", function(e) {console.log("blurred at " + performance.now()) } )
Update:
In the link to the possible duplicate is a link to the W3 Page Visibility doc here.
It says to use the visibilitychange event to check when the page is visible or hidden like so:
document.addEventListener('visibilitychange', handleVisibilityChange, false);
But there are issues:
The Document of the top level browsing context can be in one of the
following visibility states:
hidden
The Document is not visible at all on any screen. visible
The Document is at least partially visible on at least one screen. This is the same condition under which the hidden attribute is set to
false.
So it explains why it's not firing when switching apps. But even when switching apps and the window is completely hidden the event does not trigger (in Firefox).
So at the end of the page is this note:
The Page Visibility API enables developers to know when a Document is
visible or in focus. Existing mechanisms, such as the focus and blur
events, when attached to the Window object already provide a mechanism
to detect when the Document is the active document.
So it would seem to suggest that it's accepted practice to use focus and blur to detect window activation or app switching.
I found this answer that is close to what would be needed to make a cross browser solution but needs focus and blur (at least for Firefox).
Observation:
StackOverflow has a policy against mentioning frameworks or libraries. The answers linked here have upvotes for the "best" answer.
But these can grow outdated. Since yesterday I found mention of two frameworks (polyfills) that attempt to solve this same problem here for visibly and isVis (not creating a link). If this is a question and answer site and a valid answer is, "here is some code that works for me" but "Here is the library I created using the same code that can be kept up to date and maintained on github" is not valid then in my opinion it's missing it's goal.
I know above should probably go to meta and I have but they resist changing the status quo for some reason. Mentioning it here since it's a relevant example.
The Page lifecycle API can be used to listen for visibilitychange events.
[This event triggers] when a user navigates to a new page, switches tabs, closes a tab, minimizes or closes the browser, or switches apps on mobile operating systems. Quote
Current browser support
Reference on MDN
Is there a way to detect if the browser window is visible to the user? I know this has been asked before. However, the answers I have seen suffer from the following problems:
Using visibilityChange event. The problem with this approach is that (at least on a Mac) when one uses cmd+tab to switch between applications, this event is not fired.
Using onBlur and onFocus events. These solve the above problem. However, these also fire when a page's visibility does not change. For example, if the browser is open in one half of the screen and another application is open in the other half, then switching between these will cause these events to fire; even though the user has the browser window visible all the time.
Using onPageShow and onPageHide events - these appear quite useless for the task of visibility. For example, onPageHide does not fire either when the page is minimized, or when cmd+tab is used to switch to another application that occupies the whole window.
What is the ideal solution for checking whether the page is visible to the user given the above issues?
Thank you.
Could you use setIterval polling and document.hidden?
nice wrapper Visibility.js
I have made an image gallery in HTML5, JavaScript and CSS by using jQuery mobile. IE Phonegap platform ok.
The images are coming dynamically and are loaded in it, like this:
http://torontographic.com/wordpress/mouseSwipe/mouseSwipe.html
Above mouseSwipe Slider:
TYPE: 'mouseSwipe'
HORIZ: true
plugin available at
torontographic.wordpress.com
The problem coming with it is that I cannot click on the image and go to next page, because two events are occurring together.
The second problem is that I cannot swipe the page up down, from the place where gallery is placed, except the other area where gallery is not present.
To make it more clear, I am making news application in which I have added 5 - 10 gallery like Pulse news application.
I'm a little confused about some of the details of the issue, but I hate to see this question go completely unanswered in case someone else has this issue.
This plugin (mouseSwipe) overrides the default dragging functionality for mobile devices. Whereas normally devices would scroll the page on the mouse starting event, this plugin overrides that behavior to detect click movement across an element. Since it interrupts that functionality, dragging the opposite direction (for scrolling) is also broken. If the plugin were still being maintained by the owner (it doesn't appear to be), it could be updated to fix this issue, or emit events that could be used to manually create the functionality you're wanting.
I assume this is also what is giving you trouble for clicking to go to the specified page.
If you want my honest opinion, I would choose a different library, perhaps one that focuses solely on the swipability of mobile devices, and then handle desktop functionality separately (though, if you're using PhoneGap, it's likely you aren't even publishing this to a web platform for desktops). If it's going to be on the web, you can use modernizr (or the like) to figure out if the device supports touch input, and then implement something like the following:
http://labs.rampinteractive.co.uk/touchSwipe/demos/Image_gallery_example.html
For devices that do not support touch, you could fall back to button/arrow-based navigation (after all, as a desktop user, I do not expect to be able to drag it back and forth with the mouse).
In the file http://torontographic.com/wordpress/mouseSwipe/jquery.mouseSwipe.js onmousedown function has the code below. This will stop the event from the default behaviour and in cases stop captured/bubbled. You may want to look at these or the way event are being handled by the libraries.
e.preventDefault()
Here is more on how to stop JQuery propagation and regular behaviour.
event.preventDefault() vs. return false
What is event bubbling and capturing?
The reason you cannot swipe up and down is likely due to that the "swipe" event is hogging the "movestart" or "move" event.
I ran into a similar problem once when using this plugin:
http://stephband.info/jquery.event.swipe/
Their solution as pointed on on their website was to call the preventDefault method on the event to keep it from blocking as seen here.
jQuery('.mydiv')
.on('movestart', function(e) {
// If the movestart is heading off in an upwards or downwards
// direction, prevent it so that the browser scrolls normally.
if ((e.distX > e.distY && e.distX < -e.distY) ||
(e.distX < e.distY && e.distX > -e.distY)) {
e.preventDefault();
}
});
I have no experience with jQuery mobile, but i would reckon the problems are similar.
I have a web page where users can play flash games. We are now making some changes to the page which requires the games to be embedded with wmode=transparent or wmode=opaque so that we can show HTML elements on-top of the flash games. The problem is that in Internet Explorer (on all versions) the whole page scrolls if a user presses the up/down arrow keys. I've tried everything I can think of and I've spent a whole day searching for a solution without success.
So far I've tried putting the game inside a iframe and I tried disabling the up/down keys with JS, none of which solves my problem.
The requirements are: wmode has to be transparent or opaque and I can't modify the flash games.
The only way to prevent scrolling when using wmode=transparent in Flash is to prevent scrolling using the arrow keys for the whole page. This page summarizes it best.
Basically, when transparent mode is active, the keyboard events in IE are propagated through to the browser; I don't know how to prevent scrolling (haven't tested), but you'd basically have to prevent keyboard scrolling globally.
This discussion highlights a possible workaround for IE8, and an example of the implementation using jQuery here. I don't have a copy of IE on me right now, but it might be worth a try.
AFAIK, though, games in Flash usually don't work very well with wmode=transparent, since focus can be stolen without user interaction. Your best bet would be reworking the page so as not to require Flash to have HTML overlays (even YouTube avoids having transparent set on their page, and they own the whole content).
The user needs to focus the flash movie first before any key actions are intercepted. This is actually a good behaviour, and shouldn’t be changed.
It would be a good idea to somehow ask the user to focus the movie voluntarily, maybe by putting a bit start button on it which they need to click first. Then all key actions should be sent to Flash.
How about some JS magic, if it works.
http://api.jquery.com/keypress/
http://api.jquery.com/event.preventDefault/
Register a KeyPress event handler on the object/embed tags. Let's say you have flash object with id #flashobj
$('#flashobj').keypress( function(event) { event.preventDefault(); } );
Or, more tricky, if the binding on flash object/embed wouldn't work, you can bind the keypress on the whole window, and check something along the lines of:
if (event.target.tagName.toLower() == "object") ...
Mileage may vary, as I remember it event.target is not very reliable...
Hopefully, flash will catch the keyboard event, and the page will ignore it. I know you said you tried it, but your approach might have been different (I suggested two distinctly different ways to do it, one might work)
It seems that there is simply no way around this. We will just have to accept the fact that HTML stuff (FB like chat in our case) will hide behind flash games.
But I still hope somebody proves me wrong :)