I'm using a javascript library, DetectRTC, to detect if the browser can use microphone and other stuff.
if(DetectRTC.isWebsiteHasMicrophonePermissions){
//Is ok
}else{
//Can't use microphone
}
The site has the permissions to use the microphone, but DetectRTC.isWebsiteHasMicrophonePermissions is still false. So I tried to print the object on the console and I get that isWebsiteHasMicrophonePermissions is set to true. But when I print the variable alone, it changes to false again.
console.log(DetectRTC); //isWebsiteHasMicrophonePermissions: true
console.log(DetectRTC.isWebsiteHasMicrophonePermissions) //false
Is this a bug or something? How can I fix it?
As covered in the docs, you need to use DetectRTC.load() to wait for detecting audio/video input/output devices.
See this part of the docs for further info.
// This is too early
console.log(DetectRTC.hasMicrophone);
DetectRTC.load(() => {
// This is reliable
console.log(DetectRTC.hasMicrophone);
});
<script src="https://cdn.rawgit.com/muaz-khan/DetectRTC/master/DetectRTC.js"></script>
Related
I use ionic serve to run my app on localhost.
how can I know when I'm in browser and not in android?
I tried:
navigator.platform // MacIntel
navigator.platforms // undefined
ionic.Platform.is('BROWSER') // false
navigator.userAgent // ...iPhone... => i'm in chrome device mode
Thank you!
There's probably more than one way to do it, but a simple one is that cordova will only be defined on Android/iOS so you could do
if (window.cordova) {
// running on device/emulator
} else {
// running in dev mode
}
Edit
Some text editors and TypeScript parsers may complain that Property 'cordova' does not exist on type 'Window'. In order to work around that, you can use the following:
if ((<any>window).cordova) {
// running on device/emulator
} else {
// running in dev mode
}
By explicitly casting to type any you can avoid transpiler errors, and still accomplish what you're trying to do.
I found I can use
ionic.Platform.platforms[0] == "browser"
to check if the application is running in a browser or not.
Important thing, ionic.Platform.platforms is set only after $ionicPlatform.ready event is fired.
Checking if window.location.hostname is equal to localhost will work too.
if(window.location.hostname === "localhost"){
return 'http://localhost:8100/api/';
} else {
return 'https://some-api.com/';
}
use
if(ionic.Platform.isWebView()){
console.log('i am in a browser webview!');
}
or
console.log(ionic.Platform.platform());
That will tell you what platform you are on. Webview or android or ios or whatever.
For now, in my Ionic 1 app (using last version 3.9.x, but with --type ionic1), ionic.Platform.platform() when i am in desktop is returning "linux", not "browser". And window.cordova now exists in browser, but you can check if window.cordova.platformId == 'browser'. It seems work here.
Just a little correction to Mirko N. answer.
Typescript will actually return error if you use cordova directly or as a child of window object.
The proper answer is to check if window has cordova as own property.
if(window.cordova) //returns error "Property 'cordova' does not exist on type 'Window'."
if(window.hasOwnProperty('cordova')) //Proper Check
I'm using this function to detect if the device is a touch device:
function is_touch_device()
{
return !!('ontouchstart' in window) || !!('onmsgesturechange' in window);
};
Got this function from here: What's the best way to detect a 'touch screen' device using JavaScript?
But since Chrome 25 (25.0.1364) it returns true on my desktop which isn't a touch device.
Also I've updated IE9 to IE10 and it returns true in IE!
Searched around but couldn't find anything useful to fix this except using a something like this: http://detectmobilebrowsers.com/
What do you recommend?
I'm looking forward to your responses!
The code works just fine, the browser is able to understand touch events, just because your screen isn't touchable doesn't mean that the browser doesn't support the functionality. What you are looking to test is a hardware capability which isn't really testable. You can always use different ways though of seeing if the user is actual using a touch interface after touching it once, such as this article describes, or many others that larger libraries use such as Modernizer.
As a reference the code actually used in the article above is:
function isTouchDevice() {
var el = document.createElement('div');
el.setAttribute('ongesturestart', 'return;');
if(typeof el.ongesturestart == "function"){
return true;
}else {
return false
}
}
This seems to work:
function isTouchEnabled() { return !!document.createTouch; }
You could use Modernizr to detect touch capability.
This question is very similar to What's the best way to detect a 'touch screen' device using JavaScript? and should perhaps be considered a duplicate.
i was experiencing a false positive IE10 touch issue as well when I was visiting the site i've been working on from my laptop. The original is_touch_device method, i used basically the same thing. I modified the latter half of that statement to be the following:
function is_touch_device()
{
return !!('ontouchstart' in window) || (!!('onmsgesturechange' in window) && !!window.navigator.maxTouchPoints);
}
window.navigator.maxTouchPoints seems to be something specific in IE10 based on this post: http://msdn.microsoft.com/en-us/library/hh772144(v=vs.85).aspx
You can use 51dergees.mobi for detection on the server appropriately changing page view. It has HasTouchScreen, IsSmartPhone, IsTablet properties etc.
I'm looking for a neat way to detect whether postMessage in the browser supports the sending and receiving of objects or just strings. I figure that someone out there must have wrote something that does this but I have not managed to find a solution.
I'm using postMessage to send data to/from a WebWorker. Whilst detecting whether the browser supports workers is straight-forward, detecting whether objects can be send via postMessage has proved more difficult.
I'd like to write a simple detection function. So, if the browser supports the sending of objects to use that. If only strings are allowed I can fallback to using JSON.stringify(). I'll probably assign the function to a dojo/has test (although this is not relevant to the question/answer).
What have other people done to solve this problem? Any advice would be great, I'm new to both WebWorkers and postMessage. Thanks in advance.
I found an even easier way to detect if postMessage only supports strings or if it supports other types. Simply add a custom toString-method on the object. When trying to send an object with postMessage in IE8 and IE9 they will be converted to a string with the toString-method on the object. Since browsers that support sending objects doesn't call toString we can use this to our advantage. This test is not async, so you'll get the result instantly. Haven't tested this with web-workers, but I suppose you can use the same technique.
var onlyStrings = false;
try{window.postMessage({toString:function(){onlyStrings=true;}},"*");}catch(e){}
console.log("Browser only supports postMessage with strings? " + onlyStrings);
Tested in IE8, IE9, IE10 and latest version of Chrome, Firefox, Safari and Opera:
http://jsbin.com/igowoFaj/1/edit?js,console
Update: Did a BrowserScope test with many more tests and browsers. Conclusion is that it's safe to send clonable objects, arrays, numbers, pixel data and array buffers if onlyStrings is false. In theory all browsers that allow sending objects should use the structured clone algorithm, but the Android browser and Opera Mobile has quirks. The BrowserScope test result is a bit hard to read, because a 0 for send_xxx is only problematic if the browser actually has support for that type, so check supports_xxx too. If they are equal it's ok, but it's a bug if the browser has support but can't send (when onlyStrings is false).
You could try to perform an action BEFORE resuming your script. You could try this:
dummy_task.js
self.onmessage = function(event) {
self.postMessage(event.data);
};
javascript
workerSupportObject(callback);
function workerSupportObject(callback) {
var callbackIsCalled = false; // to make sure callback isn't run twice
var worker = new Worker('dummy_task.js'); // create a worker
// create event
worker.onmessage = function(event) {
// if the value is the same as we sent, it probably works
if(!callbackIsCalled) callback.call(null, event.data.value === 'dummy');
callbackIsCalled = true;
};
try {
// send dummy JSON data
worker.postMessage({'value': 'dummy'});
} catch(e) {
// oh... an error... clearly that's a no.
if(!callbackIsCalled) callback(null, false);
callbackIsCalled = true;
}
}
function callback(objectSupported) {
console.log('Worker supports objects: ', objectSupported);
}
I wanted to know the same thing. I created this script to detect if an object could be passed in postMessage by a simple callback to the current window. You will see IE 9 return false, IE 10 returns true.
http://jsfiddle.net/milesplit/DvqqH/
var supportsPostObject = false;
(function(){
var callback = function(e) {
supportsPostObject = (typeof(e.data)!='string');
};
(window.addEventListener) ?
window.addEventListener('message', callback) :
window.attachEvent('onmessage', callback);
('postMessage' in window) && window.postMessage({}, '*');
})();
setTimeout(function(){
alert(supportsPostObject);
}, 0);
postMessage also works between iframes; assuming that the behavior is the same between workers and frames, you should try the following or something like it:
<html>
<body>
<iframe id='if'>
</iframe>
<script>
var iframe = document.getElementById('if');
var iframeScript = iframe.contentDocument.createElement("script");
iframeScript.appendChild(
iframe.contentDocument.createTextNode(
'window.addEventListener("message", function(e) {console.log(e.data);}); console.log("listener attached");'));
iframe.contentDocument.body.appendChild(iframeScript);
iframe.contentWindow.postMessage("asdf", "*");
iframe.contentWindow.postMessage({'whatAmI': 'an object, maybe?'}, "*");
</script>
</body>
</html>
You may need to replace console or console.log to be able to see results, but on Chrome, this gets me
listener attached about:blank (1):1
asdf about:blank (1):1
Object {whatAmI: "an object, maybe?"} about:blank (1):1
when I save it to a local file and open it up.
The jsfiddle version (and the version which uses an actual worker) are left as an exercise for the reader. :)
my first time on here.
My problem is with AS3, Javascript and possibly the browsers Firefox and IE.
I have done so much searching for an answer so i will print my code:
i am using this line to call the flash application and in all browsers its combatible and actually traces in firebug to hold an OBJECT->FLASH_ID so thats not the problem.
var obj = document.getElementById('test');
then i use addcallback:
obj.sendStatus(loggedIn);
now whats weird is that i trace all individual elments in chrome and
-obj = flash object
-sendStatus = flash->function
-loggedIn = either false or true;
everything works great but when i am on firefox or ie
it traces differently
-obj = flash object
-sendStatus = undefined
-loggedIn = either true or false;
now what am i missing??????????
i tried embedding rather than object insertion
i made sure that the id's were all unique
i checked to make sure i had the right flash object selected with getElementById
im so confused.. and it feels like something simple.
I know about some browser - dependent timing problems, making the interface of the flash object available...
A timer could help, try this:
var obj = document.getElementById('test');
setTimeout(function(){obj.sendStatus(loggedIn);}, 500);
500 is a bit to long, but just to be sure. If it works you can try to lower it to 200 - 300.
make sure you declared allowScriptAccess = sameDomain both in embed tag and object tag
in case you don't use swfObject
Maybe the way you get a reference to the swf is wrong, try this
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
The problem is that using ExternalInterface requires both parties (browser and flash) to be ready.
You can have the flash poll a method in the page which just returns true so that you know its ready to receive calls from flash.
On the flip side if the page is cached, it can sometimes happen that the page wants to send to flash before flash is ready, so I use a callback to the page telling it flash is ready, so its like a handshake, once both parties are ready, then we can start sending data back and forth.
This has been my approach since Firefox 3.
Is there any way to check a browser whether it supports 'HTML5 History API' using JavaScript.
Do I have to check all the browsers and its versions with a long list of condition in if statement.
Or simply like checking any object of function using 'if' statement is enough???...
Checking for the existence of a pushState() method on the global history object should be sufficient.
function supports_history_api() {
return !!(window.history && history.pushState);
}
For more general HTML 5 feature detection I'd look at Modernizer
http://diveintohtml5.info/detect.html#modernizr
This will insulate your code from the messy specifics of each test, making the code more readable and less error prone. With the Modernizer script on your page you'd just do:
if (Modernizr.history) {
// history management works!
} else {
// no history support :(
// fall back to a scripted solution like History.js
}
Checking for history.pushState and history.replaceState objects existence should be sufficient, as it's generally sufficient with feature detection in general.
You can use canisuse.js script to detect if your browsers supports history or not
caniuse.history()
You can check weather or not a function is registered:
if (typeof history.pushState != 'undefined') {
//Enabled
}
Then just replace //Enabled with whatever you wish to do if it's supported.