I apologize I am new to javascript. I am trying to toggle a relay from a website using setInterval. The relay is a Sainsmart with 16 channels and it is connected to an arduino controlled by a raspberry pi. The goal is to eventually have three independent relays toggling at particular intervals. However, every attempt to get the first one working fails. In addition, every time I add a setInterval within a function or global, freezes the live streaming video from my ip camera. I am using a sandbox key through ably.
The html code and script work to toggle the relay on, and then a second button will toggle it off, but I need a single button to accomplish it.
The button initiates the sequence with a counter dictating whether the relay toggles on or off. It is set up to toggle on with an even number and off with an odd number. Any help would be greatly appreciated.
Here is the updated code I am trying to work with.
<div class="grid-item"><button id="37" onclick="startOnOff()">Start</button>
</div>
<script src="http://cdn.ably.io/lib/ably.min-1.js"></script>
<script>
var count = 0;
function startOnOff() {
var on = "37" + "on";
var off = "37" + "off";
if (counter % 2 == 0) {
toggleRelay(on);
count += 1;
} else if (count % 2 == 1) {
toggleRelay(off);
}
setInterval(startOnOff, 2000);
}
You have count in a few places and counter in one place where it should be count.
Assuming toggleRelay() is defined somewhere else in your code, try this:
var count = 0;
var on = "37" + "on";
var off = "37" + "off";
function startOnOff() {
if (count % 2 == 0) {
toggleRelay(on);
} else {
toggleRelay(off);
}
count += 1;
setTimeout(startOnOff, 2000);
}
count += 1; should be outside of the if conditional statement,
and use setTimeout() when calling startOnOff() recursively.
Related
I am second semester, taking a class in Javascript. Basically, we were given the HTML and CSS for a website, and it is supposed to do the following:
It's a number game. The computer generates a number, and you have ten tries to guess this number. If you get to zero, the computer wins, and there is a reset button which should reset all the variables and start again. Only problem is, I cannot for the life of me figure out how to reset the countDown variable after the score reaches 0. Please help. Also we are using only pure Javascript for this course for now. I don't want to cheat, I am more trying to figure out what the issue is that's holding me back.
var countDown = 10;
var computerNumber = Math.floor((Math.random() * 501) + 1);
function generate() {
playerNumber = document.getElementById("guess").value;
if (computerNumber == playerNumber && countDown > 0) {
alert("Congratulations! You've won!");
} else if (playerNumber < computerNumber && countDown > 0) {
countDown--;
document.getElementById("guesses").value = countDown;
document.getElementById("result").value = "Too Low";
} else if (playerNumber > computerNumber && countDown > 0) {
countDown--;
document.getElementById("guesses").value = countDown;
document.getElementById("result").value = "Too High";
} else if (countDown == 0) {
alert("Game Over. The Number Was " + computerNumber);
}
}
function reset() {
countDown = 10;
computerNumber = Math.floor((Math.random() * 501) + 1);
}
In the reset function, you would need to update the element that displays the countDown in the HTML
Here you need to add the reset button in the html:
<input type="button" class="reset-button" value="Reset Count">
Then grab that button in your JS below the reset function and attach an eventListener that fires the reset function when clicked:
const resetBtn = document.querySelector('.reset-button')
resetBtn.addEventListener('click', reset )
And that's it.
You would probably want the count displayed on the page, too. You could add a line in the reset function that pushes the new value of countDown into the html (with element.textContent = countDown.toString(), for example)
If you take a JS class in 2021 you should definitely use const and let instead of var, and let your teacher know why. Using var works, though, but will show a future employer that you're out of touch with what's going on in the JS world.
I'm writing a choose your own adventure program where If a specific option is chosen (example to wait) the user gets a random number between 1-10 to do push ups(the push-ups would be the user clicking on the prompt "ok" button however many times the random number is equal to) here's my code so far but I keep getting errors. I'm a complete noob so go easy on me.
var count = Math.floor((Math.random() * 10) + 1);
var setsOf10 = false;
function pushUps() {
alert("Nice! Lets see you crank out " + pushUps + "!");
}
if (setsOf10 == pushUp) {
alert("Nice! Lets see you crank out " + pushUp + "!");
setsOf10 = true;
}
for (var i=0; i<count; i++){
pushUps();
}
else {
alert("Really, thats it? Try again");
}
while ( setsOf10 == false);
}
After playing with this some more I can tell i'm close but still don't have it. and again, I'M NOT ASKING YOU TO SOLVE THIS FOR ME JUST NEED POINTERS AS TO WHAT IM DOING WRONG OR MISSING. Here's what I have, Its giving me my random number I just need it to allow me to click the "ok" button however many times the random number has assigned me.
var pushUpSets = Math.floor((Math.random() * 10) + 1);
function pushUps(){
alert(pushUpSets);
if (pushUpSets < 3){
var weak = "Thats it? Weak sauce!";
alert(weak);
}
else{
alert("Sweet lets get some reps in!");
}
for (i=0; i>3; i++){
pushUps(pushUpSets);
}
}
Here, the make a choice button is just dummy to allow us to go to do push ups. Each click decrements our count.
// This is important, we use this event to wait and let the HTML (DOM) load
// before we go ahead and code.
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#choice').addEventListener('click', makeChoice);
});
function makeChoice() {
// Call a method to set random pushups and setup the click event
setUpPushUp();
// Here we change the display style of the push up section so that it shows to the player.
document.querySelector('.activity').style.display = 'block';
}
// The pushups variable is declared at the document level
// This way our setUpPushUp and doPushUp functions have easy access.
let pushUps = 0;
function setUpPushUp() {
// Create a random number of pushups, in sets of 10.
// We add an extra 1 so we can call the doPushUp method to initialize.
pushUps = (Math.floor((Math.random() * 10)+1)*10)+1 ;
// Add a click event to the push up button and call our doPushUp method on each click.
document.querySelector('#push').addEventListener('click', doPushUp);
// This is just an init call, it will use the extra 1 we added and place test in our P tag.
doPushUp();
}
function doPushUp() {
// Get a reference to our output element, we will put text to player here.
let result = document.querySelector('p');
// They have clicked, so remove a push up.
pushUps--;
// See if the player has done all the required push ups (i.e. pushUps is 0 or less.)
if (pushUps > 0) {
result.innerText = `You need to crank out ${pushUps} pushUps`;
} else {
result.innerText = 'Nice work!';
}
}
.activity {
display: none;
}
<button id="choice">Make a choice !</button>
<div class="activity">
<p></p>
<button id="push">Push</button>
</div>
I've put together a small test at http://jsfiddle.net/Hwqb3/3/ this morning. This is on the back of a larger project with pagination. I have tried this with native JS and jQuery. The test uses jQuery.
A quick search on SO says that Chrome handles things poorly if background-size is set, but this is not the case here. No trace of background-size in the source, and inspecting elements shows no background-size being set / inherited.
Ignore the initial page load while 5,000 elements are added to the list. It is only a few seconds, but it just so there are some elements to test with.
In Firefox 18.0.1, the moving between pages is almost instant and in IE9 there is maybe a 0.1s delay between mouse click and the paged results refreshing; However, in Chrome (24.0.1312.57 m) the delay is a noticeable 1-2 seconds.
I spent the majority of my night last night pouring over my code to see if I can find the cause before writing this test. This is bare bones and still has the issue.
I can only assume that Chrome is handling the element.style.display=''; poorly. Without that (even looping through the 5,000 elements to display='none') the thing is snappy.
Any ideas? Client wants pagination on a result set of around 4,000 - 7,500, but doesn't want page reloads and doesn't understand that they should apply filters to whittle that list down to <100, as no one is ever going to page through 200 - 375 pages looking for something specific.
Last resort is AJAX calls, which may be slightly quicker on Chrome. Untested yet though.
Thanks in advance.
Code from jsfiddle, excluding the jQuery CDN link
HTML:
First
Previous
Next
Last
<br>
<ul id='list'>
</ul>
JS:
window.onload=function() {
window.list=$('#list'), window.max=20, window.page=0, window.pages=0, window.elements;
var i=0;
while(i<5000) {
i++;
list.append("<li>"+i+"</li>");
}
jump('first');
};
function jump(operation) {
window.elements=list.find('li');
window.pages=Math.ceil(window.elements.length/window.max);
if(operation=='first') {
window.page=0;
}
else if(operation=='last') {
window.page=(window.pages-1);
}
else if(operation=='+1') {
window.page=(window.page+1);
if(window.page>=window.pages) {
window.page=(window.pages-1);
}
}
else if(operation=='-1') {
window.page=(window.page-1);
if(window.page<0) {
window.page=0;
}
}
var showing=0, total=0;
window.elements.each(function() {
var show=false, self=$(this);
if(showing<window.max) {
if(total>=(window.page*window.max) && total<((window.page*window.max)+window.max)) {
self[0].style.display='';
showing++;
show=true;
}
}
if(!show) {
self[0].style.display='none';
}
total++;
});
}
check this
window.onload = function() {
window.list = $('#list'),
window.max = 20,
window.page = 0,
window.pages = 0,
window.elements;
var i = 0;
var html = '';
while(i < 5000) {
i++
html += '<li>' + i + '</li>';
}
list.append(html);
window.elements = list.find('li');
window.pages = Math.ceil(window.elements.length/window.max);
jump('first');
};
function jump(operation) {
if (operation == 'first')
window.page = 0;
else if (operation == 'last')
window.page = window.pages - 1;
else if (operation == '+1')
(window.page + 1 >= window.pages) ? window.page = window.pages - 1 : window.page++ ;
else if (operation == '-1')
(window.page - 1 < 0) ? window.page = 0 : window.page--;
var index = page * window.max;
window.elements.hide().slice(index, index + window.max).show();
}
http://jsfiddle.net/Hwqb3/16/
I'm testing out a layout on a website using 3 pictures here:
Schechterbusiness.info
the left button works, making it go through the pictures. But I can't figure out how to get the right button to work, which is supposed to scroll through the other way. I know there's probably a way to do it with arrays but I can't wrap my brain around it. Halp!
Code to scroll through pictures:
$('#fryLink').click(function() {
$('#hide').hide();
$('#img').hide();
count++;
if(count == 1) {
$('#img').attr("src","images/fry.png");
}
else if(count == 2) {
$('#img').attr("src","images/bender.png");
}
else if(count == 3) {
$('#img').attr("src","images/zoidberg.png");
}
$('#img').show("fade");
if(count > 2) {
count = 0;
}
normally it should be enough to just use use the same function the other way around with
count--;
following the first answere
Bind event to right mouse click
reverse the counter ;)
You have count cycling through four states: 0, 1, 2, and 3. But you only set the image for states 1 - 3.
This leads to duplicating one image--whichever was the last one--when your count variable is on 0.
As to helping you get exactly what you want, unfortunately that is not really clear. Are the three buttons supposed to be a sort of "forward / something / reverse"? What do you want to happen when the center button is clicked on?
Also, making the buttons display the proper pointer/hand icon is important. Right now they show the text selection bar instead, and that makes it confusing since it conveys to the user that the items are not clickable.
Try this
var count = 0;
var imgLength = 3;
$('#leftLink , #rightLink').click(function() {
$('#hide').hide();
$('#img').hide();
if (this.id === 'leftLink') {
count--;
if (count < 0) {
count = imgLength-1;
}
}
else {
count++;
if (count > imgLength-1) {
count = 0;
}
}
var src = "images/fry.png";
if (count == 1) {
src = "images/bender.png";
}
else if (count == 2) {
src = "images/zoidberg.png";
}
$('#img').attr('src',src).show("fade");
});
I want to fill a lottery field with random numbers when the user shakes the phone.
My shake detection
function watchForShake(threshold)
{
console.log ("Am Watching for shakes");
axl.watchAcceleration(
function (Accel)
{
if (true === Accel.is_updating){
return;
}
var diffX = Accel.x - prevX;
if (diffX >= threshold)
{
console.log("Phone shaken");
if (gettingRandomNumbers==false){
randomNumbers();
}
}
prevX = Accel.x
}
, function(){}
, {frequency : 100}
);
}
this Method sets a number in the lottery field as selected.
function clickNumber(number)
{
console.log("ClickNumber invoked with number "+number);
tNumber = $(number).html();
tPosition = $(number).position();
if($(number).hasClass('selected'))
{
lottoNumbers.pop(number);
console.log("number.hasClass = true");
$(number).removeClass('selected');
$(number).children().remove();
}else{
if (lottoNumbers.length <= 5) {
lottoNumbers.push(number);
console.log("number.hasClass = false");
$(number).addClass('selected');
$(number).append('<img src="assets/images/spielschein_kreuz.png" style="position:absolute;top:'+ tPosition.top +'px;left:'+ tPosition.left +'px;"/>');
}
}
}
The next method gets random numbers and sets them in the lotteryfield (using jquery). I think this method is what causes the memory leak. The app doesnt crash when I take out the inner for-loop, but I dont know how to fix it.
function randomNumbers(){
console.log("Am Getting Random Numbers");
gettingRandomNumbers=true;
counter = 0;
clearAllNumbers();
while (counter < 6){
zufallsZahl = Math.floor((Math.random()*49)+1);
zufallsZahlen[counter]=zufallsZahl;
if (isUniqueNumber){
counter++;
console.log("Zufallszahl: "+zufallsZahl);
clickNumber($('#ticket_detail .tipfield .tipbox ul li').filter(function(){return $(this).html() == zufallsZahl;}));
}
}
gettingRandomNumbers = false;
}
I dont know what exactly causes the GC_CONCURRENT message. The app crashes and freezes without an explicit error message. After several shakes detected, the app crashes.
All variables are initialized in the document.ready() method in the index.html file. I dont create new objects on every shake, do I?
any help or hints greatly appreciated.
thank you,
Daniel