how toggle between two functions automatically without button - javascript

I want to toggle between interstitial ads and rewarded video ads in my game html use it construct 2 every time loading layout like if first runtime show interstitial and if loading again show rewarded video ads and repeat this every time .
SysActs.prototype.GoToLayout = function(to) {
showInterstitialAd();
showRewardedVideoAd();
if (this.runtime.isloading)
return; // cannot change layout while loading on loader layout
if (this.runtime.changelayout)
return; // already changing to a different layout
;
this.runtime.changelayout = to;
};
my testcode aftert toggle between two functions automatically
SysActs.prototype.GoToLayout = function (to)
{
if($(this).data('toggleAds') == 1) {
toggleAds = 0;
if (this.runtime.isloading || showRewardedVideoAd())
return;
if (this.runtime.changelayout )
return;
;
this.runtime.changelayout = to;
}
else {
toggleAds = 1;
if (this.runtime.isloading || showInterstitialAd() )
return;
if (this.runtime.changelayout )
return;
;
this.runtime.changelayout = to;
showInterstitialAd();
}
$(this).data('toggleAds', toggleAds);
return false;
};
i try this but is not work?

It doesn't work because you're not persisting anything on page reload, so you get the exact same page and same code, so the behaviour is exactly the same. You can't toggle this way. Store a state in the localStorage and read it on page load.
const previousState = localStorage.getItem("state"); // null, "interstitial" or "rewarded"
let currentState;
if(previousState){
currentState = previousState === "interstitial" ? "rewarded" : "interstitial";
} else { // First page load ever
currentState = "rewarded"; // or "interstitial", initialize it like you want
}
localStorage.setItem("previousState", currentState); // It's saved for next reload
// Now do something with currentState

Related

Old JavaScript no longer working. Chrome says Event.path is deprecated, but I don't use Event.path in my code

I built a game of concentration over a year ago. I tried to run it today and when you click on the back of a "card" it's supposed to reveal a picture, but it does not. Chrome dev tools says "Event.path is deprecated and will be removed. Please use Event.composedPath() instead."
Nowhere in my code do I use Event.path and I can't seem to figure out what specifically is broken.
Here is the code I do have for a click event. The first function is repeated for all 24 cards and calls the second function which is supposed to reveal the picture "underneath" the back of the card and if both revealed pictures are the same they remain revealed, otherwise they both get reset to show the back of the card.
//onClick functions for all card images
pic1.onclick = () => {
console.log(revealedPics); //this sends the file link of the revealed picture to the console
if (isClicked(pic1) === false) {
pic1.src = picArray[0];
checkIfMatch(pic1);
} else if (trackRevealedCardsArray.includes(pic1.src) === true) {
return;
} else {
pic1.src = backOfCard;
}
console.log(revealedPics);
}
//Check if two revealed images are a match
const checkIfMatch = (pic) => {
if (revealedPics === 1) {
firstPic = pic;
} else if (revealedPics === 2) {
secondPic = pic;
if (firstPic.src === secondPic.src) {
revealedPics = 0;
totalPairs--;
trackRevealedCardsArray.push(firstPic.src);
console.log(`total pairs ${totalPairs}`);
if (totalPairs === 0) {
window.setTimeout(gameOver, 500);
}
} else {
window.setTimeout(function() {
firstPic.src = backOfCard;
secondPic.src = backOfCard;
}, 800);
window.setTimeout(resetRevealedPics, 800);
}
}
}
I've checked to make sure all my paths are correct and they are. When I run the same html files from my local drive it works perfectly.

Angular - window - EventListener - refresh main tab when other close

I use Angular 7. I deal with documents When I click on "INDEXER" button, a second tab is opened with content of the first document and a form.
When the form is filled, the second document appears on this second tab etc...
When all the documents are ok, this second tab close and and the first main tab must be refreshed.
Code for second tab :
iterate(index) {
this.loadingAction = false;
if (index < this.workflowList.length) {
this.getDetails(this.workflowList[index]);
} else {
localStorage.setItem('actualise', 'true');
window.close();
}
}
Code for the first tab
ngOnInit() {
const that = this;
// COMMUNICATION INTER ONGLETS
window.addEventListener('storage', (event) => {
console.log(event.key)
// console.log('event storage = LocaleStorage : ' + event.storageArea !== localStorage);
if (event.storageArea !== localStorage) {
return;
}
if (event.key === 'actualise') {
// if (event.storageArea.getItem('actualise') === 'true') {
console.log('appel backend')
this.refresh();
} else {
console.log(localStorage.getItem('actualise'));
}
});
}
Problem is that backend is called multiple times and when there are a lot of documents, it's very long.
I updated code in order the backend is called one time, it works but the screen is not refreshed
Original : Backend called multiple time and screen refresh
Update: backend called one time but screen is not refreshed
How can I solve that ?

Reduce the impact of third-party code (zendesk)

<script
id="ze-snippet"
src="https://static.zdassets.com/ekr/snippet.js?key=some_zendesk_key"
/>
I'm trying to optimize my web site performance. I've faced a big impact of third-party code to my performance, I think all my bundle has a lower size than zendesk code. How can I load it without impacting on the main thread? Should I use the async or defer tags? Or which approach is better for this case?
This seems to be an issue that tortures so many people without a clear solution.
What I managed to do it to reduce the block time by adding this configuration.
window.zESettings = {
webWidget: {
chat: {
connectOnPageLoad: false
}
}
};
ref https://developer.zendesk.com/embeddables/docs/widget/settings#connectonpageload
ps
I did a performance test to my zendesk helpdesk "domain.zendesk.com" and the results there were even worse
I came across this issue recently and made this hack using a function for loading the zendesk script only when you reached certain point of the doc. I know is kind of dirty but it works:
<script defer type="text/javascript">
(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i,el){
function visPx(){
var H = $(this).height(),
r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));
} visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
$('#trigger_div').inViewport(function(px){
if(px) {
//zopim code
}
});
Starting from this article https://www.newmediacampaigns.com/blog/maintaining-great-site-performanc-using-zendesk-web-widget I have implemented a solution that significantly reduces the load time by at least 3 seconds (in Google Lighthouse).
I have created a fake button in the HTML that will load the Zendesk script and open the widget when clicked. It will also load a localStorage item that will prevent this from happening on subsequent page loads.
⚠️ Warning:
The code relies heavily on how the widget is currently implemented (for example it expects a #launcher and a #webWidget element to appear on the page), so it can break as soon as the original code changes, but at least we will have an improvement in the loading times until they fix it.
Here is the most important part of the code:
HTML Button
<button class="zendesk-button">
<span class="left-icon">
<!-- here you insert the icon -->
</span>
<span class="text">Chat</span>
</button>
JavaScript code
// select the button
const zendeskButton = document.querySelector('.zendesk-button');
// add the script to the page
const loadZendeskScript = () => {
const zenDeskScript = document.createElement("script");
zenDeskScript.id = "ze-snippet";
zenDeskScript.src = "https://static.zdassets.com/ekr/snippet.js?key=HERE_YOU_INSERT_YOUR_KEY";
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] || document.getElementsByTagName('script')[0].parentNode).insertBefore(zenDeskScript, null);
};
// a poller that waits for a condition and executes a callback
const poller = (comparison, callback, timerStep = 250, maxTime = 5000) => {
// why setTimeout instead of setInterval
// https://stackoverflow.com/questions/8682622/using-setinterval-to-do-simplistic-continuous-polling
let currTime = 0;
const checkCondition = () => {
// `comparison` is a function so the condition is always up-to-date
if (comparison() === true) {
callback();
} else if (currTime <= maxTime) {
currTime += timerStep;
setTimeout(checkCondition, timerStep);
}
};
checkCondition(); // calling the function
};
// load the script and execute a callback if provided
const loadZendeskChat = callback => {
loadZendeskScript();
if (callback) {
callback();
}
};
// this function opens the chat
const openZendeskChat = () => {
poller(
() => {
// check that zendesk-related functions are available
return typeof zE !== 'undefined';
},
() => {
// open the widget
zE('webWidget', 'open');
poller(
() => {
// check that the elements exist and that the opacity is already set to "1"
const launcher = document.querySelector('#launcher');
const webWidget = document.querySelector('#webWidget');
return launcher !== null && webWidget !== null && webWidget.style.opacity === '1';
},
() => {
// hide the fake button
zendeskButton.style.opacity = '0';
// save in localStorage
localStorage.setItem('zd_hasOpened', 'true');
}
);
}
);
};
// zendesk management
if (localStorage.getItem('zd_hasOpened')) {
// load the zendesk widget if we find that it was opened
loadZendeskChat();
} else {
// show the fake button if it's the first time it shows
zendeskButton.style.opacity = '1';
}
// This will run when the .zendesk-button element is clicked
zendeskButton.addEventListener('click', () => {
// add a 'Loading' text to the button, as the widget will take some time to load (between 1 and 2 seconds on my laptop)
zendeskButton.querySelector('.text').innerHTML = 'Loading';
// load the zendesk widget
// open the widget and hide the fake button
loadZendeskChat(openZendeskChat);
});
Regarding styles, I have pretty much copied the style in the original widget, converting ems to pixels, but one part I'd like to highlight is the focus style, because in my opinion it helps telling the user that something is happening.
.zendesk-button:focus {
outline: none;
box-shadow: inset 0 0 0 0.21429rem rgb(255 255 255 / 40%) !important;
}

JavaScript ignore alert if reloading page

I am detecting the end of a webrtc stream in JavaScript like this...
stream.getVideoTracks()[0].onended = () => {
alert('Feed Has Ended');
};
This is working correctly, but if the user refreshes or reloads the page then the alert is also shown.
I understand that this is technically correct, but how can I get it to not display the alert under those conditions?
Why don't you use a global boolean to check if video is playing or not? When you will reload or refresh the page, isVideoRunning will become false and alert won't show.
Like
this.isVideoRunning = false;
On addtrack,
this.rtcPeerCon_.ontrack = function (event) {
if (!this.rtcPeerCon_) {
return;
}
if( !this.remoteVideo_ ) {
return;
}
this.remoteVideo_.srcObject = event.streams[0];
this.isVideoRunning = true;
}
then in your onStream ended callback you can check
if (this.isVideoRunning) {
alert('whatever');
this.isVideoRunning = false;
}
(I wanted this to be comment but I am not allowed to comment yet)

Persist a page action's state in a chrome extension

So, I have the following code:
var clicks = 0; // click counter
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook.com") > -1) {
chrome.pageAction.show(tabId);
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
chrome.pageAction.setIcon({path: "dontlike.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "idontlike", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Hide like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
}
else {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
}
// wrap coutner around
clicks++;
if (clicks > 1)
clicks = 0;
});
for a chrome extension that hides all "Like" buttons on facebook when a pageaction icon is clicked. This works; however, any time a new facebook url is loaded, the state of the extension is lost, e.g. if the button is in dislike mode (hide all likes), if I go to a new page, it is reset to like mode.
I had an idea to persist the state of the extension using the click counter, and to make the code more functional with something like the following
var clicks = 0; // click counter
function like() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
function dislike() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook.com") > -1) {
chrome.pageAction.show(tabId);
if (clicks == 0) {
like();
}
else {
dislike();
}
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
like();
}
else {
dislike();
}
});
But that code doesn't work at all (when I click on the page action icon, nothing happens and no error messages appear in the chrome console).
I'm new to JS and Chrome Extensions. Is there an easy way to persist the state of my extension, and a better way to execute the script I need to hide all like buttons?
Thank you!
The question of states in chrome extension can have several answers. The choice depend of the situation. Whet I have understand in your case is that you only have tow states, so I will give you some idea.
1. Persistent background script
By default, background script is loaded at chrome startup, so it lives during the whole execution of chrome, until the user explicitly close chrome. In combination with Content Script, you can have a state full system.
So You can use this background script to save a state during the execution and inform listening content scripts of the changes :
background.js
var state = 0;
chrome.pageAction.onClicked.addListener(function(tab) {
if (state = 0) {
state = 1;
state0Actions(); //Do what you want
}
else {
state = 0;
state1Actions(); //Do what you want
}
//Inform content scripts that the state have changed
chrome.tabs.sendMessage(tab.id, {state : state});
});
//At initialisation, Content scipts will request the current state to background script.
chrome.runtime.onMessage(function(message, sender, callback){
if(message.getState) callback({state : state});
});
You can then inject a content script to all facebook pages by adding this to your manifest.json file
"content_scripts" :
[
{
"matches": ["https://www.facebook.com/*","http://www.facebook.com/*"],
"all_frames": true,
"js": ["contentScript.js"]
}
]
It will automatically inject the contentScipt.js script to all page beginning with http(s)://www.facebook.com.
contenScript.js
//the actions to do for each states
function state0Actions()
{
//Do what you want for the state 0
}
function state1Actions()
{
//Do what you want for the state 1
}
//Message will be received at each update of state in the background page
chrome.runtime.onMessage.addListner(function(message, sender, callback))
{
//Check the message is valid
if(message.state == null)
{
console.log("Unreconized message");
return;
}
//Do actions for the right state
//You also can use if statements here... Switch are more used when there is lots of states
switch(message.state) {
case 0 : state0Actions(); break;
case 1 : state1Actions(); break;
}
}
//Request the current state to initialise the script
chrome.runtime.sendMessage({getState: true});
Here, the onMessage handler will be call a first time when he is loaded and then each time the background change the state.
Pay attention that the state will be reset at the chrome startup.
2. Chrome storage
You can use chrome.storage API to manage the state. The main point of this is that the state will be saved and will not be reset at chrome startup.
To do this, you have pretty the same background code :
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.storage.local.get("state", function(result)
{
//First initialisation of the state in the local storage
if(result.state == null)
{
chrome.storage.local.set({state: 0});
state0Actions(); //Do what you want
}
else if (result.state == 0) {
result.state = 1;
state0Actions(); //Do what you want
}
else {
result.state = 0;
state1Actions(); //Do what you want
}
//Save the new state to the storage
chrome.storage.set({state: result.state});
}
});
And the content script will listen changes of the local storage instead of wating update notification from the background page :
//the actions to do for each states
function state0Actions()
{
//Do what you want for the state 0
}
function state1Actions()
{
//Do what you want for the state 1
}
chrome.storage.local.onChanged.addListener(function(changes, areaName)
{
if(areaName != "local" || changes.state == null) return;
switch(changes.state)
{
case 0 : state0Actions(); break;
case 1 : state1Actions(); break;
}
})
chrome.storage.local.get("state", function(result){
if(result.state == null) state0Actions(); //Do what you want if the state is not yet initialised
else if (result.state == 0) state0Actions(); //Do what you want
else if (result.state == 1) state1Actions(); //Do what you want
})
You also can use chrome.storage.sync instead of chrome.storage.local for a shared state with all user's devices.
This are to way to play with state. you have to compare what is the better for your use case. The code I have written is not tested, they are only example to illustrate my explanation.
Don't forget to check Chrome API documentation
When the extension is using a non-persistent background page aka Event page it is unloaded after ~5 seconds of inactivity. And every time it's reloaded the code runs again and all variables are re-initialized, thus losing the previous state.
The solution is to store the state in localStorage which doesn't require any additional permissions in manifest.json:
Initialization:
var clicks = localStorage.clicks || 0; // click counter
Toggling and storing (no need for ++ and if):
var clicks = localStorage.clicks = 1 - clicks;
The value will be stringified and stored as "0" or "1" but for the above arithmetic it's not a problem.

Categories