I have a variable speed controlled by the user from keyboard, and I want to display it current value all the time.
I tried:
var user_speed= 1; //init
<h3 style="float:left;" id="userspeed"></h3>
document.getElementById("userspeed").innerHTML = user_speed.toFixed(2);
but what I get is only speed = 1 and it never changed.
Is there a way to keep changing the displayed value, without creating a function that fire each time the user change the speed and execute document.getElementById()... again?
Why not use setInterval to update the value like so:
var speed = 1; //init
setInterval(function(){
document.getElementById("userspeed").innerHTML = user_speed.toFixed(2);
}, 1000);
This will update the value every 1 second (1000 ms).
You are only getting the initial value, because you are calling only once that code.
As you said, if you want to change the value you should need to create a call to that function in order to renew the value.
I think there is no way around. You may have to use a function and an event. Because how would you know or trigger some calculation when you dont know on which point the user entered some keys?
See this question
UPDATE: As you maybe know setInterval/setTimeout are evil!
If you take a look at this link, you will see that you should avoid those functions for not very good reasons. Simplified:
... The first argument is a string, you actually pass it some JavaScript that will be evaluated at a global namespace when the timer expires. Read the evils of evals again above and then come back. The good thing is that you are not required to pass in a string of JavaScript code. ...
Related
I want to reset a variable automatically without any user interaction to 0 every midnight.
How to do that in vanilla Javascript?
Or does Chrome have any default method to do it. Because I store that variable in Chrome.storage.local.
What is the best way to do it in either vanilla JS or using chrome apis?
It is impossible to do so automatically without user accessing the page.
But, you can add script to the page which onload check the last time the value was stored and if the time passed you can reset the variable.
Rough code to make this:
const isToday = (someDate) => {
const today = new Date()
return someDate.getDate() == today.getDate() &&
someDate.getMonth() == today.getMonth() &&
someDate.getFullYear() == today.getFullYear()
}
window.onload = function init() {
const { value, date } = JSON.parse(localStorage.getValue('key'));
if (!isToday(date)) {
localStorage.setValue('key', JSON.stringify({ date: new Date(), value: defaultValue}))
}
}
You've said you're storing the value in Chrome.storage.local. Also store the date/time you saved that value. When you load it, if midnight has passed since that time, reset the value to zero.
In case the page has been left open overnight, either always load the value from storage before using it (even if you already have it in a JavaScript variable), or do the same thing at the JavaScript level (remember the date/time and reset the value). Although you can set a timer, pages that sit idle for a long period of time have their timers de-prioritized by modern browsers, so it probably wouldn't be reliable to do this with a timer.
Without server assisting to do that, you may want to implement reset_variable() to be scheduled with helping of setTimeout() https://developer.mozilla.org/en-US/docs/Web/API/setTimeout and setInterval() https://developer.mozilla.org/en-US/docs/Web/API/setInterval - But you have to trigger setInterval() at midnight first, and adjust the interval as 24h. Thus, you have to implement some algorithm to calculate when to start executing (trigger) setInterval() using the setTimeout().
With server assisting, you may want to implement a cron-like job in the server. The job may look like sending some predefined values to reset the variable on the browser.
Therefore, you can do it in diverse ways. The simplest way is over WebSocket https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API.
Explanation:
Browser/Client-side:
Implement a Listener on the browser Ex, message event https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event, whenever you caught a message, process that message if it's the predefined value to reset the variable, then someVar.reset().
Server-side:
Create a handler to connect to the client-side WebSocket Listener -WebSocket supported in most programming languages-.
Implement a cron-like job to execute a function every midnight. I have no idea if you have a server, and if so, which programming language you are using. However, a cron-like job can be implemented in several programming languages, and basically, it can be implemented natively on Unix-like OSs, you may want to ask another question if you need help regarding this.
The function should send a predefined value using the handler of the WebSocket connection.
-you can do some Security validation though-
Ok so this may sound foolish but I know how we can generate random number in javascript every x seconds, but actually I just want to receive a value from my custom template tag which is frequently updating, but when I do so by calling it repeatedly through my javascript it just gives the same value, so I think template tags just calls the function on start and store the value, however I need to get updated value every time I call my tag.
My custom_tags.py -
#register.simple_tag
def getTest():
verification_code = str(randint(100000, 999999))
return verification_code
And in my javascript -
window.setInterval(function(){
let temp5 = "{% getTest %}"
console.log(temp5)
}, 5000);
This returns me same number everytime, so is there any fix or workaround for this ?
PS I dont want to reload every x seconds so it should be done using custom template tags only.
Any help is appreciated
Take the following html:
<div id="somediv" style="display:none;"></div>
<script>
document.getElementById("somediv").style.display = 'none';
</script>
somediv is already hidden, some javascript runs, effectively doing nothing. I need code that detects when style.display has been used in javascript, regardless of if style was changed or not.
I've tried MutationObserver:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
alert(mutationRecord.target.id);
});
});
observer.observe(document.getElementById("somediv"), { attributes : true, attributeFilter : ['style'] });
The above only triggers if there was a style change. I need it to trigger regardless if there was a style change or not.
So I did come up with an answer. The way it works, is you grab every script tag, replace .style.display with your own function, and finally replace the DOM (which is the real trick):
//loop through <script> tags
$('script').each(function(){
var scripthtml = $(this).html();
if (scripthtml.indexOf('style.display') != -1){
scripthtml = scripthtml.replace(/.style.display = 'none'/g, ".customdisplay('none')");
scripthtml = scripthtml.replace(/.style.display = "none"/g, '.customdisplay("none")');
scripthtml = scripthtml.replace(/.style.display ='none'/g, ".customdisplay('none')");
scripthtml = scripthtml.replace(/.style.display ="none"/g, '.customdisplay("none")');
scripthtml = scripthtml.replace(/.style.display='none'/g, ".customdisplay('none')");
scripthtml = scripthtml.replace(/.style.display="none"/g, '.customdisplay("none")');
$(this).replaceWith('<script>' + scripthtml + '</script>');
}
});
Now here is my .style.display replacement function:
HTMLElement.prototype.customdisplay = function(showhide){
//insert whatever code you want to execute
this.style.display = showhide;
alert('Success! .style.display has been detected!');
};
.replaceWith is what actually changes the DOM. The only thing this script doesn't do, is it isn't able to look through included javascript files. Thank you all for your comments <3.
UPDATE:
When using replaceWith to add the script tag, ipad/iphone/ipod will execute the script tag a second time. to prevent this double execution, you need to do this:
$(this).replaceWith('<script>if (1==0){' + scripthtml + '}</script>');
Your functions will be valid, but anything outside of the function will not be executed.
I don't think you fully realise what you are asking for, but here is a short description of closest options I am aware of:
https://blog.sessionstack.com/how-javascript-works-tracking-changes-in-the-dom-using-mutationobserver-86adc7446401
Basically, MutationObserver is the major improvement over past here that is closest to what you want and supported in modern browsers. But the whole point of all this is it listens to changes.
You are basically asking to detect even non-changes. I don't see you getting out of this problem other than:
Writing a wrapper for the ways you use to change this in code and then instead of calling the change call the wrapper. Simple, easy, requires refactoring all the calls in code.
Overwriting the actual functions that make a change. This saves you the refactor but you are playing with fire here. Rewriting a well-known function on a global level means a PERMANENT source of problems to you and all developers who work on the project.
Polling - in short calling over and over on some element to check properties. Not only it detects changes with a lag of 0 to the polling interval it also uses resources and if you want to monitor everything you will have to write a recursion that descends through the current DOM from the top to each node and check it. You are gonna kill the performance with this. How hard I can't tell but I suspect either polling interval will be long thus increasing the detection lag or your performance will dive down like a gray falcon.
I have 1 big question for you:
What led you to the state where you need this?
You basically want the ability for a program to detect when it is using a specific part of itself (be that as it is, a core part, one implemented by the browser).
This sounds similar to request: hey whenever I change or not change a value in any variable in my code I should be able to react to it.
I am not trying to sound like Naggin Nancy here but instead encourage you to question train of thought that led to this being something you need and figure out whether you want to sink further time into this, because I don't think you are getting that what you desire easily and I suspect it came to be due to poor design decisions in the past.
I am a new student understanding javascript. I am currently having a difficult time understanding a simple concept on storing a variable on my calculator side project. My problem is when a operator (+,-,/,*) is clicked, I want to store the first value as a variable (first user input). Then after the user clicks on the digits again, the display screen will clear and display the second variable (or the second user input). Then if the operator button or equals button is pressed it will calculate the two variables (so var + var2). I have used a global variable for variable1, but I am having trouble assigning the second variable with the user input after clearing the item. I have a feeling there is a simple answer to this question, but I want to know what I am fundamentally doing wrong so I can start reviewing all the topics I need to do cover again. Anyways any help will be great! Thanks
'http://codepen.io/kevk87/pen/EVoEaa`
First thing, you have a syntax error in your statement that is causing jQuery to not select the right element. I have fixed that in my snippet below.
Second, you need to implement the equal operator to put all of this together. Meanwhile, to address your problem and point you in the right direction, You aren't really capturing the second element. Everytime the user clicks on an operator, you are reassigning the value that is on the screen to 'number' variable, then clearing the screen and assigning the value that is on the screen(which is clear because you just cleared it) to 'number2'.
One way to get around this is to check and see if the 'number' variable has a value, if so then you assign the next value to the 'number2' variable. Here's a snippet of code that does this.
$(".operator").on("click",function() {
if (number == null) {
number = $("#screen").html();
}
else {
number2 = $("#screen").html();
$("#screen").html("");
}
});
You forgot the # selector on the line $("screen").html("");, jQuery won't select the correct element. Also you haven't implemented the equal operator yet.
$(".operator").on("click",function() {
number = $("#screen").html();
$("screen").html("");
number2 = $("#screen").html();
});
i try to figure out a greasemonkey script that replaces every onmousedown on a site with an ondblclick. And i want it to constantly update, like every 1,5 Seconds, because the page refreshes using AJAX.
This is the script i came up with, but it doesn't seem to be working.
window.setInterval(document.body.innerHTML= document.body.innerHTML.replace('onmousedown','ondblclick');,1500);
The page it should work with is internal use only. But a good example would be the google search, where onmousedown is used for the links of the results to swap out the URL before you click it.
I also tried it without the semicolon after the document.body.innerHTML.replace.
I'm really new to JavaScript, but since i'm the only one in the company who can code, this one is stuck with me.
Any help would be appreciated.
Also, a small "side question"
Do i have to use #exclude, or is it enough to only use #include internal.companysite.tld* so it will only work on this site ?
A direct answer: you need to supply a function to setInterval - and it's best to set a variable so that you can later cancel it with clearInterval() if necessary.
function myF(){document.body....;}
var myIntv = setInterval(myF, 1500);
You could also do it using an anonymous function in one line as you're trying to do... do that this way:
var myIntv = setInterval(function(){document.body....;}, 1500);
I wouldn't suggest this as the solution to your problem. What it sounds like you want to do is manipulate the active DOM - not really change the UI. You likely need something like this:
var objs = document.getElementsBy__(); // ById/ByName/etc - depends on which ones you want
for (var i in objs){objs[i].ondblclick = objs[i].onmousedown;objs[i].onmousedown = undefined;} // just an example - but this should convey the basic idea
Even better, if you can use jQuery, then you'll be able to select the proper nodes more easily and manipulate the event handlers in a more manageable way:
$(".class.for.example").each(function(){this.ondblclick = this.onmousedown;this.onmousedown = undefined;}); // just an example - there are multiple ways to set and clear these