Firefox extension - save boolean to storage - javascript

In the Firefox extension, I want to implement a simple toggle switch that will enable/disable an extension. A basic idea is that the change of state will be saved as a boolean into browser (sync) storage. The state should be read every time, so an extension will know if should work or not.
But - my Javascript knowledge is so poor that I came into trouble.
Here is simple HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<form id="form" class="ps-3 mt-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitch">
<label class="form-check-label" for="flexSwitch">Plugin ON/OFF</label>
</div>
</form>
<label id="test"></label>
<br>
<script src="options.js"></script>
</body>
</html>
And here is a simple JS file:
function CheckAndSave()
{
var state = document.getElementById("flexSwitch");
if(state.checked)
{
document.getElementById('test').innerHTML = 'ON';
browser.storage.sync.set({ delovanje: 1 });
}
else
{
document.getElementById('test').innerHTML = 'OFF';
browser.storage.sync.set({ delovanje: 0 });
}
restoreState();
}
function restoreState()
{
//browser.storage.sync.get("delovanje", function(items) { console.log(items)});
let getting4 = browser.storage.sync.get("delovanje");
getting4.then(setCurrentChoice, onError);
function onError(error) {
console.log(`Error: ${error}`);
}
function setCurrentChoice()
{
var toggle = document.getElementsByName("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
}
document.addEventListener("DOMContentLoaded", restoreState);
document.getElementById("flexSwitch").addEventListener('change', CheckAndSave);
What is wrong with my code? Is my way of saving Boolean ok?
I tried to write to the console for "debugging", but I don't know how to do it - this is a pop-up after a user press an icon, and nothing is shown in the console.

Most of all you did a mistake here:
function setCurrentChoice(result)
{
var toggle = document.getElementsByName("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
In this case, toggle will be array like object, but not the element you expect.
You should use document.getElementById("flexSwitch") as previously.
Another issue that you missed an argument in the setCurrentChoice function. It should take settings like this:
function setCurrentChoice(result){...}
I would also suggest to hide the logic of getting element behind the scene by either wrapping it to the function:
const getToggle = () => document.getElementById("flexSwitch")
Or even move it to the separate class and encapsulate all logic there:
class Toggle {
constructor() {
this._el = document.getElementById("flexSwitch");
}
setCheck(value) {
this._el.checked = value;
}
}
Here is the working sample:
function CheckAndSave()
{
var state = document.getElementById("flexSwitch");
if(state.checked)
{
document.getElementById('test').innerHTML = 'ON';
chrome.storage.sync.set({ delovanje: 1 });
}
else
{
document.getElementById('test').innerHTML = 'OFF';
chrome.storage.sync.set({ delovanje: 0 });
}
}
function restoreState()
{
chrome.storage.sync.get("delovanje",setCurrentChoice );
function setCurrentChoice(result)
{
var toggle = document.getElementById("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
}
document.addEventListener("DOMContentLoaded", restoreState);
document.getElementById("flexSwitch").addEventListener('change', CheckAndSave);
This approach will help you reduce the code and accidental mistakes.
P.S. Here is how I worked with the storage

The code seems okay, while there are some things I would change (for refactoring purposes to match my flavour) I think it should be working without much issue.
In any case verify the following.
The browser.storage.sync API is only available from extensions, so check that the HTML and JS that you are posting are actually part of the extension that you are using.
The manifest.json is what tells the browser what resources can your extension access, verify that you did add the "storage" permission on there here you can read more about it for chrome, though it will be the same for other browsers
For debugging purposes always remember that the browser lets you have great tools. Read more about developer tools, but as a starter I would tell you to open them and put a debugger statement there where you feel like there's something that isn't working as expected. And then with the console start looking for the properties that you are not finding.
To log items to the console use console.log('XXX') and it should show what you want

I think the problem is that the change event is not fired when setting toggle.checked with JavaScript. Just call CheckAndSave(); from the end of setCurrentChoice.

Related

window.speechSynthesis.speak(msg) not working until button click

The brief page below does not work. Specifically, "window.speechSynthesis.speak(msg)" does not work until the button has been pressed. If the button has been pressed then the "Hello" message works. If it has not then any calls to "window.speechSynthesis.speak(msg)" do not produce any audible output.
Suspecting that it has something to do with initialization of speechSynthesis - some things have been tried below to ensure that it is initialized when "Hello" is called. None have worked. Although it seems like it should have. It seems like it is getting properly initialized only if it is called from the button press.
The setup of the SpeechSynthesisUtterance itself is the same whether called from the button or the timeout. That setup works when called by the button. But nowhere else until it has been called by the button.
What is wrong here?
<!DOCTYPE html>
<html>
<head>
<title>Voice Test 3</title>
</head>
<body>
<div id="header">User Interface Terminal</div>
<input type="text" id="control_box"></input><br>
<button id="startButton" onclick="voicemessage('Button');">start</button><br>
<script>
function voicemessage(ttstext) {
var msg = new SpeechSynthesisUtterance(ttstext);
msg.volume = 1;
msg.rate = 0.7;
msg.pitch = 1.3;
window.speechSynthesis.speak(msg);
document.getElementById('control_box').value = ttstext;
}
window.speechSynthesis.onvoiceschanged = function() {
document.getElementById('control_box').value = "tts voices recognized";
window.setTimeout(function() {
voicemessage("Hello");
}, 5000);
};
window.addEventListener('load', function () {
var voices = window.speechSynthesis.getVoices();
})
</script>
</body>
</html>
This may be due to the browser itself...
Recent updates in some browsers (Firefox and Chrome) have policies to prevent audio from being accessed unless some user interaction triggers it (like a button click)...

Is there any callback function after 'Friends List' loaded in cometchat?

I have integrated 'Embed Layout' comet chat on my site. Now I want to open particular friend chat on page load.
In the documentation, I've found below code to do the same. REF : Documentation Link
jqcc.cometchat.chatWith(user_id)
I have included in custom js from admin panel. However, it is showing below error in console
jqcc.cometchat.chatWith is not a function
But If I use same after friends list loaded from the console it is working fine.
How can I fix this issue?
Currently for time being I have fixed this issue by adding below code in custom js
var first_chat_loaded = false;
var first_chat = setInterval(function () {
try {
if (first_chat_loaded === false) {
// Function to get other user id defined in parent html page
var other_userid = parent.get_other_user_id();
jqcc.cometchat.chatWith(other_userid);
first_chat_loaded = true;
clear_first_load();
}
} catch (e) {
}
}, 1000);
function clear_first_load() {
clearInterval(first_chat);
}
Please let me know, If there is any proper way to do the same.
Kindly make use of this code snippet for the above mentioned issue
var checkfn = setInterval(
function(){
if(typeof jqcc.cometchat.chatWith == 'function'){
jqcc.cometchat.chatWith(user_id);
clearInterval(checkfn);
}
},
500);

Save user preferences in popup.html Chrome Extension

I've finished developing the main functionality of a Chrome Extension, but I'm struggling to retain the user preferences in the popup.html file. So, I have a button in the popup.html file which is supposed to be a user preference, but I am not able to retain the user preference upon reloading the page and clicking on the extension again.
I tried using the Chrome Storage API, but I was unable to achieve what I wanted.
Here is a picture of popup.html:
I want to be able to save a user's preference if they choose to toggle between on and off. But as of what I have now, when the user slides it on (as indicated in the picture), upon clicking away from the popup and clicking the icon again, the button always defaults to the 'off' position.
I tried using a combination of localStorage and the Chrome Storage API to load the user preferences, but I was unable to do so.
Here is my popup.js file:
function saveChanges() {
// Get a value.
if ($('#myonoffswitch').is(':checked')) {
localStorage.mydata = 'y';
} else {
localStorage.mydata = 'n';
}
// Save it using the Chrome extension storage API.
chrome.storage.sync.set({
'value': localStorage.mydata
}, function () {
});
}
$(document).ready(function () {
if (localStorage.getItem('mydata')) {
if (localStorage.mydata == 'n') {
$('myonoffswitch').attr('checked', false);
} else {
$('myonoffswitch').attr('checked', true);
}
} else {
if ($('#myonoffswitch').is(':checked')) {
localStorage.setItem('mydata', 'y');
} else {
localStorage.setItem('mydata', 'n');
}
}
$('#myonoffswitch').click(function () {
saveChanges();
});
});
Here is my popup.html file:
<html>
<head>
<title>Replace some text</title>
<link rel="stylesheet" type="text/css" href="popup.css">
<script type='text/javascript' src='jquery-1.12.3.js'></script>
<script type="text/javascript" src="options.js"></script>
</head>
<body>
<div>
<div class='logo'>
</div>
<div class='main-text'>
</div>
<div class='buttons-area'>
<div class="onoffswitch">
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch">
<label class="onoffswitch-label" for="myonoffswitch"></label>
</div>
<div class='block-spoilers-message'>
On Off Button
</div>
</div>
</div>
</body>
</html>
And finally, here is a relevant part of my content script:
$(document).ready(function () {
var on_off_pref = true;
chrome.storage.onChanged.addListener(function (changes, namespace) {
for (key in changes) {
var storageChange = changes[key];
on_off_pref = storageChange.newValue;
console.log('Storage key "%s" in namespace "%s" changed. ' +
'Old value was "%s", new value is "%s".',
key,
namespace,
storageChange.oldValue,
storageChange.newValue);
}
});
if (on_off_pref === 'y') {
//Execute main functionality here only if the button in popup.html is on.
}
});
So, in short, I need to preserve the settings on popup.html and use those settings in the content script to determine whether or not to run the main part.
I have looked at the other StackOverflow solutions, but I have not been able to get any of them to work.
Any help on resolving this issue would be thoroughly appreciated!
see what #Xan said
You just forgot # in $('myonoffswitch').attr('checked', true);
your webextension needs the storage permission. See https://sites.google.com/site/getsnippet/browser/chrome/extensions/storage

How to Detect Browser Back Button event - Cross Browser

How do you definitively detect whether or not the user has pressed the back button in the browser?
How do you enforce the use of an in-page back button inside a single page web application using a #URL system?
Why on earth don't browser back buttons fire their own events!?
(Note: As per Sharky's feedback, I've included code to detect backspaces)
So, I've seen these questions frequently on SO, and have recently run into the issue of controlling back button functionality myself. After a few days of searching for the best solution for my application (Single-Page with Hash Navigation), I've come up with a simple, cross-browser, library-less system for detecting the back button.
Most people recommend using:
window.onhashchange = function() {
//blah blah blah
}
However, this function will also be called when a user uses on in-page element that changes the location hash. Not the best user experience when your user clicks and the page goes backwards or forwards.
To give you a general outline of my system, I'm filling up an array with previous hashes as my user moves through the interface. It looks something like this:
function updateHistory(curr) {
window.location.lasthash.push(window.location.hash);
window.location.hash = curr;
}
Pretty straight forward. I do this to ensure cross-browser support, as well as support for older browsers. Simply pass the new hash to the function, and it'll store it for you and then change the hash (which is then put into the browser's history).
I also utilise an in-page back button that moves the user between pages using the lasthash array. It looks like this:
function goBack() {
window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
//blah blah blah
window.location.lasthash.pop();
}
So this will move the user back to the last hash, and remove that last hash from the array (I have no forward button right now).
So. How do I detect whether or not a user has used my in-page back button, or the browser button?
At first I looked at window.onbeforeunload, but to no avail - that is only called if the user is going to change pages. This does not happen in a single-page-application using hash navigation.
So, after some more digging, I saw recommendations for trying to set a flag variable. The issue with this in my case, is that I would try to set it, but as everything is asynchronous, it wouldn't always be set in time for the if statement in the hash change. .onMouseDown wasn't always called in click, and adding it to an onclick wouldn't ever trigger it fast enough.
This is when I started to look at the difference between document, and window. My final solution was to set the flag using document.onmouseover, and disable it using document.onmouseleave.
What happens is that while the user's mouse is inside the document area (read: the rendered page, but excluding the browser frame), my boolean is set to true. As soon as the mouse leaves the document area, the boolean flips to false.
This way, I can change my window.onhashchange to:
window.onhashchange = function() {
if (window.innerDocClick) {
window.innerDocClick = false;
} else {
if (window.location.hash != '#undefined') {
goBack();
} else {
history.pushState("", document.title, window.location.pathname);
location.reload();
}
}
}
You'll note the check for #undefined. This is because if there is no history available in my array, it returns undefined. I use this to ask the user if they want to leave using a window.onbeforeunload event.
So, in short, and for people that aren't necessarily using an in-page back button or an array to store the history:
document.onmouseover = function() {
//User's mouse is inside the page.
window.innerDocClick = true;
}
document.onmouseleave = function() {
//User's mouse has left the page.
window.innerDocClick = false;
}
window.onhashchange = function() {
if (window.innerDocClick) {
//Your own in-page mechanism triggered the hash change
} else {
//Browser back button was clicked
}
}
And there you have it. a simple, three-part way to detect back button usage vs in-page elements with regards to hash navigation.
EDIT:
To ensure that the user doesn't use backspace to trigger the back event, you can also include the following (Thanks to #thetoolman on this Question):
$(function(){
/*
* this swallows backspace keys on any non-input element.
* stops backspace -> back
*/
var rx = /INPUT|SELECT|TEXTAREA/i;
$(document).bind("keydown keypress", function(e){
if( e.which == 8 ){ // 8 == backspace
if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
e.preventDefault();
}
}
});
});
You can try popstate event handler, e.g:
window.addEventListener('popstate', function(event) {
// The popstate event is fired each time when the current history entry changes.
var r = confirm("You pressed a Back button! Are you sure?!");
if (r == true) {
// Call Back button programmatically as per user confirmation.
history.back();
// Uncomment below line to redirect to the previous page instead.
// window.location = document.referrer // Note: IE11 is not supporting this.
} else {
// Stay on the current page.
history.pushState(null, null, window.location.pathname);
}
history.pushState(null, null, window.location.pathname);
}, false);
Note: For the best results, you should load this code only on specific pages where you want to implement the logic to avoid any other unexpected issues.
The popstate event is fired each time when the current history entry changes (user navigates to a new state). That happens when user clicks on browser's Back/Forward buttons or when history.back(), history.forward(), history.go() methods are programatically called.
The event.state is property of the event is equal to the history state object.
For jQuery syntax, wrap it around (to add even listener after document is ready):
(function($) {
// Above code here.
})(jQuery);
See also: window.onpopstate on page load
See also the examples on Single-Page Apps and HTML5 pushState page:
<script>
// jQuery
$(window).on('popstate', function (e) {
var state = e.originalEvent.state;
if (state !== null) {
//load content with ajax
}
});
// Vanilla javascript
window.addEventListener('popstate', function (e) {
var state = e.state;
if (state !== null) {
//load content with ajax
}
});
</script>
This should be compatible with Chrome 5+, Firefox 4+, IE 10+, Safari 6+, Opera 11.5+ and similar.
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
alert('hello world');
}
This is the only one solution that worked for me (it's not a onepage website).
It's working with Chrome, Firefox and Safari.
I had been struggling with this requirement for quite a while and took some of the solutions above to implement it. However, I stumbled upon an observation and it seems to work across Chrome, Firefox and Safari browsers + Android and iPhone
On page load:
window.history.pushState({page: 1}, "", "");
window.onpopstate = function(event) {
// "event" object seems to contain value only when the back button is clicked
// and if the pop state event fires due to clicks on a button
// or a link it comes up as "undefined"
if(event){
// Code to handle back button or prevent from navigation
}
else{
// Continue user action through link or button
}
}
Let me know if this helps. If am missing something, I will be happy to understand.
In javascript, navigation type 2 means browser's back or forward button clicked and the browser is actually taking content from cache.
if(performance.navigation.type == 2)
{
//Do your code here
}
Correct answer is already there to answer the question. I want to mention new JavaScript API PerformanceNavigationTiming, it's replacing deprecated performance.navigation.
Following code will log in console "back_forward" if user landed on your page using back or forward button. Take a look at compatibility table before using it in your project.
var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
console.log(perfEntries[i].type);
}
This will definitely work (For detecting back button click)
$(window).on('popstate', function(event) {
alert("pop");
});
My variant:
const inFromBack = performance && performance.getEntriesByType( 'navigation' ).map( nav => nav.type ).includes( 'back_forward' )
Browser: https://jsfiddle.net/Limitlessisa/axt1Lqoz/
For mobile control: https://jsfiddle.net/Limitlessisa/axt1Lqoz/show/
$(document).ready(function() {
$('body').on('click touch', '#share', function(e) {
$('.share').fadeIn();
});
});
// geri butonunu yakalama
window.onhashchange = function(e) {
var oldURL = e.oldURL.split('#')[1];
var newURL = e.newURL.split('#')[1];
if (oldURL == 'share') {
$('.share').fadeOut();
e.preventDefault();
return false;
}
//console.log('old:'+oldURL+' new:'+newURL);
}
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
<!DOCTYPE html>
<html>
<head>
<title>Back Button Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body style="text-align:center; padding:0;">
Share
<div class="share" style="">
<h1>Test Page</h1>
<p> Back button press please for control.</p>
</div>
</body>
</html>
See this:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
it works fine...
I was able to use some of the answers in this thread and others to get it working in IE and Chrome/Edge. history.pushState for me wasn't supported in IE11.
if (history.pushState) {
//Chrome and modern browsers
history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event) {
history.pushState(null, document.title, location.href);
});
}
else {
//IE
history.forward();
}
A full-fledged component can be implemented only if you redefine the API (change the methods of object ' history ')
I will share the class just written.
Tested on Chrome and Mozilla
Support only HTML5 and ECMAScript5-6
class HistoryNavigation {
static init()
{
if(HistoryNavigation.is_init===true){
return;
}
HistoryNavigation.is_init=true;
let history_stack=[];
let n=0;
let current_state={timestamp:Date.now()+n};
n++;
let init_HNState;
if(history.state!==null){
current_state=history.state.HNState;
history_stack=history.state.HNState.history_stack;
init_HNState=history.state.HNState;
} else {
init_HNState={timestamp:current_state.timestamp,history_stack};
}
let listenerPushState=function(params){
params=Object.assign({state:null},params);
params.state=params.state!==null?Object.assign({},params.state):{};
let h_state={ timestamp:Date.now()+n};
n++;
let key = history_stack.indexOf(current_state.timestamp);
key=key+1;
history_stack.splice(key);
history_stack.push(h_state.timestamp);
h_state.history_stack=history_stack;
params.state.HNState=h_state;
current_state=h_state;
return params;
};
let listenerReplaceState=function(params){
params=Object.assign({state:null},params);
params.state=params.state!==null?Object.assign({},params.state):null;
let h_state=Object.assign({},current_state);
h_state.history_stack=history_stack;
params.state.HNState=h_state;
return params;
};
let desc=Object.getOwnPropertyDescriptors(History.prototype);
delete desc.constructor;
Object.defineProperties(History.prototype,{
replaceState:Object.assign({},desc.replaceState,{
value:function(state,title,url){
let params={state,title,url};
HistoryNavigation.dispatchEvent('history.state.replace',params);
params=Object.assign({state,title,url},params);
params=listenerReplaceState(params);
desc.replaceState.value.call(this,params.state,params.title,params.url);
}
}),
pushState:Object.assign({},desc.pushState,{
value:function(state,title,url){
let params={state,title,url};
HistoryNavigation.dispatchEvent('history.state.push',params);
params=Object.assign({state,title,url},params);
params=listenerPushState(params);
return desc.pushState.value.call(this, params.state, params.title, params.url);
}
})
});
HistoryNavigation.addEventListener('popstate',function(event){
let HNState;
if(event.state==null){
HNState=init_HNState;
} else {
HNState=event.state.HNState;
}
let key_prev=history_stack.indexOf(current_state.timestamp);
let key_state=history_stack.indexOf(HNState.timestamp);
let delta=key_state-key_prev;
let params={delta,event,state:Object.assign({},event.state)};
delete params.state.HNState;
HNState.history_stack=history_stack;
if(event.state!==null){
event.state.HNState=HNState;
}
current_state=HNState;
HistoryNavigation.dispatchEvent('history.go',params);
});
}
static addEventListener(...arg)
{
window.addEventListener(...arg);
}
static removeEventListener(...arg)
{
window.removeEventListener(...arg);
}
static dispatchEvent(event,params)
{
if(!(event instanceof Event)){
event=new Event(event,{cancelable:true});
}
event.params=params;
window.dispatchEvent(event);
};
}
HistoryNavigation.init();
// exemple
HistoryNavigation.addEventListener('popstate',function(event){
console.log('Will not start because they blocked the work');
});
HistoryNavigation.addEventListener('history.go',function(event){
event.params.event.stopImmediatePropagation();// blocked popstate listeners
console.log(event.params);
// back or forward - see event.params.delta
});
HistoryNavigation.addEventListener('history.state.push',function(event){
console.log(event);
});
HistoryNavigation.addEventListener('history.state.replace',function(event){
console.log(event);
});
history.pushState({h:'hello'},'','');
history.pushState({h:'hello2'},'','');
history.pushState({h:'hello3'},'','');
history.back();
```
Here's my take at it. The assumption is, when the URL changes but there has no click within the document detected, it's a browser back (yes, or forward). A users click is reset after 2 seconds to make this work on pages that load content via Ajax:
(function(window, $) {
var anyClick, consoleLog, debug, delay;
delay = function(sec, func) {
return setTimeout(func, sec * 1000);
};
debug = true;
anyClick = false;
consoleLog = function(type, message) {
if (debug) {
return console[type](message);
}
};
$(window.document).click(function() {
anyClick = true;
consoleLog("info", "clicked");
return delay(2, function() {
consoleLog("info", "reset click state");
return anyClick = false;
});
});
return window.addEventListener("popstate", function(e) {
if (anyClick !== true) {
consoleLog("info", "Back clicked");
return window.dataLayer.push({
event: 'analyticsEvent',
eventCategory: 'test',
eventAction: 'test'
});
}
});
})(window, jQuery);
The document.mouseover does not work for IE and FireFox.
However I have tried this :
$(document).ready(function () {
setInterval(function () {
var $sample = $("body");
if ($sample.is(":hover")) {
window.innerDocClick = true;
} else {
window.innerDocClick = false;
}
});
});
window.onhashchange = function () {
if (window.innerDocClick) {
//Your own in-page mechanism triggered the hash change
} else {
//Browser back or forward button was pressed
}
};
This works for Chrome and IE and not FireFox. Still working to get FireFox right. Any easy way on detecting Browser back/forward button click are welcome, not particularly in JQuery but also AngularJS or plain Javascript.
I solved it by keeping track of the original event that triggered the hashchange (be it a swipe, a click or a wheel), so that the event wouldn't be mistaken for a simple landing-on-page, and using an additional flag in each of my event bindings. The browser won't set the flag again to false when hitting the back button:
var evt = null,
canGoBackToThePast = true;
$('#next-slide').on('click touch', function(e) {
evt = e;
canGobackToThePast = false;
// your logic (remember to set the 'canGoBackToThePast' flag back to 'true' at the end of it)
}
<input style="display:none" id="__pageLoaded" value=""/>
$(document).ready(function () {
if ($("#__pageLoaded").val() != 1) {
$("#__pageLoaded").val(1);
} else {
shared.isBackLoad = true;
$("#__pageLoaded").val(1);
// Call any function that handles your back event
}
});
The above code worked for me. On mobile browsers, when the user clicked on the back button, we wanted to restore the page state as per his previous visit.
Solution for Kotlin/JS (React):
import org.w3c.dom.events.Event
import kotlin.browser.document
import kotlin.browser.window
...
override fun componentDidMount() {
window.history.pushState(null, document.title, window.location.href)
window.addEventListener("popstate", actionHandler)
}
...
val actionHandler: (Event?) -> Unit = {
window.history.pushState(
null,
document.title,
window.location.href
)
// add your actions here
}
Was looking for a solution for this issue and put together a simple skeleton test html based on a few answers here and the MDN Web Doc pages for History.pushState() and WindowEventHandlers.onpopstate.
The following HTML and JavaScript is easy enough to copy and paste and test.
Works with back and forward browser buttons, shortcut keys, adds a change to the URL (which is important in some cases).
Simply enough to add to existing code key points and should be expandable too.
<html>
<body>
<div id="p1">Option 1</div>
<div id="p2">Option 2</div>
<div id="p3">Option 3</div>
<div id="p4">Option 4</div>
<div id="c"></div>
<script>
var chg={
set:function(str){
var d=document.getElementById("c");
d.textContent=str;
},
go:function(e){
var s={"p":this.id};
chg.set(s.p);
hstry.add(s);
}
};
var hstry={
add:function(s){
var u=new URL(window.location);
u.searchParams.set("x",s.p);
window.history.pushState(s,"",u);
},
adjust:function(state){
if(state.p){
chg.set(state.p);
}
}
};
window.onpopstate=function(e){
console.log("popstate, e.state:["+ JSON.stringify(e.state) +"]");
hstry.adjust(e.state);
}
window.onload=function(){
var i,d,a=["p1","p2","p3","p4"];
for(i=0;i<a.length;i++){
d=document.getElementById(a[i]);
d.addEventListener("click",chg.go,false);
}
}
</script>
</body>
</html>
browser will emit popstate event if you navigate through your app with calling
window.history.pushState({},'','/to')
If you manually enter the addresses into the address bar and click on the back button, popstate event will NOT be fired.
If you navigate in your app with this simplified function
const navigate = (to) => {
window.history.pushState({}, ",", to);
};
then this will work
const handlePopstate = () => {
console.log("popped");
};
window.addEventListener("popstate", handlePopstate);
I tried the above options but none of them is working for me. Here is the solution
if(window.event)
{
if(window.event.clientX < 40 && window.event.clientY < 0)
{
alert("Browser back button is clicked...");
}
else
{
alert("Browser refresh button is clicked...");
}
}
Refer this link http://www.codeproject.com/Articles/696526/Solution-to-Browser-Back-Button-Click-Event-Handli for more details

My setInterval function isn't working at all, Google Chrome

I am a fairly new programmer, and currently am trying to understand OOP from the JS side of things. I have some pretty basic code for a flashing cursor, yet for some reason it isnt working. The page loads, and the cursor just appears onscreen with no changing. The code is below:
<html>
<head>
<title>Cursor</title>
<script src="jquery.js"></script>
<script>
var str = null;
var counter = 0;
var flipFlop = function() {
alert("working");
if(counter === 0) {
document.getElementbyId('console').style.visibility='visible';
counter = 1;
}
else if(counter === 1) {
document.getElementbyId('console').style.visibility='hidden';
counter = 0;
}
else {
//debug alert
alert("function broken.");
}
};
var setIntOnload = function() {
setInterval(function() {
flipFlop();
}, 1000);
};
</script>
</head>
<body onload="setIntOnload()">
<div id="console">
|
</div>
</body>
</html>
Not sure why this isnt working... Help would be appreciated :)
PS First Post :D
Its Working
Change getElementById instead of getElementbyId
Fiddle
You have a typo in your code. Use getElementById instead of getElementbyId. JavaScript variable names (and methods) are case sensitive.
Fiddle: http://jsfiddle.net/FcrQ7/
Always check your browser console in case something in your code is not working. You had the following error:
Uncaught TypeError: Object # has no method 'getElementbyId'

Categories

Resources