The back button just causes my page to refresh. Is there a way around this without disabling the cache?
Try adding this to your HTML header:
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
where you click on product/image on page there call onclick javascript function i.e.
function getHashOnBack(valueget)
{
location.hash = "#backTo=" + $(window).scrollTop();$(document).height();
}
Now, put
$(document).ready(function ()
{
var ab = window.location.hash.substring(1).split("=");
if (ab[0] == "backTo")
{
// this would be called automatically when back putton pressed and hav #back=1234 etc. // value in url
$(window).scrollTop(parseInt(ab[1]));
}
}
Related
This seems to be the easiest thing to do, but it's just not working. In a normal browser the .html and .js files works perfectly, but in the Chrome/Firefox extension the onClick function is not performing what it's supposed to do.
.js file:
function hellYeah(text) {
document.getElementById("text-holder").innerHTML = text;
}
.html file:
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">
ha
</div>
<br />
<a onClick=hellYeah("xxx")>
hyhy
</a>
</body>
</html>
So basically once the user clicks "hyhy", "ha" should change into "xxx". And again - it works perfectly in the browser but does not work in the extension. Do you know why? Just in case I'm attaching the manifest.json below as well.
manifest.json:
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"http://api.flickr.com/"
]
}
Chrome Extensions don't allow you to have inline JavaScript (documentation).
The same goes for Firefox WebExtensions (documentation).
You are going to have to do something similar to this:
Assign an ID to the link (<a onClick=hellYeah("xxx")> becomes <a id="link">), and use addEventListener to bind the event. Put the following in your popup.js file:
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
hellYeah('xxx');
});
});
popup.js should be loaded as a separate script file:
<script src="popup.js"></script>
Reason
This does not work, because Chrome forbids any kind of inline code in extensions via Content Security Policy.
Inline JavaScript will not be executed. This restriction bans both inline <script> blocks and inline event handlers (e.g. <button onclick="...">).
How to detect
If this is indeed the problem, Chrome would produce the following error in the console:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
To access a popup's JavaScript console (which is useful for debug in general), right-click your extension's button and select "Inspect popup" from the context menu.
More information on debugging a popup is available here.
How to fix
One needs to remove all inline JavaScript. There is a guide in Chrome documentation.
Suppose the original looks like:
<a onclick="handler()">Click this</a> <!-- Bad -->
One needs to remove the onclick attribute and give the element a unique id:
<a id="click-this">Click this</a> <!-- Fixed -->
And then attach the listener from a script (which must be in a .js file, suppose popup.js):
// Pure JS:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("click-this").addEventListener("click", handler);
});
// The handler also must go in a .js file
function handler() {
/* ... */
}
Note the wrapping in a DOMContentLoaded event. This ensures that the element exists at the time of execution. Now add the script tag, for instance in the <head> of the document:
<script src="popup.js"></script>
Alternative if you're using jQuery:
// jQuery
$(document).ready(function() {
$("#click-this").click(handler);
});
Relaxing the policy
Q: The error mentions ways to allow inline code. I don't want to / can't change my code, how do I enable inline scripts?
A: Despite what the error says, you cannot enable inline script:
There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includes 'unsafe-inline' will have no effect.
Update: Since Chrome 46, it's possible to whitelist specific inline code blocks:
As of Chrome 46, inline scripts can be whitelisted by specifying the base64-encoded hash of the source code in the policy. This hash must be prefixed by the used hash algorithm (sha256, sha384 or sha512). See Hash usage for <script> elements for an example.
However, I do not readily see a reason to use this, and it will not enable inline attributes like onclick="code".
I had the same problem, and didn´t want to rewrite the code, so I wrote a function to modify the code and create the inline declarated events:
function compile(qSel){
var matches = [];
var match = null;
var c = 0;
var html = $(qSel).html();
var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg;
while (match = pattern.exec(html)) {
var arr = [];
for (i in match) {
if (!isNaN(i)) {
arr.push(match[i]);
}
}
matches.push(arr);
}
var items_with_events = [];
var compiledHtml = html;
for ( var i in matches ){
var item_with_event = {
custom_id : "my_app_identifier_"+i,
code : matches[i][5],
on : matches[i][3],
};
items_with_events.push(item_with_event);
compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8");
}
$(qSel).html(compiledHtml);
for ( var i in items_with_events ){
$("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){
eval(items_with_events[i].code);
});
}
}
$(document).ready(function(){
compile('#content');
})
This should remove all inline events from the selected node, and recreate them with jquery instead.
I decide to publish my example that I used in my case. I tried to replace content in div using a script. My problem was that Chrome did not recognized / did not run that script.
In more detail What I wanted to do: To click on a link, and that link to "read" an external html file, that it will be loaded in a div section.
I found out that by placing the script before the DIV with ID that
was called, the script did not work.
If the script was in another DIV, also it does not work
The script must be coded using document.addEventListener('DOMContentLoaded', function() as it was told
<body>
<a id=id_page href ="#loving" onclick="load_services()"> loving </a>
<script>
// This script MUST BE under the "ID" that is calling
// Do not transfer it to a differ DIV than the caller "ID"
document.getElementById("id_page").addEventListener("click", function(){
document.getElementById("mainbody").innerHTML = '<object data="Services.html" class="loving_css_edit"; ></object>'; });
</script>
</body>
<div id="mainbody" class="main_body">
"here is loaded the external html file when the loving link will
be clicked. "
</div>
As already mentioned, Chrome Extensions don't allow to have inline JavaScript due to security reasons so you can try this workaround as well.
HTML file
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">ha</div><br />
<a class="clickableBtn">
hyhy
</a>
</body>
</html>
<!doctype html>
popup.js
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
var clickedEle = document.activeElement.id ;
var ele = document.getElementById(clickedEle);
alert(ele.text);
}
}
Or if you are having a Jquery file included then
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
alert($(target).text());
}
}
We are encountering problems when trying to load our outlook appointment addin. Our command shows up in the ribbon ui and the addin is trying to start and we can trace the calls to our wev-app. We are not getting any errors, 404 or 500 in the tracing and the service responds with our first html-page containing a text and a button to initiate our authentication.
But after the html is returned outlook just stops the spinner for the addin and nothing is showed. Is there any good ways to debug this to understand what is happening?
The html-page is very simple and only contains the code below.
<head>
<title>Office-bokning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.components.min.css">
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
<!--[authentication-popup-script]-->
<script>
startCheck = function () {
var checkCode = setInterval(function () {
localStorage.setItem('dummy', "dummy");
localStorage.removeItem('dummy');
var code = localStorage.getItem('code');
var externalProviderUserId = localStorage.getItem('externalProviderUserId');
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var fallbackCode;
var fallbackExternalProviderUserId;
if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
fallbackCode = readCookie('NAME_OF_COOKIE');
fallbackExternalProviderUserId = readCookie('externalProviderUserId');
}
console.log("code " + code);
if (code || fallbackCode) {
clearInterval(checkCode);
var http = new XMLHttpRequest();
var url = [URL]
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "text/plain");
//var that = this;
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
localStorage.removeItem('code');
localStorage.removeItem('externalProviderUserId');
window.location.href = "[URL]";
//location.reload();
}
}
http.send(params);
}
}, 1000);
}
startCheck();
</script>
</head>
<body class="container-fluid" style="padding-left: 0px; padding-right: 0px; height: 100%">
<p>
Some text describing the addin...
</p>
<!--[popup-button]-->
<script>
Office.initialize = function (reason) {
console.log("authorize office init" + reason);
var butan = document.getElementById('loginButton');
if (butan)
butan.style.display = 'block';
}
function commandFunction(event) {
event.completed();
}
</script>
</body>
TL;DR : It seems you want to pop up a page for auth. Use the displayDialogAsync API to do that.
Looking at your code, I don't see anything wrong with it. Moreover, the behavior you described is actually correct according to the code you have.
I see that you have a function named "commandFunction" that takes in an "event" parameter. My guess is that you have an ExecuteFunction in your manifest that calls commandFunction.
So when a user clicks on your add-in's button in the ribbon ui of an appointment window, Outlook will load your html webpage, invoke "Office.initialize", show a default spinner for your app just above the "Subject" field of the appointment window, and then call "commandFunction". The only code inside this function is "event.completed", so Outlook calls that code, which basically ends the execution of your app, at which point Outlook removes the default spinner to signal completion. That's exactly what you are experiencing.
You have to run any relevant code inside "commandFunction" before calling "event.completed". So for example, you can add code that will add a notification message/infobar to the appointment before calling "event.completed". Sample code below:
function commandFunction(event)
{
Office.context.mailbox.item.notificationMessages.addAsync
(
"some_unique_id_such_as_a_guid",
{
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
persistent: false,
message: "hello world",
icon: "default_icon"
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
It appears that you want to open an html window for the user to authenticate before proceeding with the execution of your app. In that case, you should use the "displayDialogAsync" API by calling it inside "commandFunction" before "event.completed". This will open an IE window that points to authentication page URL. Sample code below:
function commandFunction(event)
{
Office.context.ui.displayDialogAsync
(
"https://ur/to/auth/page",
{
width: 50,
height: 45,
requireHTTPS: true
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
The documentation for the displayDialogAsync API is at: https://github.com/OfficeDev/office-js-docs/blob/master/reference/shared/officeui.md
For debugging, open IE, go to 'Internet Options' -> 'General tab' -> click on 'Settings' button to open the 'Website Data Settings' window. In the 'Temporary Internet Files' tab, under 'Check for newer versions of stored pages', select 'Every time I visit the webpage'. Click Ok.
Now go to 'Advanced' tab -> 'Settings' section and uncheck the following:
Disable script debugging (Internet Explorer)
Disable script debugging (Other)
Then check the following:
Display a notification about every script error
Then add "debugger;" as the first line in "commandFunction":
function commandFunction(event)
{
debugger;
// add other code below...
}
This will prompt you to debug your code when you run the app. And you can debug in Visual Studio and go through your code if you have any other issues.
The HTML you pasted doesn't have a reference to Office.js: <script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
I have a button link which I'm using the 'onClick' event to play a sound (the correct answer to a quiz question). I then want to add a delay so the sound has enough time to play out before the link function loads the next page in.
I've tried using the set time out function, but I can't get it to work. Is this the best way to do this?
HEAD
<script>
$("#correct").click(function()
{
var url = "question2.html";
//5000 is the number of milliseconds (or 5 seconds) that you want to wait before redirection.
var delay = 5000;
setTimeout(function() {
window.location.href = url;
}, delay);
});
</script>
BODY
<button onclick="document.getElementById('answer1').play()" id="correct">A) Reduce – make less waste in the first place</button>
This is using HTML5 tags. Therefore, it will only work with browser that support HTML5. However, I think is a bad idea to validate the answer via javascript, since people can cheat and look the code and know which answer is corrected.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- javascript/jQuery -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
<div id='audio'>This will be replaced with an audio tag</div>
<button id="correct">A) Reduce – make less waste in the first place</button>
<script type='text/javascript'>
$("#correct").on('click',function (){
$("#audio").stop("true").delay('5000').queue(function() {
$(this).html('<audio controls="controls" autoplay="autoplay"><source src="song.mp3" type="audio/mp3" /></audio>');
});
});
</script>
</body>
</html>
i'm trying to do something similar to some websites where you leave and it'll display a popup saying "Are you sure you want to leave this page" and with two options saying "Cancel" and "OK".
How would I do that and make it so when you click "Cancel" it'll just cancel the box and when they click "OK" it'll do a 'leaveChat();' function and leave the website?
I've tried using the onbeforeunload which was working but i'm not sure on the function part.
Thanks for the help!
There is no way to do that.
You can try sending the AJAX request in onunload, but I don't think that will work reliably.
To pop a message when the user is leaving the page to confirm leaving, you just do:
<script>
window.onbeforeunload = function(e) {
return 'Are you sure you want to leave this page? You will lose any unsaved data.';
};
</script>
To call a function:
<script>
window.onbeforeunload = function(e) {
callSomeFunction();
return null;
};
</script>
here is my html
<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>
<body onload="myFunction()">
<h1 id="belong">
Welcome To My Home
</h1>
<p>
<a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
</p>
</body>
And so this is how I did something similar in javaScript
var myGlobalNameHolder ="";
function myFunction(){
var myString = prompt("Enter a name", "Name Goes Here");
myGlobalNameHolder = myString;
if (myString != null) {
document.getElementById("replaceME").innerHTML =
"Hello " + myString + ". Welcome to my site";
document.getElementById("belong").innerHTML =
"A place you belong";
}
}
// create a function to pass our event too
function myFunction2(event) {
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}
I am posting custom action with facebook open graph api and I am successfully posted that on my timeline with facebook c# sdk.
Here is my action code
curl -F 'access_token=AccessToken' \
-F 'job=http://samples.ogp.me/476622222351784' \
'https://graph.facebook.com/me/sajidap:apply'
Here is my object code
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# sajidap: http://ogp.me/ns/fb/sajidap#">
<meta property="fb:app_id" content="APPID" />
<meta property="og:type" content="sajidap:job" />
<meta property="og:url" content="Put your own URL to the object here" />
<meta property="og:title" content="Sample Job" />
<meta property="og:image" content="https://s-static.ak.fbcdn.net/images/devsite/attachment_blank.png" />
I am posting in this way.
var fb = new FacebookClient(AccessToken);
var parameters = new Dictionary<string, object>
{
{ "og:type", "sajidap:job"},
{ "og:url" , "http://www.google.com"},
{ "og:image", "http://www.theappdynamics.com/images/babafooka.jpg" },
{ "og:title" , "Arslan Job"},
{ "job" , "http://samples.ogp.me/476622222351784"}
};
var Response = fb.post(me/NameSpace:ActionName,Parameters);
Its posting an activity on my timeline but its showing Sample activity of an object that is like this url http://samples.ogp.me/476622222351784
How I can give my own url, image and title of that object by passing with parameter dynamically from C#.
Please guide me on this thing
Its Simple i have done this. You have one page like that which have your Open graphs tags in it like this. Mean It should be some content page on your web.
Let me clear more.. Like I have one resturant and I am selling some chicken burgers and I want to make one action "Buy" Mean In facebook it should be like this Arslan buy chicken lawa on link.
In This Arslan is user who performed the action
And Action is buy
And Object was chicken lawa
And URL is my below page who have all open graph tags in it to show in feeds.
Here is ASPX Page
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# myapp: http://ogp.me/ns/fb/myapp#"> // Your app name will be replaced with this "myapp"
<title>Buy Falafeel</title>
<meta property="fb:app_id" content="4735" /> // Your APP ID
<meta property="og:type" content="myapp:falafeel" /> // YourAppName:Action Type
<meta property="og:url" content="http://demo.anything.net/buy.aspx" />
<meta property="og:title" content="Chicken Lawa Falafeel" />
<meta property="og:image" content="http://www.theappdynamics.com/images/babafooka.jpg" />
</head>
<body>
<form id="form1" runat="server">
<div>
This is Falafeel Page. Demo Demo......
</div>
</form>
</body>
</html>
Here I am Performing The action on button click from my code behind.
void PostAction(string URL, string Token, string Action, string objects)
{
var fb = new FacebookClient(Token);
var parameters = new Dictionary<string, object>
{
{ objects , URL}
};
try
{
dynamic result = fb.Post("me/myapp:" + Action, parameters); // again here should be your app name instead of "myapp"
}
catch { }
}
PostAction("URL", "AccessToken", "Action", "Object"); // Here is The Above Method Call
// Here is URL That URL Who Have Open Graph Tags Like we have created one page with tags named buy.aspx and it should be full link like "http://xyz.com/buy.aspx"
//Access Token Of User On Behalf we are going to create This Action
//Action The One Created On facebook App Setting Of OpenGraph Tag Like "Buy"
//Object That We Also Created On Facebook App Setting For OpenGraph Like "ChickeLawa"
Just publish an action with your object set to the OG URL of your object, as described here: https://developers.facebook.com/docs/opengraph/actions/#create
Anything else (picture, title etc.) will be fetched from the og:tags of the URL.