Trying to get my imageslider to work - javascript

I have an image slider that shows all the images I have in my view in MVC5 however when I reach the last one I dont know how to make it jump back to the first one and continue from there.
The Html for the thing looks like this:
<div class="container2">
<div class="slider_wrapper">
<ul id="image_slider">
<li> <img src="#Model.ImagePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"],"../../")" width=50 height=50 /> </li>
#foreach (var item in Model.ImageGallarys)
{
<li> <img src="#item.ImagePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"],"../../")" width=50 height=50 /></li>
}
</ul>
<span class="nvgt" id="prev"></span>
<span class="nvgt" id="next"></span>
</div>
</div>
And the javascript looks like this:
function startFunction() {
$(window).load(function () {
var src = $("#image_slider").find('li:first-child img').attr('src');
$("#image_slider li:first-child ").addClass("start");
var src1 = src.replace("../..", " ");
var src2 = src1.replace('\\', "/");
$(".container2").css("background-image", 'url("' + src2 + '")');
//fadeInandOut();
});
}
function nextImageFunction() {
$("#next").click(function () {
$("li.start").next("li").addClass("start");
$("li.start").prev("li").removeClass();
var srcNext = $("li.start img").attr('src');
var srcNext1 = srcNext.replace("../..", " ");
var srcNext2 = srcNext1.replace('\\', "/");
$(".container2").css("background-image", 'url("' + srcNext2 + '")');
if($("li.start").is(":last-child"))
{
//I want the solution for this one!
}
});
}
function previousImageFunction() {
$("#prev").click(function () {
$("li.start").prev("li").addClass("start");
$("li.start").next("li").removeClass();
var srcNext = $("li.start img").attr('src');
var srcNext1 = srcNext.replace("../..", " ");
var srcNext2 = srcNext1.replace('\\', "/");
$(".container2").css("background-image", 'url("' + srcNext2 + '")');
});
if ($("li.start").is(":first-child")) {
//And also for this one!
}
}
Help me Obiwan Kenobi your my only hope!

Just do it :)
<div class="container2">
<div class="slider_wrapper">
<ul id="image_slider">
<li> <img src="#Model.ImagePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"],"../../")" width=50 height=50 /> </li>
#foreach (var item in Model.ImageGallarys) {
<li> <img src="#item.ImagePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"],"../../")" width=50 height=50 /></li>
}
</ul>
<span class="nvgt" id="prev"></span>
<span class="nvgt" id="next"></span>
</div>
</div>
And in our JS (with a little refoctoring) we will have:
// we need this support principle don't repeat yourself (DRY)
function avoidSrcSymbols(src){
return src.replace("../..", " ").src1.replace('\\', "/");
}
// This function need to improve set image via class in future//
function changeImage($src, imageSrc){
$src.css("background-image", 'url("' + imageSrc + '")');
}
function startFunction() {
$(window).load(function () {
var $firstLi = $("#image_slider").find('li:first-child');
$firstLi.addClass("start");
var src = $firstLi.find('img').attr('src');
src = avoidSrcSymbols(src);
changeImage($(".container2"), src);
//fadeInandOut();
});
}
function nextLi($currentLi){
if ($currentLi.is(":last-child")) {
// here is many method to get firstChild from current
return $currentLi.parent().first();
}
return $currentLi.next("li");
}
function prevLi($currentLi){
if ($currentLi.is(":first-child")) {
// here is many method to get lastChild from current
return $currentLi.parent().last();
}
return $currentLi.prev("li");
}
function nextImageFunction() {
$("#next").click(function () {
var $currentLy = $("li.start");
nextLi($currentLy).addClass("start");
$currentLy.removeClass("start");
var src = $currentLy.find("img").attr('src');
src = avoidSrcSymbols(src);
changeImage($(".container2"), src);
});
}
function previousImageFunction() {
$("#prev").click(function () {
var $currentLy = $("li.start");
prevLi($currentLy).addClass("start");
$currentLy.removeClass("start"); // remove Class from currect li
var src = $currentLy.find("img").attr('src');
src = avoidSrcSymbols(src);
changeImage($(".container2"), src);
});
}

Related

How can I reduce the repetitive work of this jquery source?

$("#sel1").click(function () {
$("#itemed1").attr("src", "../img/tab_img_01_on.png");
$("#itemed2").attr("src", "../img/tab_img_02.png");
$("#itemed3").attr("src", "../img/tab_img_03.png");
$("#itemed4").attr("src", "../img/tab_img_04.png");
$(this).find("span").addClass("add");
$("#sel2").find("span").removeClass("add");
$("#sel3").find("span").removeClass("add");
$("#sel4").find("span").removeClass("add");
});
$("#sel2").click(function () {
$("#itemed2").attr("src", "../img/tab_img_02_on.png");
$("#itemed1").attr("src", "../img/tab_img_01.png");
$("#itemed3").attr("src", "../img/tab_img_03.png");
$("#itemed4").attr("src", "../img/tab_img_04.png");
$(this).find("span").addClass("add");
$("#sel1").find("span").removeClass("add");
$("#sel3").find("span").removeClass("add");
$("#sel4").find("span").removeClass("add");
});
$("#sel3").click(function () {
$("#itemed3").attr("src", "../img/tab_img_03_on.png");
$("#itemed1").attr("src", "../img/tab_img_01.png");
$("#itemed2").attr("src", "../img/tab_img_02.png");
$("#itemed4").attr("src", "../img/tab_img_04.png");
$(this).find("span").addClass("add");
$("#sel1").find("span").removeClass("add");
$("#sel2").find("span").removeClass("add");
$("#sel4").find("span").removeClass("add");
});
$("#sel4").click(function () {
$("#itemed4").attr("src", "../img/tab_img_04_on.png");
$("#itemed1").attr("src", "../img/tab_img_01.png");
$("#itemed2").attr("src", "../img/tab_img_02.png");
$("#itemed3").attr("src", "../img/tab_img_03.png");
$(this).find("span").addClass("add");
$("#sel1").find("span").removeClass("add");
$("#sel2").find("span").removeClass("add");
$("#sel3").find("span").removeClass("add");
});
Hello This JQuery code is a source that changes the image when you click on the element.
It works fine, but I have a lot of iterations,
so I want to reduce my code. What should I use?
You could use a simple combination of selectors.
See sample here or in CodePen:
$(".selector").click(function () {
let index = $(this).data('index');
$(".selector").find("span").removeClass("add");
$(this).find("span").addClass("add");
$(".imgs").each( function(){
$(this).attr("src", `../img/tab_img_0${$(this).data('index')}.png`);
});
$(`.imgs[data-index="${index}"]`).attr("src", `../img/tab_img_0${index}_on.png`);
});
.add {
font-size: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="selector" data-index="1">Sel 1 <span>sample</span></button>
<button class="selector" data-index="2">Sel 2 <span>sample</span></button>
<button class="selector" data-index="3">Sel 3 <span>sample</span></button>
<button class="selector" data-index="4">Sel 4 <span>sample</span></button>
<img data-index="1" class="imgs" />
<img data-index="2" class="imgs" />
<img data-index="3" class="imgs" />
<img data-index="4" class="imgs" />
Obviously, if you are using n index > 10 you should use the padStart function.
Expendable version of same code.
function pad(v) {
return (v.length === 2 ? v : '0' + v);
}
$('[id^=sel]').click(function() {
var total = 4;
var idNumber = $(this).attr('id').match(/\d+/);
for ( i = 1; i <= total; i++ ) {
$('#itemed' + i).attr('src', '../img/tab_img_' + pad(i) + '.png');
$('#sel' + i).find('span').removeClass('add');
}
$('#itemed' + idNumber).attr('src', '../img/tab_img_' + pad(idNumber) + '_on.png');
$(this).find('span').addClass('add');
});
But I think #SnakeDrak approach is correct
This will work up to selects with the number 9. It will need a little more work to make it work with numbers grater then 9
$("[id^=sel]").click(function () { // match every element where the id starts with "sel"
var idNumber = $(this).attr('id').match(/\d+/); // get the number of given id
// reset all src paths from all given elements
$("#itemed1, #itemed2, #itemed3, #itemed4").attr("src", "../img/tab_img_01.png");
// use the idNumber to concatenate the selector and set the src
$("#itemed" + idNumber).attr("src", "../img/tab_img_0"+idNumber+"_on.png");
// remove the add class to all given elements
$("#sel1, #sel2, #sel3, #sel4").find("span").removeClass("add");
// add the "add" class to $(this) element
$(this).find("span").addClass("add");
});
Please refer below code.
$("[id^=sel]").on('click', function() {
var selectionID = ["sel1", "sel2", "sel3", "sel4"];
var itemID = ["itemed1", "itemed2", "itemed3", "itemed4"];
var selectedButton = $(this).attr("value");
$(this).find("span").addClass("add");
var indexID = selectionID.indexOf(selectedButton) + 1;
$("#itemed" + indexID).attr("src", "../img/tab_img_0" + indexID + "_on.png");
selectionID = selectionID.filter(e => e !== selectedButton);
itemID = itemID.filter(e => e !== itemID[indexID - 1]);
for (var i = 0; i < selectionID.length; i++) {
$("#" + selectionID[i]).find("span").removeClass("add");
$("#" + itemID[i]).attr("src", "../img/tab_img_0" + itemID[i].charAt(itemID[i].length - 1) + ".png");
}
});
.add {
background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button value="sel1" id="sel1"><span>sel1</span></button><br/>
<button value="sel2" id="sel2"><span>sel2</span></button><br/>
<button value="sel3" id="sel3"><span>sel3</span></button><br/>
<button value="sel4" id="sel4"><span>sel4</span></button><br/>
<img src="" id="itemed1">
<img src="" id="itemed2">
<img src="" id="itemed3">
<img src="" id="itemed4">

Flickity won't initialising when switching Tab

I installed flickity in multiple vanilla js tabs and it is correctly initialized in the first tab. while the content of the first tab is loaded, the content of the second isn't correct initialized.
<div class="outer-wrap">
<ul class="simple-tabs" id="demo-tabs">
<li class="tab-1 active">tab-1</li>
<li class="tab-2">tab-2</li>
<li class="tab-3">tab-3</li>
</ul>
<div class="clear-float"></div>
<div id="tab-1" class="tab-page active-page"><div class="carousel" data-flickity><div class="carousel-cell"></div><div class="carousel-cell"></div><div class="carousel-cell"></div></div></div>
<div id="tab-2" class="tab-page">
<div class="carousel" data-flickity><div class="carousel-cell"></div><div class="carousel-cell"></div><div class="carousel-cell"></div></div></div>
<div id="tab-3" class="tab-page">
<div class="carousel" data-flickity><div class="carousel-cell"></div><div class="carousel-cell"></div><div class="carousel-cell"></div></div></div></div>
JS
<script src="https://cdnjs.cloudflare.com/ajax/libs/flickity/2.2.1/flickity.pkgd.min.js"></script><script>var SimpleTabs = function (elem) {
var activeTabObject;
var TabObject = function () {
var self = this;
this.tab; //element
this.pane; //element
this.setClick = function () {
self.tab.addEventListener('click', self.showThisTab)
};
this.showThisTab = function () {
if (self !== activeTabObject) {
//change the tab page and update the active tab
activeTabObject.pane.className = activeTabObject.pane.className.replace('active-page', '');
activeTabObject.tab.className = activeTabObject.tab.className.replace('active', '');
self.pane.className = self.pane.className + ' active-page';
self.tab.className = self.tab.className + ' active';
activeTabObject = self;
}
};
};
var ul = elem;
var i;
var items = ul.getElementsByTagName("li");
for (i = 0; i < items.length; ++i) {
var tab = new TabObject();
tab.tab = items[i];
var classString = items[i].className;
var className = classString.split(' ')[0];
tab.pane = document.getElementById(className);
tab.setClick();
if (classString.indexOf('active') > -1) {
activeTabObject = tab;
}
}
};</script><script>
window.onload = function() {
var demoTabs = new SimpleTabs(document.getElementById('demo-tabs'));
};
</script>
content of the second isn't correct initialized.
codepen : https://codepen.io/himalayanath/pen/xvgyoO
Thank You!
According to the Flickity document,
you should call resize() after switch tabs.

Show dynamically created divs one by one

I am trying to show dynamically created li's one by one. Here is my code. Any idea why something like this would not work?
$('form').submit(function(e) {
e.preventDefault();
var userInput = $('#inputNumber').val();
console.log(outputResult);
var modifiedResult = outputResult.map(function(item) {
return '<li class="ball">' + item + '</li>'
});
$('.output').html(modifiedResult.join(""));
$('.ball').each(function(i, e) {
$(this).delay(i * 400).fadeIn();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="output"></ul>
When you do $('.output').html(modifiedResult.join("")); the lis are already visible (display property is block by default).
It would suffice to add style="display:none" in the html strings you create with #map() function - see a demo below:
var userInput = $('#inputNumber').val();
var outputResult = [1,2,3,4,5];
var modifiedResult = outputResult.map(function(item) {
return '<li style="display:none" class="ball">' + item + '</li>'
});
$('.output').html(modifiedResult.join(""));
$('.ball').each(function(i, e) {
$(this).delay(i * 400).fadeIn();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="output"></ul>
If you want to fadeIn after created user display:none initially.
$('#submit').click(function(e) {
e.preventDefault();
var userInput = 5;
var outputResult = [1, 2, 3, 4, 5];
console.log(outputResult);
var modifiedResult = outputResult.map(function(item) {
return '<li style="display:none" class="ball">' + item + '</li>'
});
$('.output').html(modifiedResult.join(""));
$('.ball').each(function(i, e) {
debugger;
$(this).delay(i * 400).fadeIn();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="output"></ul>
<input id="submit" type="button" value="submit" />

setTimeout callback function not working

I am calling a function using onClick inside button. The called function is inside an object and it is getting called each second using setTimeout. But callback function is not getting called by setTimeout and works for just first call.
if i do not use object and use a encapsulating function that returns startPomadoro function, then its working.
###HTML Code ##########
<div class="cold-md-12 text-center">
<button>Set Pomodoro</button>
<input id="pomodoroInput" type="number">
<button>Set Break</button>
<input id="breakInput" type="number">
</div>
<div class="cold-md-12 text-center"><br>
<button onClick="pomodoroClock.startPomodoro()">Start Pomodoro</button>
</div>
<div id="output">
</div>
### JS COde
var pomodoroClock = {
countPomadoro: 0,
countBreak: 0,
currentTimerText:'',
startPomodoro: function(){
var pomadoroTimeInMinutes = document.getElementById('pomodoroInput').value;
var breakInMinutes = document.getElementById('breakInput').value;
if(this.countPomadoro<pomadoroTimeInMinutes){
var minutesLeftPomadoro = pomadoroTimeInMinutes - this.countPomadoro;
this.currentTimerText = "Your have " + minutesLeftPomadoro + " Minutes Left.";
this.countPomadoro++;
this.displayPomadoro();
setTimeout(this.startPomodoro, 1000);
}
else {
if(this.countBreak<breakInMnutes){
var minutesLeftBreak = this.breakInMinutes - this.countBreak;
currentTimerText = "Your have " + minutesLeftBreak + " Minutes Left in Break.";
this.countBreak++;
this.displayPomadoro();
setTimeout(this.startPomodoro, 1000);
}
else {
this.currentTimerText=" Break Time is UP. ";
this.displayPomadoro();
}
}
},
displayPomadoro: function(){
var pomodoroHtmlElement = document.createElement('p');
var outputDiv = document.getElementById('output');
pomodoroHtmlElement.textContent=this.currentTimerText;
outputDiv.appendChild(pomodoroHtmlElement);
}
}
You had a problem with this not being what you think, when function was called from setTimeout. Try something like this:
var pomodoroClock = {
countPomadoro: 0,
countBreak: 0,
currentTimerText: '',
startPomodoro: function() {
var that = this;
var pomadoroTimeInMinutes = document.getElementById('pomodoroInput').value;
var breakInMinutes = document.getElementById('breakInput').value;
if (this.countPomadoro < pomadoroTimeInMinutes) {
var minutesLeftPomadoro = pomadoroTimeInMinutes - this.countPomadoro;
that.currentTimerText = "Your have " + minutesLeftPomadoro + " Minutes Left.";
that.countPomadoro++;
that.displayPomadoro();
setTimeout(function() { that.startPomodoro() }, 1000);
} else {
if (that.countBreak < breakInMinutes) {
var minutesLeftBreak = that.breakInMinutes - that.countBreak;
currentTimerText = "Your have " + minutesLeftBreak + " Minutes Left in Break.";
that.countBreak++;
that.displayPomadoro();
setTimeout(function() { that.startPomodoro() }, 1000);
} else {
that.currentTimerText = " Break Time is UP. ";
that.displayPomadoro();
}
}
},
displayPomadoro: function() {
var pomodoroHtmlElement = document.createElement('p');
var outputDiv = document.getElementById('output');
pomodoroHtmlElement.textContent = this.currentTimerText;
outputDiv.appendChild(pomodoroHtmlElement);
}
}
<div class="cold-md-12 text-center">
<button>Set Pomodoro</button>
<input id="pomodoroInput" type="number">
<button>Set Break</button>
<input id="breakInput" type="number">
</div>
<div class="cold-md-12 text-center"><br>
<button onClick="pomodoroClock.startPomodoro()">Start Pomodoro</button>
</div>
<div id="output">
</div>
PS. You also had a typo breakInMnutes instead of breakInMinutes.
I have solved this problem by moving away from jquery , and simply
setting event handler on divs by wrapping each image inside one div using
JavaScript. Below is the sample code.
//code
handler.divs.forEach(function(div){
var img = document.getElementById(div);
img.onclick = function(){
var id = parseInt(img.id,10);
userPattern.push(id);
handler.effect(id);
console.log(" div clicked " + id + " u p " + userPattern);
if(userPattern.indexOf(id) !== simonGame.PATTERN.indexOf(id)){
console.log(" if ");
handleWrongInput();
} else if(userPattern.length === simonGame.PATTERN.length){
setTimeout(function(){simonGame.patternGen({result:"success"})},1200);
}
}
});
console.log(" up " + userPattern + " SGP " + simonGame.PATTERN);

Link in div repeats the function on roll over

So I have a side menu made of divs containing some text and a link.
When I roll over the div I fade in an image.
When I roll over the a tag link in that div it repeats that same function and creates another fade in of the same image witch looks real buggy.
How can I prevent the link a tag to repeat the function
I tried to create a variable set to true on roll over the link and a if inside the fade in method but with no success?
Any ideas would be appreciated.
$j=jQuery.noConflict();
jQuery(document).ready(function($) {
var num = 0;
var numtot = 4;
var delai = null;
var stop_x=0;
var numCur=0;
var thisIs = 0;
var delayRoll = 0;
var count = null;
var overlink = false;
//on ini
//--//
$j(document).ready(function() {
function start() {
delai=setInterval(test, 5000);
console.log(">> start interval");//>>>>>>>>>>>>>>>>>>>trace;
};
numtot = ($j("#news dl dt").size())-1;
test();
start();
})
function fistImage(){
//if(delayRoll==0){
$j("#news dl dd").fadeOut();
$j("#news dl dt").removeClass('current');
console.log("num on test: " + num);//>>>>>>>>>>>>>>>>>>>trace;
console.log("numCur on test: " + numCur);//>>>>>>>>>>>>>>>>>>>trace;
//console.log("current is"+ );//>>>>>>>>>>>>>>>>>>>trace;
$j("#news dl dt").eq(num).addClass('current');
$j("#news dl dt").eq(num).next('dd').fadeIn(500);
if (num>=numtot) {num = 0;} else {num ++;};
//}
}
//firstImage();
//--//
////////--------//////// NEXT IMAGE METHOD
function nextImage(){
if( overlink == false || overlink == true){
console.log("delayRoll image: " + delayRoll);//>>>>>>>>>>>>>>>>>>>trace;
$j("#news dl dd").fadeOut();
$j("#news dl dt").removeClass('current');
$j(thisIs).addClass('current');
$j(thisIs).next('dd').fadeIn(500);
//stop_x=1;
var new_pos=$j(thisIs).attr('id').substring(4, 5);
new_pos=parseInt(new_pos);
if (numtot==new_pos) {new_pos = 0;}
num = new_pos;
numtot = ($j("#news dl dt").size())-1;
}
}
//--//
function test() {
//console.log("num on test: " + num);//>>>>>>>>>>>>>>>>>>>trace;
if(stop_x==0){
fistImage();
}
if(stop_x==1){
}};
//--//
//--/
delai=setInterval(test, 5000);
//--//
//-- OVERLAY//
$j(".overlay").mouseover(function() {
stop_x=1;
}).mouseout( function (){
stop_x=0;
});
//--//mouseover
$j("#news dl dt").mouseover(function() {
thisIs = $j(this);
stop_x=1;
clearInterval(delai);
nextImage();
delayRoll==2;
})
$j("#news dl dt").mouseout(function() {
stop_x==0;
firstImage();
delayRoll=0;
})
$("#news dl dt a").live("mouseover mouseout", function() {
// alert(this.href);
//return false;
overlink=true;
});
})//close duc ready
//--//
and here the html
<div id="news" class="slideshow">
<dl>
<dt id="pos_1">08/16/11<br /><br />Holy Cross to Welcome Class of 2015 on Aug. 27<br />
<a class="more" href="blog/2011/08/16/holy-cross-to-welcome-class-of-2015-on-aug-27/index.html">See more ></a>
</dt>
<dd>
<div class="overlay">
<p>Holy Cross to Welcome Class of 2015 on Aug. 27 <span class="nav">
<img src="wp-content/themes/marsten/images/ico_more_white.png" width="14" height="14" alt="" />
<div id="disLink"><span><a class="more" href="blog/2011/08/16/holy-cross-to-welcome-class-of-2015-on-aug-27/index.html" >See more ></a></span></div>
</span>
</p>
<div id="boxit"><p class="author">by
Nikolas Markantonatos</p></div>
</div>
<img alt="" src="wp-content/uploads/2011/08/gate2.jpg" width="612" height="451" />
</dd>
Trying doing a event.stopPropagation during the hover over after you fade in...

Categories