I'm trying to use a facebook UI request dialog for selecting a friend. This works absolutely fine in safari and Chrome but in firefox and IE11 (Not tested lower versions yet) it continuously hangs with the loading animation.
function pickFriend(ev)
{
FB.ui(
{
method: "apprequests",
message: "Choose a friend.",
max_recipients: 1,
title:"Invite a friend"
},sendMessage);
ev.preventDefault();
}
$("#element").click(pickFriend);
I then tried calling the function directly in the console to ensure that it wasn't my implementation that was the problem, and i got the same result with it hanging with the loading animation. I then tried different display options and i can get it too work in popup mode but for me this is not very elegant and i would far prefer it to work in iframe mode the same way it does in safari and chrome.
Has anyone else been experiencing this issue? If so is there a reason for this and is ther a fix?
I'm thinking that this maybe something that is entirely down to facebook to fix which would leave no other option but to run in popup mode if i want to keep browser compatibility.
In IE11 (and node) the javascript engine can get hung up on long operations. The recommended work around is utilizing "setImmediate", so for your example:
function pickFriend(ev)
{
ev.preventDefault();
setImmediate(FB.ui
, {
method: "apprequests",
message: "Choose a friend.",
max_recipients: 1,
title:"Invite a friend"
}
, sendMessage
);
}
$("#element").click(pickFriend);
Also, make sure your "sendMessage" variable is scoped properly and not undefined or null.
Syntax
var immediateID = setImmediate(func, [param1, param2, ...]);
var immediateID = setImmediate(func);
Reference:
https://developer.mozilla.org/en-US/docs/Web/API/Window.setImmediate
Related
I use adobe analytics and try to track links using this:
$(document).on('click', 'a', function() {
s.tl(this, 'e', 'link', null, 'navigate');
return false;
});
or
$("a").click(function() {
s.tl(this, 'e', 'link', null, 'navigate');
return false;
});
and when I tested it and click in a link in Chrome I receive for the first the status page canceled and using the second option in chrome everything works fine but in Firefox I receive status 0 GET (NS_BINDING_ABORTED).
Is there any workaround which could run without problem in all browsers or should I fix anything to the previous?
From here is the example I use using the second box as example
I found this solution:
https://marketing.adobe.com/developer/es/forum/general-topic-forum/custom-link-tracking-capturing-issue
Which proposes this as a work around:
<script language="javascript">
function pejTracking(linkname,url) {
var s=s_gi('myprodsuite');
s.tl(this,'o',linkname,null,navigate(url));
}
function navigate(url) {
window.location=url;
}
</script>
This really works!
Is it possible to make it to work with the JQuery document or a onclick function as I have at the start of my post and there is any need to have the onclick in every link?
This is common, and (probably) isn't a problem.
This error occurs because the link tracking image request is designed to let the browser proceed to the next page before waiting for a response from the Adobe data collection servers.
Adobe Reference: NS_Binding_Aborted in Packet Monitors
Update:
You commented:
Yes I have seen this but is it possible to fix it?
You are asking to "fix" this as if it's something that is broken.. my point is that it's not broken.
But if you insist on wanting to make sure this doesn't show up, you will need to do the solution you already posted in your question.
The jQuery equivalent would be to make use of event.preventDefault() and then update window.location after the s.tl call (in navigate callback) same as the non-jQuery solution.
You also asked:
And what about chrome?
What about it? This isn't browser-specific. It has to do with timing. Try it enough times in Chrome and you should see that NS_Binding_Aborted error in Chrome, too. Maybe. Depends on connection speed, current CPU resources, internet traffic in general, how the stars are aligned, etc. - you know, all the things that make requests and response happen later rather than sooner.
I am aware of two ways of calling the "print" dialog of browser (I used the Search, of course):
document.print()
document.execCommand('print', false, null)
What is the difference between them? Support across browsers? Papers, docs or standards? Which is more correct thing to use?
Another question: what is the most straight way to print given part of a webpage? I know we can create new window or iframe to call any of two print methods above. Which one has less pitfalls?
I've tested different ways of printing part of webpage across browsers:
Chrome, Firefox, Opera (12 and new), IE11, 10, 9 and 8. I've tried to create new window, new iframe, or use existing iframe on the page. And then tried .print() and .execCommand('print').
Note: Keep in mind that .print() is called on window, and .execCommand() is called on document.
Code used for testing can be found here
Correct me if my testing code is wrong, I just wanted to find the clearest way to do the job. My conclusions:
Opera 12 can not print part of a webpage (?)
IEs don't print() iframes and windows, except current window.
Calling print() on documents inside iframes or created windows in IEs breaks the print() on current document. Be careful!
jQuery plugin printThis uses tricks for IE to do the job, and it just works. The only exception is Opera 12. By the way, this plugin uses print().
execCommand('print') works almost everywhere and with any approach (iframes, window). It's not supported by Firefox though.
execCommand() returns false if call was unsuccessful, so if you don't want to use plugins and magic tricks, create window or iframe, call execCommand('print') and if it returns false, call print().
One more thing:
Creating an iframe is tricky: you can't access its window or document directly (yes, you have ContentDocument property, which behaves differently across browsers). You should name it and then call window.frames[name] to get window object from that iframe. Do not try to call window.frames(id) - it will return the iframe.
That last method mentioned in the accepted answer, then, ends up looking like this:
iframe = document.getElementById('iframe-id');
var printed = iframe.contentWindow.document.execCommand('print', false, null);
if (!printed) window.print();
alternative:
try {
iframe = document.getElementById('iframe-id');
iframe.contentWindow.document.execCommand('print', false, null);
}
catch(e) {
window.print();
}
similar method used by printThis
if (document.queryCommandSupported("print")) {
$iframe[0].contentWindow.print();
$iframe[0].contentWindow.document.execCommand("print", false, null);
} else {
$iframe[0].contentWindow.focus();
$iframe[0].contentWindow.print();
}
You can use the combination of window.open and execComand (saveas
exemple:
<script type= "text/javascript">
function saveas() {
var oPrntWin = window.open("","_blank","width=1,height=1,left=1,top=1,menubar=yes,toolbar=yes,resizable=yes,location=no,scrollbars=yes");
oPrntWin.document.open();
oPrntWin.document.write(editeur.innerHTML);
oPrntWin .document.execCommand("SaveAs",true,"C:\\My Documents\\Saved Content.html");
oPrntWin.document.close();
}
</script>
editeur.html is a part of my document
you can do same for your frame
replace the writting in a new Window by the property "src" for the body
I have a small piece of code for a template project I'm working on. There are three separate buttons, that point to three separate locations. In order to make it easier for content providers, I have these buttons calling minimal routines to load the next page.
The code is as follows:
/* navigation functions here for clarity and ease of editing if needed */
prevURL = 'ch0-2.html';
nextURL = 'ch2-1.html';
manURL = 'ch1-2.html';
function prevPage() {
window.location = prevURL;
}
function nextPage() {
window.location = nextURL;
}
function goManager() {
window.location = manURL;
}
This works perfectly in Firefox and Chrome, but seems to fail in Internet Explorer.
I open up the developer tools in IE (F12) and am presented with the message:
SCRIPT5009: 'manURL' is undefined
The location information (line 43, character 13) points to the "window.location = manURL" part of the code.
However, once the developer tools are open, if I hit F5 to reload the page, the button works without error until I close IE and reopen it, where it once again fails to respond and gives the same "undefined" error.
I'm baffled. Anyone have any ideas?
UPDATE
I know the variable declaration is poor, and that I can use window.location.href instead. What is relevant here is that the other two pieces of code, which are identical in all of these significant ways, work perfectly either way.
epascarello has put me on the right track. by removing all console.log commands, everything starts working. I'm just wondering why this happens, and would like to be able to give epascarello credit for helping me.
IE does not have console commands when the developer window is not open. So if you have them in there the code will not run. It will error out.
You can either comment out the lines or add in some code that adds what is missing.
if (typeof console === "undefined") {
console = {
log : function(){},
info : function(){},
error : function(){}
//add any others you are using
}
}
Try setting
window.location.href
instead of just window.location.
Source:
http://www.webdeveloper.com/forum/showthread.php?105181-Difference-between-window.location-and-window.location.href
Always define variables before using them ,being explicit (expressing the intention) is a good practice,
so define your variables like this,
var prevURL = 'http://google.com';
var nextURL = 'http://msn.com';
var manURL = 'http://stackoverflow.com';
You can try using
window.location.href
refer to this post for difference
Suggestion:
Make a jsfiddle.net for us so we could guide you easily
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.
My simple ActionScript
I am trying to use Flash's ExternalInterface to setup a callback so that JavaScript can call a method on my Flash object. Everything works fine in Safari, Firefox and in IE, but I cannot get Chrome working. When I try the code on Chrome, I get the following error:
Uncaught TypeError: Object #<an
HTMLObjectElement> has no method
'setText'
Here is the example HTML I am using (again, works fine in Safari, FF and IE)
<html><body>
<div id="mycontent"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("http://invincible.dynalias.com:8080/HelloWorld.swf", "mycontent", "400", "420", "9.0.0","expressInstall.swf", {}, {allowScriptAccess:'always'},{id:'hw',name:'hw'});
function getFlash(movieName) {
return ( navigator.appName.indexOf("Microsoft") != -1) ? window[movieName] : document.getElementById(movieName);
}
</script><p>
<input type="text" id="exampleText" /> <input type="button" value="Set Text" onclick="getFlash('hw').setText(document.getElementById('exampleText')
.value)" />
</body>
</html>
and here is the ActionScript...
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.external.ExternalInterface;
import flash.system.Security;
public class HelloWorld extends Sprite {
private var textField:TextField = new TextField();
public function HelloWorld() {
Security.allowDomain("*");
ExternalInterface.addCallback("setText", this.setText);
textField.text = "Hello, world!";
addChild(textField);
}
public function setText(text:String):void {
this.textField.text = text;
}
}
}
I agree with Robson that it is a race condition, but it's not in 'writing the Flash tag' and adding a timer is not a good solution - in fact its very dangerous.
The problem is that the SWF itself isn't loaded and had a chance to initialize your external interface. For a small SWF in Chrome the timing may be more sensitive than other browers, but the underlying problem isn't specific to Chrome.
What you need to do is this :
In Actionscript
Call this function from your constructor :
public function InitializeExternalInterface():void
{
if (ExternalInterface.available) {
// register actionscript functions so they can be called by JS
ExternalInterface.addCallback("activate", activate);
Security.allowDomain("www.example.com");
// send message to parent page that SWF is loaded and interface active
trace("External Interface Initialized...");
ExternalInterface.call("flashInitialized")
}
else
{
trace("ERROR: External Interface COULD NOT BE Initialized...");
}
}
In your HTML
<script>
function flashInitialized()
{
alert("Initialized!"); // remove this obviously!
$('#Main')[0].activate(); // safe to call Flash now
}
</script>
You may find on your local machine that it works without this, but as soon as you add network delays into the equation you'll regret not doing this. An arbitrary timer is a bad idea because you will still get the error on a slow connection. This method lets the page call the flash object at the earliest possible time.
Note: Using jQuery's 'on ready' pattern is NOT a solution to the problem - although at first I mistook it for one.
$(function()
{
$('#animation')[0].SetTitle("Hello");
}
Also swfobject's callbackFn is also not a solution becasue that just tells you when the tag is inserted and not when the SWF is loaded.
I got the same problem, to fire and recieve listener events between javascript and flash.
The solution was to use AC_OETags.js file from Adobe as embedd script instead of JQuery flash. (It is found in the zip file under Client Side detection, Adobe probably have it some other places as well)
The trouble based on a race condition when the flash builds the javascript callbacks in the browser. This is not handeled correctly by a straight embed for some reason.
<div>
<script>
// Major version of Flash required
var requiredMajorVersion = 10;
// Minor version of Flash required
var requiredMinorVersion = 0;
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
AC_FL_RunContent(
"src", "tagflash",
"width", "200",
"height", "200",
"id", "myTagFlash",
"quality", "high",
"bgcolor", "#FFFFFF",
"name", "myTagFlash",
"allowScriptAccess","always",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer",
"flashvars", "templateData=theYear:2010&theTagNumber:123"
);
</script>
</div>
Then you can do: (works in IE, FF, Safari, Crome,++)
$("#tagFlash").gotoNewFrame();
I was having problems with ExternalInterface and Firefox and Chrome and discovered that the Adobe Script was not writing the Flash tag quickly enough, so when the browser tried to find the addCallback() function it was not there at the time.
Simply putting my Javascript function that calls the Flash created addCallback() in a window.setTimeout() calling solves the problem. Delays less than 200 ms still make the problem to occur.
I didn’t have to use the solution of trying to find if the “length” attribute exists in the document[FlashId] object. Just calling “FlashEmbed = document[FlashId]” worked just fine.
After struggling a lot, I finally decided to use the official solution from Adobe:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
Search for ExternalInterfaceExample.as.
There is a workaround to the problem by disabling Chrome built-in flash plugin:
type the chrome://plugins in the address bar of chrome.
expand the details of plugins by clicking the details on top right corner.
in the entry of "Adobe Flash Player", disabling the first one.
This is not a solution, but shows why this happens on Chrome. Chrome accompany with a built-in flash plugins, that often cause the troubles when we use the ExternalInterface of AS3, it's annoying.