A better method to detect phone notch? - javascript

I have a method to detect the notch on iPhones and it works...but I just found out it doesn't work well. About 1 out of 5 app starts, I see the function reporting that the phone doesn't have the notch when in fact it does.
When my app deviceReady() state is activated, I then check to see if the device has the notch then assign the true/false value to a variable that I use later on. As mentioned, about 1 in 5 times it returns false. I think its a timing thing, the function is evaluating the DOM before the DOM has fully loaded causing the detection method to fail.
function hasNotch() {
if (CSS.supports('padding-bottom: env(safe-area-inset-bottom)')) {
var div = document.createElement('div');
div.style.paddingBottom = 'env(safe-area-inset-bottom)';
document.body.appendChild(div);
setTimeout(function() {
var calculatedPadding = parseInt(window.getComputedStyle(div).paddingBottom, 10);
document.body.removeChild(div);
if (calculatedPadding > 0) {
errMgmt("preIndex/hasNotch ",101.1,"READY: Notch Detected") ;
return true ;
} else {
errMgmt("preIndex/hasNotch ",101.2,"READY: Notch Not Detected") ;
return false ;
}
},100) ;
} else {
errMgmt("preIndex/hasNotch ",101.3,"READY: Notch Not Supported") ;
return false ;
}
}
$ionicPlatform.ready(function() {
$rootScope.hasNotch = hasNotch() ;
...
}) ;
Then in my landing page controller:
.controller('HomeCtrl', function($rootScope,$scope,$state,$stateParams,$ionicModal,$q,apiService) {
if ($rootScope.hasNotch == true) {
.. do css stuff ..
}
}) ;
When it fails to detect, its always the message READY: Notch Not Detected returned...not once has it returned the READY: Notch Not Supported which means the CSS.supports is working, but not part regarding the calculatedPadding.
The true/false value is needed in the Controller of the landing page, and when it fails its causing CSS layout issues. Either the hasNotch() is too slow and the app init is triggering the landing page faster than the response from hasNotch() or there is actually something else wrong with my function.
On a side note, I have researched different methods to detect the notch on Android phones - the two plugins seem to have issues and/or aren't really supported anymore. Was hoping for a solid solution for Android....or even better, a universal solution for both iOS types.

I came up with a solution but I still hoping there is a better way. Something that can detect a phone notch during app initialization versus having to rely on DOM evaluations. I have tested the app over 25 times and so far this new method has detected the notch every single time. As I code other things I will continue to evaluate the outcome, but so far so good. Here is what I did.
I removed the check from deviceReady:
$ionicPlatform.ready(function() {
$rootScope.hasNotch = hasNotch() ;
...
}) ;
And in my landing page controller:
.controller('HomeCtrl', function($rootScope,$scope,$state,$stateParams,$ionicModal,$q,apiService) {
$scope.hasNotch = null ;
var watchNotch = $scope.$watch('hasNotch',function() {
//begin watching for var change
deviceData.hasNotch = $scope.hasNotch ;
$scope.doSomething() ;
watchNotch() ; // kill watch
}) ;
if (ionic.Platform.isIOS()) {
$scope.hasNotch = hasNotch() ;
} else {
deviceData.hasNotch = false ;
$scope.doSomething() ;
watchNotch() ; // kill notch
}
}) ;
Now I just need to go find a reliable plugin to detect Android notches....easier said than done.

Related

Fix header after scrolling Angular 4

I am having issue fixing the header after scrolling, I tried a lot of stuff but can't get it to work. I checked this thread but it doesnt work for me: Angular 4 #HostListener Window scroll event strangely does not work in Firefox . This is my component structure:
Layout
Steps
Routes
Inside steps is my header which I want to fix, after scrolling for 50px. Inside Layout is some other content like a div with logo background (above the content of steps).
This is what I tried inside Steps.ts
#HostListener('window:scroll', [])
onWindowScroll() {
const number = window.scrollY;
if (number > 40) {
this.fixed = true;
} else if (this.fixed && number < 10) {
this.fixed = false;
}
}
but the problem is that scroll is not triggering at all. I found examples
where scroll logs the event, but for me it doesn't work (I tried with $event as well). Anyone has a solution?
Found a solution. On my layout component I put a function
(scroll)="onWindowScroll($event)"
and in layout component i used:
#HostListener('window:scroll', ['$event'])
onWindowScroll($event) {
const number = $event.target.scrollTop;
if (number > 40) {
this.fixed = true;
} else if (this.fixed && number < 10) {
this.fixed = false;
}
}
I removed Steps component since I didnt need it anymore, all the content is inside layout now.
In Angular 5+ it works a little differently:
const number = $event.target.scrollingElement.scrollTop || $event.target.documentElement.scrollTop;
Since some people come via Google to this question:
I'm quite a fan of moving logic like this into something re-useable. For Angular this would mean a directive. Therefore as I run into this issue myself I created a library from my code that at least has some tests and support across many browsers. So feel free to use this tested piece of code instead of polluting your components with more code.
https://w11k.github.io/angular-sticky-things/
With the code I see in the answer I did run into some issues. In another SO I found this solution. It is crucial to determine the offsetY of the header element correctly.
// Thanks to https://stanko.github.io/javascript-get-element-offset/
function getPosition(el) {
let top = 0;
let left = 0;
let element = el;
// Loop through the DOM tree
// and add it's parent's offset to get page offset
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return {
y: top,
x: left,
};

Protractor: How do I get the current browser width?

I want some helper function code to run based on whether the browser is in "desktop" mode, which is default, or "mobile" mode, which some specs require for mobile only functionality. Height is always 800, but width can be 600 or 1280.
login: function() {
var self = this;
var browserSize = browser.manage().window().getSize().then(function(size) {
// size is still an unresolved promise ;.;
return size;
});
// Go to login page
browser.get(browser.baseUrl); // Will redirect authed users to the application
// If not at the login page, logout first
if (browser.getCurrentUrl() !== browser.baseUrl) {
if (browserSize.width == 600) {
self.mobileLogout();
} else {
self.desktopLogout();
}
}
self.loginPage.login();
}
How do I either resolve the promise getSize returns or determine the browser width some other way?
You were so very close! This worked for me just now:
var browserSizeOfMe = browser.driver.manage().window().getSize().then(function(size) {
console.log(" BROWSER SIZE "+ JSON.stringify(size) );
return size;
});
You don't have to approach the problem of differentiating mobile and desktop judging by the size of the browser window. Instead, you can access the configured capabilities via getCapabilities(), please see examples at:
Protractor: accessing capabilities
you can get the browser width using this script
var width = window.innerWidth || document.body.clientWidth;
but i dont think this answers your problem
There was indeed too many promises going on in this function. I had to nest needing the width and the current url so things would be defined and usable at the correct times.
Roughly the working code:
login: function() {
var self = this;
browser.get(browser.baseUrl);
browser.getCurrentUrl().then(function(url) {
if(url !== browser.baseUrl) {
browser.manage().window().getSize().then(function(size) {
if (size.width == 600) {
self.mobileLogout();
} else {
self.desktopLogout();
}
}
}
self.loginPage.login();
}
}
It can be done using "viewport", have a look following link
http://www.w3schools.com/css/css_rwd_viewport.asp

iOS 8 Bug - OnUpdateReady never called again when device returns from sleep

When an iOS 8 device running a Web Application (i.e. launched from a shortcut on the Home Screen) returns from it's Sleep state all asynchronous web requests made fail to trigger the OnUpdateReady callback.
The problem is quite easy to reproduce - simply put the two code files below on any web server and give it a try.
Has anyone else run into this issue? If so is there any workarounds?
I'm posting this to try to attract attention to this bug in iOS 8 that has essentially ruined all of my web applications - we've had to recommend to NOT upgrade beyond iOS 7. And yes, I've posted the problem on Apple Bug Reporter but I think no one is looking at these since it has been a long time.
app.manifest
CACHE MANIFEST
# 2014-09-24 - Test
CACHE:
default.html
default.html
<!DOCTYPE html>
<html manifest="app.manifest">
<head>
<title>Test Harness</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="HandheldFriendly" content="true" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<script language="javascript" type="text/javascript">
var Test = new function () {
var _GetEnd = function (oResult) {
var sResult = ': ' +
((oResult.Value === true)
? 'Success'
: 'Failure<br>' + oResult.Reason) +
'<br>';
var oLog = document.getElementById('idLog');
oLog.innerHTML = (new Date()) + sResult + oLog.innerHTML
setTimeout(_GetBegin, 1000);
};
var _GetBegin = function () {
var sURL = 'app.manifest';
var hAsyncCallback = _GetEnd;
try {
var oRequest = new XMLHttpRequest();
oRequest.onreadystatechange =
function () {
if (oRequest.readyState != 4) return;
if (oRequest.status != 200) {
hAsyncCallback({ Value: false, Reason: oRequest.responseText });
} else {
hAsyncCallback({ Value: true, Reason: null });
}
};
oRequest.open('GET', sURL, true);
oRequest.send(null);
} catch (e) {
alert('Critical Error: ' + e.message );
}
};
this.Start = function () { _GetBegin(); }
};
</script>
</head>
<body onload="Test.Start();">
<ol>
<li>Put both app.manifest and default.html on a web server.</li>
<li>Make sure this page is being launched from the Home screen as a web application.</li>
<li>Press the sleep button while it is running.</li>
<li>Press the wake button and unlock the phone to get back to this screen.</li>
<li>Under iOS7x the page continues, under iOS8 the onreadystatechange never gets called again.</li>
</ol>
<div id="idLog"></div>
</body>
</html>
Installing iOS 8.1.1 fixes this.
I am also seeing the same issue, though my example is much simpler. Simply have a webclip application with
<script>
window.setInterval(function(){
console.log("Johnny Five Alive! : " + new Date());
},1000);
</script>
on the page. Inspecting the console, after the sleep wakes up, no more console output. This works fine on iOS7 (my actual application is a complicated angularJS thing, I just boiled down the issue to this). Have you had any response on your bug report?
Our workaround (for AJAX) is:
Detect iOS8 (indeed 8.0.2 still has this) (also see this for other workaround: How to resume JavaScript timer on iOS8 web app after screen unlock?)
Remove the normal eventListeners, but keep the onProgress one
...
this.onProgress = function(e)
{
var position = e.position || e.loaded;
var total = e.totalSize || e.total;
var percentage = 0.0;
if(total != 0)
{
percentage = position / total;
}
if(percentage == 1) {
if( this.isIOS8() ) {
recovery_uuid.get(uuid, _.bind(this.ios8ScriptReturn, this));
}
}
}
...
//this gets called when the script with this UUID is injected
this.ios8ScriptReturn = function(uuid, value) {
//then we create a simpler non real one
this.xhr = {};
this.xhr.readyState = 4;
this.xhr.status = 200;
this.xhr.responseText = value;
this.xhr.onreadystatechange = null;
this.xhr.isFake = true;
//fake stateChnage
this.onReadyStateChange();
}
add a UUID to each request
if( this.isIOS8() ) {
ajaxInfo.url += '&recoveryUUID='+ajaxInfo.uuid;
}
Then still perform the XHR Send (that actually works fine, server gets and send back fine).
server Side save the 'result' in database/file with the UUID as index/part of filename
//detect the need for saving the result, and save it till requested
if(isset($_GET['recoveryUUID'])) {
$uuid = $_GET['recoveryUUID'];
RecoveryUUID::post($uuid, $result_json_string);
}
On the client create a little helper global object that listens to the code injects and redirects them to the onProgress handler.
var RecoveryUUID = (function (_root) {
function RecoveryUUID() {
this.callbacks = {};
}
var proto = RecoveryUUID.prototype;
proto.onLoaded = null;
proto.set = function(uuid, value) {
console.log('RECOVERY UUID: Received DATA: '+uuid+' value: '+value);
if(typeof this.callbacks[uuid] != 'undefined') {
this.callbacks[uuid](uuid, value);
delete this.callbacks[uuid]; //auto remove
}
if(this.onLoaded != null) {
this.onLoaded(uuid, value);
}
var script = document.getElementById("recoveryScript_"+uuid);
script.parentElement.removeChild(script);
}
proto.getURL = function(uuid) {
return "http://"+window.location.hostname+":8888/recoveryuuid/index.php?uuid="+uuid;
}
proto.get = function(uuid, callback) {
var script = document.createElement("script");
script.setAttribute("id", "recoveryScript_"+uuid);
script.setAttribute("type", "text/javascript");
script.setAttribute("src", this.getURL(uuid));
if(typeof callback != 'undefined') {
this.callbacks[uuid] = callback;
}
document.getElementsByTagName("head")[0].appendChild(script);
}
return RecoveryUUID;
})();
//global - just so the injected script knows what to call
recovery_uuid = new RecoveryUUID();
The script that is loaded immediately executes (pushes, since setInterval is dead as well).
// this is: http://"+window.location.hostname+":8888/recoveryuuid/index.php?uuid=...."
<?php
header('Cache-Control: no-cache, no-store, must-revalidate, post-check=0, pre-check=0 '); // HTTP 1.1. //iOS force this file to keep fresh
header('Pragma: no-cache'); // HTTP 1.0.
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header('Content-type: application/javascript; charset=UTF-8');
if(isset($_GET['uuid'])) {
$uuid = $_GET['uuid'];
$out = 'recovery_uuid.set('.json_encode($uuid).','.json_encode(RecoveryUUID::get($uuid)).');';
echo $out;
}
?>
Below is a simple filebased results implementation.
<?php
class RecoveryUUID {
static public function getFileName($uuid) {
return SOMESTATIC LOCATION.$uuid.'.json';
}
static public function post($uuid, $stdClassOrString) {
$data = '{ "data": '.json_encode($stdClassOrString).', "uuid": '.json_encode($uuid).' }';
file_put_contents(self::getFileName($uuid), $data);
}
//might not work first time as the script tag might request this file before it was written.
//so we wait just a bit.
static public function getFull($uuid) {
$tries = 10;
$filename = self::getFileName($uuid);
while ($tries > 0) {
if(file_exists($filename)) {
if (is_readable($filename)) {
$data = #file_get_contents($filename);
if($data !== FALSE) {
unlink($filename);
return $data;
}
}
}
$tries = $tries -1;
usleep(250000);//wait 0.25 secs ...
}
$data = new stdClass();
$data->uuid = $uuid;
$data->data = 'ERROR RECOVERYUUID: timeout on reading file';
return $data;
}
static public function get($uuid) {
$decoded = json_decode(self::getFull($uuid));
if( $decoded->uuid == $uuid ) {
return $decoded->data;
}
return null;
}
}
?>
As we do not use JQuery all we needed to do was add the extra logic in our Ajax class, and of course the Saving to Database for all requests..
Downsides:
Nasty
Will keep on adding memory footprint for each call (for us not an issue as the memory is cleared between window.location.href calls (we do not use SPA) so eventually will fall over.
Extra serverside logic.
Upsides:
Works until memory runs out (removing script tags, which we do does not remove the memory associated)
Comments:
You could of course just send everything with the 'call' but we wanted to have minimal server side impact (or not much work for us anyway) + we presume this will be fixed and means our 'user' code has 0 impact.
Weird, Apple just closed my bug and referred to the same bug number. Also a web app but I found css3 transitions to stop working after screen lock see below:
Engineering has determined that your bug report (18556061) is a duplicate of another issue (18042389) and will be closed
My report:
If you add an HTML app to the home screen and open it, all CSS3 transitions work correctly. Without closing the app and pressing screen lock the transitions seem to stop and can cause the ui to appear to freeze. For example if an absolute overlay is triggered (opacity:0 to opacity:1) it remains invisible making the app appear not to work
Ajax requests, Timer functions and WebkitAnimation are broken after a lock-screen on iOS8.
For the Ajax and Timer functions, we are using this solution in our system:
How to resume JavaScript timer on iOS8 web app after screen unlock? (link to the gitHub in the comment).
It is not exactly part of the question but I would like to share our workaround with CSS3 animations and events, since it may help somebody in the future.
For the webkitAnimation, we found that redrawing the element with the animation on, or more drastically the body would restart animations and events applied to them (webkitAnimationEnd for instance, which is used heavily by jquery-mobile).
so our code gives something like:
document.body.style.display='none';
setTimeout( function() { document.body.style.display = 'block'; }, 1);
You may or may not need the setTimeout function on the second statement. Most interesting thing is, once it has been redrawn, it will never go frozen again no matter how many lock screens come up after that...
The webapp environment is so horribly broken when resuming after screen lock I don't see how (a) Apple could ignore this indefinitely and (b) how any webapp can confidently work around the crippled environment.
My solution is to detect resume after sleep using setInterval (which stops working after the resume) and then posting an alert() to the user stating that the app has to be re-launched from the home screen because iOS cannot resume it.
It just so happens that alert() is also broken after the resume--it displays the alert and then the webapp exits to the home screen when the user hits OK! So this forces the user to re-launch.
The only issue when the user re-launches is the handling of apple-mobile-web-app-status-bar-style. I have this set to black-translucent which normally sets the status bar content to black (on light backgrounds) or white (on dark backgrounds). On the first re-launch after resume, the status bar content is always black. On subsequent re-launches (not interrupted by sleep/resume) the behavior returns to normal.
What a mess. If I was responsible for this at Apple I'd be embarrassed, and here we are with 8.1 and it still hasn't been fixed.

Send Geolocation in background service [Titanium]

I'm creating an app for Android and iOS with titanium which sends a new Geolocation to a server every 5 seconds for as long as the server runs. On iOS however the app stops sending those locations after a random interval. Although i myself are not completely convinced this is due to the fact that the app pauses in iOS(Since it stops randomly and not on a fixed time) i'm still eager to try and be certain.
However; i really have NO CLUE to do this whatsoever. I've created a background service in an eventListener to see what happens and it starts logging right away(I've put a console log in it for now). Nonetheless, my geolocation is still ticking normally aswell.
Now, could someone please give me some pointers on how to get through this? Do i want to stop my normal geolocation listener and let the BG service take over? Or does the BGservice keep the geolocation eventlistener in my normal code active now?
At this point i'm afraid to say that i'm pretty much desperate to get any help, haha!
Here's my geolocation handling now, along with the BGservice:
//Start button. listens to an eventHandler in location.js
btnStart.addEventListener('click', function (e) {
if( Titanium.Geolocation.locationServicesEnabled === false ) {
GPSSaved.text = 'Your device has GPS turned off. Please turn it on.';
} else {
if (Titanium.Network.online) {
GPSSaved.text = "GPS zoeken...";
//Empty interval and text to make a clean (re)start
clearInterval(interval);
//Set a half second timer on the stop button appearing(So people can't double tap the buttons)
stopTimeout = setTimeout(showStopButton, 1000);
//Switch the textlabels and buttons from startview to stopview
stopText.show();
startText.hide();
btnStart.hide();
//Locationhandler
location.start({
action: function (e) {
//Ti.API.info(e.coords.longitude);
if (e.coords) {
//If the newly acquired location is not the same as the last acquired it is allowed
if (e.coords.longitude != lastLon && e.coords.latitude != lastLat) {
//set the last acquired locations+other info to their variables so they can be checked(and used)
lastLat = e.coords.latitude;
lastLon = e.coords.longitude;
lastKnownAltitude = e.coords.altitude;
lastKnownHeading = e.coords.heading;
lastKnownSpeed = e.coords.speed;
if (lastLat != 0 && lastLon != 0) {
setGPSholder(lastLat, lastLon, lastKnownAltitude, lastKnownHeading, lastKnownSpeed);
} else {
GPSSaved.text = 'Geen coordinaten.';
}
}
}
}
});
/*
A second interval which shows a counter to the user and makes sure a location is sent
roughly every 5 seconds(setInterval isn't accurate though)
A lot of counters are tracked for several reasons:
minuteInterval: Counter which makes sure the last location is sent after a minute if no new one is found in the meantime
secondsLastSent: The visual counter showing the user how long its been for the last save(Is reset to 0 after a succesful save)
*/
interval = setInterval(function () {
minuteInterval++;
minuteIntervalTest++;
secondsLastSent++;
counterBlock.text = "De laatste locatie is " + secondsLastSent + " seconden geleden verstuurd";
//If the counter is higher than 5 send a new coordinate. If at the same time the minuteInterval is over a minute
//The last location is put in the array before calling the sendCoordinates
if (counter >= 5) {
if (minuteInterval > 60) {
if (lastLat != 0 && lastLon != 0) {
setGPSholder(lastLat, lastLon, lastKnownAltitude, lastKnownHeading, lastKnownSpeed);
}
}
counter = 0;
sendCoordinates();
Ti.API.info(1);
} else {
counter++;
}
if (minuteIntervalTest > 60) {
sendTestRequest();
}
}, 1000);
if (Titanium.Platform.osname == 'iphone' || Titanium.Platform.osname == 'ipad') {
//var service = Ti.App.iOS.registerBackgroundService({url:'send_geolocation_service.js'});
var service;
// Ti.App.iOS.addEventListener('notification',function(e){
// You can use this event to pick up the info of the noticiation.
// Also to collect the 'userInfo' property data if any was set
// Ti.API.info("local notification received: "+JSON.stringify(e));
// });
// fired when an app resumes from suspension
Ti.App.addEventListener('resume',function(e){
Ti.API.info("app is resuming from the background");
});
Ti.App.addEventListener('resumed',function(e){
Ti.API.info("app has resumed from the background");
// this will unregister the service if the user just opened the app
// is: not via the notification 'OK' button..
if(service!=null){
service.stop();
service.unregister();
}
Titanium.UI.iPhone.appBadge = null;
});
Ti.App.addEventListener('pause',function(e){
Ti.API.info("app was paused from the foreground");
service = Ti.App.iOS.registerBackgroundService({url:'send_geolocation_service.js'});
Ti.API.info("registered background service = "+service);
});
}
} else {
stopGPS();
GPSSaved.text = "Geen internetverbinding.";
}
}
});
As you can see there's some counters running in an interval to decide if a geolocation should be sent every 5 seconds or every minute(If no new location since the last is found)
tl;dr: I want geolocations to be sent every 5 seconds but somehow iOS(iPhone 4s and 5 tested) stop sending after a random timeperiod and restart sending the moment i get the phone out of standby.
actually background service has a limitation to stop after 10 mins so if you want to catch location when device is in background mode then you need to set mode tag in tiapp.xml file.
just refer this online doc for how it works.
http://docs.appcelerator.com/titanium/3.0/#!/guide/tiapp.xml_and_timodule.xml_Reference-section-29004921_tiapp.xmlandtimodule.xmlReference-LegacyiPhonesection

Flash Stage Losing Focus

I built this incredibly brilliant scrolling thumbnail image viewer for a client in Flash Actionscript 3. (Basically it just scrolls up or down depending on the mouse position). It works so so, (I can never get the percentages right so that it shows the top most image) but, that's beside the point. What is REALLY irking me is when I have the browser window open with my .swf loaded and I click on another app on my desktop, the stupid scrolling thumbnail area in the browser window starts to freak out.
"Where is my mouseY??!?!?!?" I assume it is thinking.
Is there a stage.Unfocus event I can tell my scrolling thumbnail area to STFU with?
I'd even consider writing some Javascript to call a flash function, if that's a preferred technique.
function checkMousePos(e:Event):void
{
if(mouseX < 145){
try{
var sHeight:int = MovieClip(root).stageHeight;
}catch(Error){
trace("stage not loaded");
}
if(mouseY > (sHeight/2) + 100){
if(tHolder.y-50 > - (compHeight-sHeight)){
Tweener.addTween(tHolder, {y:tHolder.y - 90, time:1,transition:"easeOutCubic"});
}
}else if(mouseY < (sHeight/2) - 100){
if(tHolder.y+50 < 80){
Tweener.addTween(tHolder, {y:tHolder.y + 90, time:1,transition:"easeOutCubic"});
}else{
Tweener.addTween(tHolder, {y:80, time:1,transition:"easeOutCubic"});
}
}
}
}
I suggest detecting the window focus events onblur and onfocus ( http://www.devguru.com/technologies/ecmascript/quickref/evHan_onBlur.html ) in Javascript then sending an enable / disable call through to the SWF file using ExternalInterface ( http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/external/ExternalInterface.html ) So inside your HTML you might have something like this (assuming swfobject here, but this isn't necessary http://code.google.com/p/swfobject/ ):
swfobject.embedSWF("mySWF", "mySWFId", swfWidth, swfHeight, "10.0.0", "", flashvars, params, attributes);
window.onblur=function () {
if ( document.getElementById("mySWFId").disableMouseScrolling) {
document.getElementById("mySWFId").disableMouseScrolling();
}
}
window.onfocus=function () {
if ( document.getElementById("mySWFId").enableMouseScrolling ) {
document.getElementById("mySWFId").enableMouseScrolling();
}
}
And inside your SWF file some equivalent ExternalInterface code to hook up the methods:
public class MyApplication extends ...
{
public function MyApplication ():void
{
ExternalInterface.addCallback("disableMouseScrolling", disableMouseScrolling);
ExternalInterface.addCallback("disableMouseScrolling", enableMouseScrolling);
...
}
private function disableMouseScrolling ():void
{
}
private function enableMouseScrolling ():void
{
}
...
}
Hope this helps. I've used it with IE8, Firefox 3 and Crome 4.
Regards,
stage.addEventListener(Event.MOUSE_LEAVE, function(e:Event):void {});

Categories