IE6 connection interruption in Comet streaming - javascript

I am using a forever frame (COMET streaming technique) and in IE6 whenever a user clicks on a link (to even just basic JavaScript method) the connection is immediately dropped and has to be manually refreshed.
Has anyone come across a similar issue and / or know how to address it?

How to address it: return false from your event handlers (event.preventDefault for listeners etc) so that the link is not followed and so no navigation occurs on a simple left-click. Put all your logic in event handlers attached from script (and not javascript: URL, which are a horrible fragile hack that should never be used).
Further: if it's just a button that does some scripting when clicked, and doesn't actually point to anywhere usefully navigable, it shouldn't be marked up as a link. Ideally it should be a button (input or button with type="button"), which you can then use CSS to style like a link rather than a button if you prefer.
(Another approach, that requires less styling work but has accessibility drawbacks, is to do what SO does and just put an onclick event on a <span> or <div>.)

Related

Which JS events apart from `click` will successfully activate the Fullscreen API?

I've been refactoring some javascript.
Previously, I had an HTML element open to Fullscreen when the user clicked on another element.
Now clicking the latter element initiates a server-side verification, instead.
Once the server-side verification check passes, the page reloads with extra data confirming the user is verified.
N.B. When the page reloads, it does so with a non-negligible amount of extra markup, styles, scripts and vectors. The reason I am re-factoring in the first place is to avoid the need to download all these extra assets (and keep them in the background, on standby) unless and until the user authenticates themselves
The first thing I discovered is that I cannot have the page reload and then have the HTML element immediately open to Fullscreen, because - and this seems entirely reasonable from a UX perspective, Firefox reports:
Request for fullscreen was denied because Element.requestFullscreen() was not called from inside a short running user-generated event handler.
Essentially, unless the user pro-actively interacts with the page, the Fullscreen API will not run.
(In this scenario, the user pro-actively interacted with the page before reload, which is not the same thing.)
So, I thought about it and then added:
document.body.addEventListener('mousemove', () => myElement.requestFullscreen(), {once: true});
Nope. The Fullscreen API still doesn't activate.
To check that I wasn't making an elementary error somewhere else, I tried:
document.body.addEventListener('click', () => myElement.requestFullscreen(), {once: true});
Which does work.
So: some user-interactions will successfully fire the Fullscreen API and others won't.
I have searched through the WHAT-WG HTML Spec but I cannot find a list of events which represent explicit and pro-active user-interactions on a webpage.
Does such a list exist?
Which other events apart from click will successfully activate the Fullscreen API?
Which JS events apart from click will successfully activate the Fullscreen API?
A small number of events will successfully activate the Fullscreen API.
Almost all of these events either imply a user-click or directly reference one:
change
click
contextmenu
dblclick
mouseup
pointerup
reset
submit
touchend
Further to the list of click-based events above, the Fullscreen API may also be activated via:
ScreenOrientation.onchange
Source:
https://www.aworkinprogress.dev/request-fullscreen

Vaadin onbeforeunload event

Is there any Out Of the Box Vaadin 10 (and higher) event similar to window.onbeforeunload in JavaScript?
I've tried to use onDetach() or beforeLeave(), but it only works inside UI, and when user reloads the page or closes the page it's not working.
You can use the approach described in https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload that was already suggested in a comment.
At the same time, I'd urge you to be really careful with beforeunload events since they are in some situations fired even though the user is actually not navigating away from the page.
The most common case is if the user clicks a link that starts a download. In that case the browser will fire the event immediately when the user clicks the link. Slightly later when the browser receives the response headers, it will discover that it's a download and not a new HTML page to display. The end result is then that beforeunload has been fired but the previous page is still kept running.
If you want to use the event for cleanup, then the best approach today is probably a combination of the unload event and then using the new-ish Beacon API for notifying the server that the user has actually navigated away. Integrating this into a Vaadin application will require slightly more JavaScript, but it has the benefit that it will actually work.

Is there a cross browser event for activate in the browser?

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

.focus() doesn't work on chrome mobile when not activated with click. Workaround?

I've come across some strange functionality on chrome, mobile.
When I try to focus on an element on chrome, it doesn't work when you try to just load the input, getItById and do .focus(). However, if you wrap it in an event listener attached to a button, and click the button with your mouse, it works fine.
So, I tried to trick it by seeing if you could call btn.click(), but that doesn't activate the .focus()
Have a go below: On mobile, chrome (at least for iOS), load the page. You should get an alert 'Clicked', but it won't focus on the input. Then, try clicking on the button. You will get both the alert AND the focus works.
I found this interesting and wanted to see if people knew of a workaround.
Link here - jsfiddle
const btn = document.getElementById('button')
btn.addEventListener('click', () => {
alert('clicked')
const input = document.getElementById('input')
input.focus()
})
btn.click()
<input id="input" type="text">
<button id="button">Button</button>
Edit
Another thing I've noticed, is that if you put your phone go to sleep, and open it again, the focus() works without the click.
Edit 2 - added link for mobile
Why does this happen?
Because mobile devices usually need to change the screen dimensions when a keyboard is shown, they come with some restrictions on when a focus event can be triggered. This is intentionally limited browser behavior on touch devices to guarantee a good UX and avoid performance issues of resizing the browser window ( = potentially very expensive style recalculation).
There's some cross browser differences in how far these restrictions go, and some browsers have bugs on top of that.
But in general they all require an actual user interaction to have happened not too long before the focus is programmatically triggered. Using btn.click() is not the same as an actual touch event, and so the browser will ignore it seeing there was no recent touch event.
On a tracking issue on this behavior for Webkit, Apple provides a motivation:
We (Apple) like the current behavior and do not want programmatic focus to bring up the keyboard when you do not have a hardware keyboard attached and the programmatic focus was not invoked in response to a user gesture. Why you may ask...because auto bringing up the software keyboard can be seen as annoying and a distraction to a user (not for your customers, but for everyone not using your app) given that:
We bring up the keyboard, which takes up valuable real estate on screen.
When we intent to bring up the software keyboard we zoom and scroll the page to give a pleasing input experience (or at least we hope it is pleasing; file bugs if not).
This similar issue with the autoplay attribute, which also requires a gesture (or page load) to have happened recently enough, could be helpful in understanding the kind of problem.
How to work around these limitations?
Most of the time
Likely you don't need to, as most code that would trigger focus is running as a response to a user action and will be allowed to trigger focus. I didn't find data yet on how big the window of time is, but I guess it's big enough that in regular cases it's not a problem (unless you set timeouts of course).
A possible problem for those cases is the script would run so long that the event is already considered too long ago. In fact that's what happened in the related autoplay issue, where the code would request some network resource, and only after the response would trigger the video to play. Depending on the speed of the network/device the video would sometimes auto play, and sometimes not.
Technically the same could happen with an input that is only focused after a network delay making it not show the keyboard. As long as your code doesn't do any network requests you won't have this kind of problem.
On page load
This is definitely not a "fix" for the problem, but you can do a best effort to manage focus on page load by using the attribute specifically made for it. This still won't make a keyboard appear when it otherwise wouldn't.
The autofocus attribute is at least partially supported on all browsers.
Perhaps just calling focus() directly in a script on page load works, but again there's a chance that this code runs too long after the page started being displayed, especially on slower devices. This probably also happens when adding HTML with the autofocus attribute programmatically (e.g. React). If the initial HTML contains the autofocus attribute on the right element that shouldn't occur.
There is deinfitely something weird happening here.
It seems "part" of the DOM thinks that the input element is in focus initially, but chrome does not complete the focusing. For exmaple, if the background is set with:
document.activeElement.style.backgroundColor = "pink";
Then the input element's background is pink. So, some part of chrome's DOM thinks the input element is in focus.
Initially, in my case, the input element is rendered by chrome in its default non-focus styling.
The alert() seems to be interfering with the process. In my case, taking the alert out had the effect of changing the styling of the input element from non-focus styling to in-focus styling, but the cursor did not appear in the input element, nor did the pop up keyboard appear.
By:
removing the alert
wrapping the click inside a function
calling that function on load
fixed the problem in my case. Initially now the element is in-focus styled, the cursor appears in the element's box, and the keyboard pops up.
The solution to the posting by #HJo, January 2019, is to replace:
btn.click();
with:
function load() { btn.click(); }
remove the alert(),
and make the body tag as:
<body onload="load()">
#Peter. If this does not fix your problem too, can you please provide minimal code for your context.
const event = new Event('tap');
const btn = document.getElementById('button')
const input = document.getElementById('input')
btn.addEventListener('click', () => {
prompt('clicked')
input.focus();
})
window.onload = function(){
btn.dispatchEvent(event);
}
}
The code above works when the website tab is just opened, but not on reload for some reason. I tested it on an Ipad and Iphone so hopefully it works well on your end too.
Here's a link to a repl:
https://r.hackinggo306.repl.co
Edit: This seems to be the closest I can get, but also acknowledge the fact that mobile devices might be deliberately preventing this. (It would be annoying if a website looped this.)
On the mobile, you will need to use touchstart event instead of click event.
You can find it here. Hope this helps.
I think, this problem can occur, because of the your JavaScript script is executed before the DOM is Mounted.
so you can do different things,
One Thing
add defer keyword to script tag. Basically it does is, that script is only run after the DOM is mounted. See
Second Thing
Wrap window.onload event with your input focus functionality.
<script type="text/javascript">
window.onload = function () {
const btn = document.getElementById('button');
const input = document.getElementById('input')
input.focus()
}
</script>
window.onload event is only fired when the DOM is finishing mounting.so that may be your JavaScript script run before the input element is mounting.so add onload event to your code.see this

Prevent scrolling in IE when flash has focus

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 :)

Categories