I'm a Java developer not well-versed in front-end technologies, so I hope this question isn't too dumb. I have 2 scripts inline on an html page.
<script type="text/javascript">
function printReceipt(orderId,email) {
var printWindowSettings;
var browserUserAgent = navigator.userAgent;
if (browserUserAgent.indexOf("Chrome") > -1) {
printWindowSettings = "status=0,toolbar=0,menubar=0,height=500,width=1000,scrollbars=1";
} else {
printWindowSettings = "status=0,toolbar=0,location=0,menubar=0,height=500,width=1000,scrollbars=1,noopener=1";
}
var path = "/shop/printReceipt?orderid="+orderId;
if (email!=null)
path+="&email=" + email;
var docPrint = window.open(path, '_blank', printWindowSettings);
if (docPrint == null) console.log("window open returned null");
}
</script>
<script type="text/javascript">
bajb_backdetect.OnBack = function()
{
window.history.back=function(){
console.log("Back Button Pressed.")
document.location='/shop/shoppingCart.seam';
}
}
</script>
printReceipt() is invoked in the onClick() handler of an anchor tag.
<div class="pull-left" style="padding-bottom:20px;"><i class="fa fa-print" aria-hidden="true" style="padding-right:6px;"></i>Print Receipt</div>
What I'm finding is that when printReceipt() is invoked, the following script (to manage the back button) gets invoked also. So when printReceipt() is called, my browser navigates to /shop/shoppingCart.seam.
Why would this be? How do I get around this?
I made a bit of research about your issue, and since you mention that you are using a third party script (which is not always the best for a developer), I found something that may help you get rid of it.
This method will need you to delete the third party script you already have (or comment it). Since we are going to handle the back button in a different way.
In the script tag where you had the following code:
bajb_backdetect.OnBack = function() {
window.history.back = function() {
console.log("Back Button Pressed.")
document.location = '/shop/shoppingCart.seam';
}
}
Replace it with this code:
(function(window, location) {
history.replaceState(null, document.title, location.pathname+"#!/history");
history.pushState(null, document.title, location.pathname);
window.addEventListener("popstate", function() {
if(location.hash === "#!/history") {
history.replaceState(null, document.title, location.pathname);
setTimeout(function(){
location.replace("/shop/shoppingCart.seam"); //Here goes your URL
},0);
}
}, false);
}(window, location));
And now, if you did remove the third party script (or commented it), you should be able to see the expected behavior.
If you want to see more about this, there is a question similar to this that has been already answered saying the best approach for handling the window back event is doing it by yourself.
I took this information from this answer, just complemented it with the explanation and code for your specific issue. Hope it helps.
Note: If it still not working, you will need to provide a more open context of your code, since there might be something else causing it to not work.
Probably the anchor being clicked causes the browser to follow the link.
Given this:
click me
Clicking that link will run the function and then the page will reload. Your back detection script will notice that the page is being unloaded and do stuff (apparently).
Change it to:
click me
To prevent the link from being followed.
Related
What would be a viable way to accomplish the following:
A website has two pages; Parent page and Inside page. If user came to the Inside page directly by typing in the address or by following a link from a page other than Parent page, then show "foo". If user came to the Inside page from the parent page, then show "bar".
I would need this done in JS if possible. If not, PHP is a secondary choice.
You can get the page the user came from with document.referrer.
So you could implement your solution like this:
if (document.referrer === 'yoursite.com/parentpage') {
// do bar
} else {
// do foo
}
Please try this
This code in second page
jQuery(window).load(function() {
if (sessionStorage.getItem('dontLoad') == null) {
//show bar
}
else{
//show foo
}
});
This code in parent page
jQuery(window).load(function() {
sessionStorage.setItem('dontLoad','true')
});
with php:
There is a simple way is to create a mediator page which redirect to inner page after make a session / cookie.. then if you'll get session / cookie, you show foo & unset session.
if someone directly come from url, no session / cookie found & it show bar..
You can use the document.referrer but this is not always set. You could add a parameter to the URL on the parent page and then check for its existance in the child page
Link on the parent page:
<a href='myChildPage.html?fromParent=1'>My Child Page</a>
JS code on your child page:
var fromParent=false;
var Qs = location.search.substring(1);
var pairs = Qs.split("&");
for(var i = 0; i < pairs.length; i++){
var pos = pairs[i].indexOf('=');
if(pos!==-1){
var paramName = pairs[i].substring(0,pos);
if(paramName==='fromParent'){
fromParent=true;
break;
}
}
}
if(fromParent){
alert("From Parent");
}else{
alert("NOT From Parent");
}
This method isnt 100% foolproof either as users could type in the same URL as your parent page link. For better accuracy check the document.referrer first and if not set use the method i've outlined above
intelligent rendering with jQuery
After using #Rino Raj answer, i noticed it needed improvement.
In javascript, the load() or onload() event is most times much slower,
since it waits for all content and images to load before executing your attached functions.
While an event attached to jQuery’s ready() event is executed as soon as the DOM is fully loaded, or all markup content, JavaScript and CSS, but not images.
Let me explain this basing, on code.
When i used #Rino Raj's code, with load() event, it works but on the second/called page, the content appears before class="hide fade" is added (which I don't really want).
Then i refactored the code, using the ready() event, and yes,
the content that i intended to hide/fade doesn't appear at all.
Follow the code, below, to grasp the concept.
<!-- Parent/caller page -->
<script type="text/javascript">
$(document).ready(function() {
sessionStorage.setItem('dontLoad', 'true');
});
</script>
<!-- Second/called page -->
<script type="text/javascript">
$(document).ready(function() {
if(sessionStorage.getItem('dontLoad') == null) {
$("#more--content").removeClass("hide fade");
} else {
$("#more--content").addClass("hide fade");
}
});
</script>
Why won't this work in Confluence:
AJS.$("body").attr("onload", AJS.$("body").attr("onload") + " myFunction()");
I want to append my own function to the onload attribute of the body element but when I add this code to the Main Layout, Confluence just ignores it. When I try this code using the Chrome debugger, it works just fine.
Edit: I guess I should be a little more clear: The above code seems to work when the Confluence page is loaded the first time. But when the page enters into edit mode, the custom script isn't executed.
As a general rule, wait until the whole page has loaded. In some cases, in particular when plugins are manipulating the DOM, you may have to put in a delay of a second or two before your script runs.
Using JQuery:
{html}
<script type="text/javascript">
AJS.$(document).ready(function() {
AJS.$("#comments-section").hide();
});
</script>
{html}
Using JavaScript:
{html}
<script type="text/javascript">
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(function() {
var ele = document.getElementById("comments-section");
ele.style.display = "none";;
})
</script>
{html}
Well, it may depend on many things. For example whether myFunction is already available at the moment when the onload handler wants to execute it.
But why don't you use a more standard way of achieving this:
AJS.$(document).ready(myFunction);
or if you really want to react on the load event
AJS.$(document).load(myFunction);
Base on a discussion with an Atlassian developer, "The proper way to execute a function when the page is loaded is: AJS.$(function($){ ... your code ... });"
This does work for the initial page load but when the page goes into edit mode, this doesn't get executed. Several console.log outputs confirm this.
For a project I need to print a document using PHP code.
Currently I have a self closing pop up to start the print.
The only problem I have is that a user could spam the button creating a lot of print requests and a huge queue.
The code I have right now:
function newPopup(url) {
popupWindow = window.open(
url,'popUpWindow','height=10,width=100,left=10,top=10,resizable=no,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=no'); // Verstop op achtergrond
popupWindow.blur();
}
Print
I have found some code to stop links but I have problems implementing these since I already call it as a pop up.
You can use a flag:
var flag=true;
function newPopup(url) {
if(flag) {
window.open(...).blur();
flag=false;
window.setTimeout(function(){flag=true;},5*1000);
}
}
Not a "good" solution (uses a global variable), but it should work.
You may disable the link before you open the popup and then re-enable it after five seconds. The problem is that to enable/disable a link can't be done in a very portable way. To workaround this you have to save the actual link, replace it with a fake one and then re-enable it later (when interval elapsed). Like this:
function newPopup(url) {
// Save current link and replace it with a fake one
var oldLink = $("#linkid").attr("href");
$("#linkid").attr("href", "#");
setinterval(function() {
// Restore true link
$("#linkid").attr("href", oldLink);
}, 5000);
// ...
}
You can extract this code to a separate function temporaryDisableLink(id, timeout) to reuse it for many different links (without polluting all other code).
Now let's explore other solutions.
Your HTML code must be updated to (in case you want to reuse the same function for many links otherwise you do not need to pass the link id parameter) to:
<a id="link-print"
href="JavaScript:newPopup('#link-print', 'print.php');">
Print
</a>
The pointer-events CSS property isn't supported by IE (and Opera) so I can't suggest to use it in real world. Anyway it's:
function newPopup(id, url) {
$(id).css("pointer-events", "none");
setinterval(function() {
$(id).css("pointer-events", "auto");
}, 5000);
// ...
}
Because you're using JavaScript to open the pop-up you may consider to change a little bit the function to use a custom disabled attribute (or to check for pointer-events if you plan to use them together):
function newPopup(id, url) {
if ($(id).attr("disabled") == "disabled") {
return false;
}
$(id).attr("disabled", "disabled");
setinterval(function() {
$(id).removeAttr("disabled");
}, 5000);
// ...
}
<script>
function newPopup(url) {
setTimeout(function () {
popupWindow = window.open(
url, 'popUpWindow', 'height=10,width=100,left=10,top=10,resizable=no,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=no'); // Verstop op achtergrond
popupWindow.blur();
},5000
);
}
</script>
Print
I'm successfully displaying an invite friend dialog (code shown below). When user clicks skip the iframe/dialog shows a new page. However from this point I can't find a way how to close the iframe/dialog. FB.ui doesn't return any object, there doesn't seem to be a Javascript SDK method and traversing and manipulating with the DOM will be brittle to any FB code changes.
Any ideas?
function popupInviteForm(actionUrl) {
var fbmlString = '<fb:fbml>' +
' <fb:request-form type="POST" content="Play against me in game?" action="' + actionUrl + '" method="post" >' +
' <fb:multi-friend-selector target="_self" exclude_ids="" max="20" cols="4" rows="3" showborder="false" actiontext="Invite friends!" />' +
' </fb:request-form>' +
'</fb:fbml>';
FB.ui({
method: 'fbml.dialog',
fbml: fbmlString,
display: 'dialog',
size: {width:640,height:480}, width:640, height:480
});
$(".FB_UI_Dialog").css('width', $(window).width()*0.8);
}
(Note: I have posted the same question on the facebook forum with no response. I will update both, should there be an answer on either.)
The Javascript code was adapted from a stack overflow answer.
I have same trouble. Second day looking for a solution. And just found one way:
for closing active FB dialog you should perform followed code in parent window where FB JS is available and where FB.ui was called:
FB.Dialog.remove(FB.Dialog._active);
So, if you want your invite dialog auto closes and don't redirects to any other page, use these steps:
1) Set target attr of and as "_self":
target="_self"
2) create some callback url/page on your site, for example
https://mysite/close_dialog.html
3) Set action attr of as just created url:
action="http://mysite/close_dialog.html"
4) In your close_dialog.html put followed JS:
<script type="text/javascript">
if (document.location.protocol == 'https:') {
document.location = 'http://mysite/close_dialog.html';
} else {
top.window.FB.Dialog.remove(top.window.FB.Dialog._active);
};
</script>
UPDATE:
5) There is one issue else in this way:
FB iframe loaded by https, but if request-form 'action' attr uses 'http' - user will get browser warning. But if request-form 'action' has 'https' - iframe js cant access to parent loaded by 'http'.
So, its the reason why you should use action by 'https'
Hope this helps
If you has better solution or you can improve this way - please let all know this,
Thanks for any comments
That doesn't work (at least not for me).
What I did was simply call the javascript window.close(); function instead of top.window.FB.Dialog.remove(top.window.FB.Dialog._active); and it works.
<script type="text/javascript">
if (document.location.protocol == 'https:') {
document.location = 'http://mysite/close_dialog.html';
} else {
//alert('some message');
window.close();
};
</script>
The FB.ui provides an option for a callback function which will be executed after the FB.ui is completed.
FB.ui(
{
method: '..........',
..................
},
function(response) {
//write your code here
}
);
Will this help to solve your problem?
i found Igor Reshetnikov's answer did work, but only if i made sure to declare both pages - The one that opens the dialog and close_dialog.html - as part of the same domain using document.domain. so at the top of the script tags in both pages you'ld had to add this line
document.domain = 'mysite.com';
obviously replacing mysite.com with what ever your domain is
This closes all dialogs, but may not work with future releases due to access of internal variable _loadedNodes
if (FB && FB.UIServer && FB.UIServer._loadedNodes) {
var nodes = FB.UIServer._loadedNodes;
if (nodes) {
for (var item in nodes) {
if (nodes[item].type && nodes[item].node && nodes[item].node.close &&
nodes[item].type === "popup") {
nodes[item].node.close();
}
}
}
}
FWIW, my browser's privacy plugin was preventing FB from closing the dialog. I just switched off the privacy plugin and dialog closed itself as expected.
So I'm trying to redirect users from html links and element id tags, to other pages with javascript. I've figured out how to do one singular redirect but having trouble writing the code for multiple links heres what I have so far:
HTML:
<head>
<script type = "text/javascript" src="script2.js"></script>
</head>
<body>
NickName
Salestax
W 3 Schools
</body>
</html>
My external script so far for just one link:
window.onload = initAll;
function initAll() {
document.getElementById("redirect").onclick = initRedirect;
}
function initRedirect() {
confirm("Go to Salestax page?");
window.location="salestax.html";
return false;
{
Do I just crank out more functions and change the location value, getElementById value and the onclick value?
A nice thing about onclick events is that if you return false it'll stop the browser from going to the link defined in the HREF. If you return true it'll keep going through with the navigation. You don't need to worry about the window.location in your function if you use this method, which will simplify things a lot. So you can just do:
Salestax
I'll prompt them if they want to continue. They click yes it'll keep going as if they clicked the link normally, they click no it'll stop them from navigating away. This way you don't have to duplicate the link's HREF in both your HTML and javascript.
You could still dynamically bind this, but if you're doing it by ID I don't really see any advantage vs just defining the onclick in the HTML.
First off, unless you're trying to prevent a user from losing changes that they've made on the current page, it's not clear why you would want to create this functionality. But at any rate, here's a standard/basic approach:
window.onload = function() {
document.getElementById("redirect").onclick = redirectConfirmation("Go to Salestax page?");
document.getElementById("redirect1").onclick = redirectConfirmation("Go to Nickname?");
};
redirectConfirmation = function(msg, urlOverride) {
return function() {
if ( confirm(msg) ) {
window.location = urlOverride || this.href || "#"
}
return false;
};
};
redirectConfirmation optionally takes a second parameter which can be used to explicitly set the url that the page is redirected to; otherwise, it will default to the URL specified by the href attribute of the anchor tag being acted upon (and if all else fails, it will fail gracefully with "#").
If you're using a common library, like jQuery, you can simplify your event registration as follows:
$(function() {
$("#redirect").click( redirectConfirmation("Go to Salestax page?") );
$("#redirect1").click( redirectConfirmation("Go to Nickname?") );
});
A far better approach would be to do something like the below - that way the logic for redirecting the user stays reasonably close to the link, and so people looking at the source wont become incredibly confused when the page takes people elsewhere.
Some link
External script:
function initRedirect(message, url)
{
confirm(message);
window.location = url;
return false;
}