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");
});
Related
I am using Swiper (no jQuery, pure JavaScript) to display 11 slides. I want to change the body background-color depending on which slide the user is on.
This code works fine, but when the slider restarts it keeps the colour of the last slide instead of restarting from the first one:
swiper.on('transitionEnd', function(e) {
if (this.activeIndex == 1) {
document.querySelector("body").style.background = '#F4F1C1';
}
if (this.activeIndex == 2) {
document.querySelector("body").style.background = '#DCDDDE';
}
if (this.activeIndex == 3) {
document.querySelector("body").style.background = '#ECEBDF';
}
if (this.activeIndex == 4) {
document.querySelector("body").style.background = '#F2E3E3';
}
if (this.activeIndex == 5) {
document.querySelector("body").style.background = '#D0EFF0';
}
});
On this JSFiddle you can see that after slide 11, the slider goes back to slide 1 but the colour is still #999999 rather than #F4F1C1.
Why is the index not restarting?
Swiper shifts its array index by 1. As seen here in the documentation
So you're correctly starting from index 1 but not accounting for the 11th item at index 12
https://swiperjs.com/api/
You can use this.realIndex to get the correct index of the looped item according to the documentation.
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.
I'm automating e2e tests on an angular app. We have virtual scrolls on few input elements (only 10-20 items are loaded at a time, scrolling down loads more items and delete the previous ones to improve performance).
I made a method to scroll until I find the DOM element and click on it. However, I don't know how I can stop looping after I clicked the element.
Here is what I've done so far :
findQuery(queryName){
this.getSavedQueryCount().then((queryCount)=>{ // Total nb of items
this.count().then((displayCount)=>{ //nb of items this screen can display
let count = 0;
let flag = 0;
let actualCount = displayCount + 1;
do
{
if(count % (actualCount) === 0 && count !== 0) count++; //handling weird behavior, index 0 never gets deleted so we increment by 1 to get the next item.
browser.executeScript('arguments[0].scrollIntoView({behavior: "smooth", block: "end"});', this.getSavedQuery(count % actualCount)); // scroll to elem at index
this.getSavedQueryByName(queryName).isPresent().then((bool)=>{ // clicking on elem if it's in the DOM
if(bool)
{
this.getSavedQueryByName(queryName).getAttribute('class').then((cl)=>{
if(!(cl === "selected"))//making sure to click only once so we don't deselect the item
{
this.getSavedQueryByName(queryName).click();
flag = 1;
}
});
}
});
count += 1;
} while(queryCount > count || flag);
});
});
}
Please don't judge the code I will refactor it after I get the answer to this question (don't take the weird index handling into account).
So far this method works but it never stops looping until queryCount > count. I want it to stop looping after I clicked the element too (with the flag var).
Thanks in advance.
$(document).ready(function fadeIt() {
$("#cool_content > div").hide();
var sizeLoop = $("#cool_content > div").length;
var startLoop = 0;
$("#cool_content > div").first().eq(startLoop).fadeIn(500);
setInterval(function () {
$("#cool_content > div").eq(startLoop).fadeOut(1000);
if (startLoop == sizeLoop) {
startLoop = 0
} else {
startLoop++;
}
$("#cool_content > div").eq(startLoop).fadeIn(1500);
}, 2000);
});
Here I want a class of divs to animate, infinitely!
However, because the interval is set to two seconds there is period where no div is showing!
What would be an appropriate way to loop the animation of these divs?
I thought about using a for loop but couldn't figure out how to pass a class of divs as arguments. All your help is appreciated.
Thanks!
Ok, generally, you should know that Javascript is a single threaded environment. Along with this, the timer events are generally not on time accurately. I'm not sure how jQuery is doing fadeIn and fadeOut, but if it's not using CSS3 transitions, it's going to be using timeOut and Intervals. So basically, there's a lot of timer's going on.
If you go with the for loop on this one, you'd be blocking the single thread, so that's not the way to go forward. You'd have to do the fade in/out by yourself in the setInterval.
Setting the opacity on each interval call. Like div.css('opacity', (opacity -= 10) + '%')
If you're trying to fade in and out sequentially, I think maybe this code would help
var opacity = 100,
isFadingIn = false;
window.setInterval(function() {
if (isFadingIn) {
opacity += 10;
if (opacity === 100) isFadingIn = false;
} else {
opacity -= 10;
if (opacity === 0) isFadingIn = true;
}
$('#coolContent > div').css('opacity', opacity + '%');
}, 2000);
Consider the following JavaScript / jQuery:
$(function(){
var divs = $('#cool_content > div').hide();
var curDiv;
var counter = 0;
var doUpdate = function(){
// Hide any old div
if (curDiv)
curDiv.fadeOut(1000);
// Show the new div
curDiv = divs.eq(counter);
curDiv.fadeIn(1000);
// Increment the counter
counter = ++counter % divs.length;
};
doUpdate();
setInterval(doUpdate, 2000);
});
This loops infinitely through the divs. It's also more efficient than your code because it only queries the DOM for the list of divs once.
Update: Forked fiddle
instead of
if (startLoop == sizeLoop)
{
startLoop = 0
}
else
{
startLoop++;
}
use
startLoop =(startLoop+1)%sizeLoop;
Check the demo http://jsfiddle.net/JvdU9/ - 1st div is being animated just immediately after 4th disappears.
UPD:
Not sure I've undestood your question, but I'll try to answer :)
It doesn't matter how many divs you are being looped - 4, 5 or 10, since number of frames are being calculated automatically
x=(x+1)%n means that x will never be greater than n-1: x>=0 and x<n.
x=(x+1)%n is just shorten equivalent for
if(x<n-1)
x++;
else
x=0;
as for me first variant is much readable:)
And sorry, I gave you last time wrong demo. Correct one - http://jsfiddle.net/JvdU9/2/
Basically I have a html page with hundreds of images on it each with a title attribute describing the image. Ideally I would change all this but the page has to stay as it is for now.
I want to search these title attributes and scroll the page to the corresponding image if possible. - I've played around with some javascript search scripts but cannot get it to work with straightforward "On page" searches as the tags are in the code rather than displayed on page.
Can anyone point me in the right direction on how to do something like this?
This was the "Search on page" code I was using
var n = 0;
function findInPage(str) {
var txt, i, found;
if (str == "") {
return false;
}
// Find next occurance of the given string on the page, wrap around to the
// start of the page if necessary.
if (window.find) {
// Look for match starting at the current point. If not found, rewind
// back to the first match.
if (!window.find(str)) {
while (window.find(str, false, true)) {
n++;
}
} else {
n++;
}
// If not found in either direction, give message.
if (n == 0) {
alert("Not found.");
}
} else if (window.document.body.createTextRange) {
txt = window.document.body.createTextRange();
// Find the nth match from the top of the page.
found = true;
i = 0;
while (found === true && i <= n) {
found = txt.findText(str);
if (found) {
txt.moveStart("character", 1);
txt.moveEnd("textedit");
}
i += 1;
}
// If found, mark it and scroll it into view.
if (found) {
txt.moveStart("character", -1);
txt.findText(str);
txt.select();
txt.scrollIntoView();
n++;
} else {
// Otherwise, start over at the top of the page and find first match.
if (n > 0) {
n = 0;
findInPage(str);
}
// Not found anywhere, give message. else
alert("Not found.");
}
}
return false;
}
You can select by html attribute.
Using plain JS (in modern browsers incl. IE8+):
document.querySelectorAll('[title*="my text"]')
Using jQuery:
$('[title*=my text]')
would find:
<img src="/path" title="this is a title with my text" />
From there, you would need to get the page position of the image returned by the selector, and then scroll your page to that point, optionally (likely) with some offset so it doesn't bang up against the top of the viewport
EDIT:
function findElementsByTitle(str) {
return document.querySelectorAll('[title*="' + str + '"]');
}
function scrollToElement(el) {
var yOffset = el.offset().top; //this is a jQuery method...you don't want to write this in plain JS
window.scrollTo(0, yOffset - 10) //params are x,y. the - 10 is just so your image has some "padding" in the viewport
}