Switching style between two elements on photo gallery change - javascript

So I have a photo gallery on my front page that switches between two images; each image links to a different page. Now, beside that gallery I have two links that go to the same two pages. The idea is that when image A is showing, side-link A should be highlighted with a border. The issue I keep running into is that once I get either side-link to be highlighted, I don't really know how to get it unhighlighted. Instead of switching with the images, they just stay highlighted.
var debugLink = "#firstLink";
function displayNextImage()
{
index++;
if(index >= indexgalpics.length)
{
index=0;
}
//---this is where I set the var debugLink which is
// supposed to carry the selected linke
if(index == 0)
{
console.log("first link selected");
//---when image A is showing, top side-link should be highlighted
//---ok so we know this much works, it seems these double equal
// signs are very important here.
//---makeActive();
//---but once makeActive() is called here, it makes the first link
// active for the entire time.
//---we can't put the entire style code here because same as before,
// it just keeps the link highlighted forever
debugLink = "#firstLink";
//---ok so i can set a var at top to a value in the makeActive() function,
// but i think the way JS works highlights either one forever
debugLink = "#firstLink";
}
else if(index == 1)
{
console.log("second link should be selected");
//---when image B is showing, bottom side-link should be highlighted
debugLink = "#secondLink";
}
showImg();
}
function makeActive()
{
var activeLink = document.querySelector(debugLink);
//---adds style to the debugLink
}
The function makeActive() is called in the function showImg(), and the function displayNextImage() is called in another function that sets the timer.

I changed your approach a little bit by using a boolean for the index, because you seem to only need two states.
Here is a revised version:
Note: In this code, I've used custom-made functions to make the code easier to read. I created hasClass(el,class), addClass(el,class), removeClass(el,class), toggleClass(el,class,bool). You can find them in the final JS Fiddle.
// Register the link elements
var links = {
true : document.getElementById('firstLink'),
false : document.getElementById('secondLink')
},
// Keep track of selected link (replaces your 'index')
leftLinkActive = false,
// Just so you don't go get it every time
gallery = document.getElementById('gallery');
// Let's trigger the gallery
displayNextImage();
// We'll change the active link and show the correct image
function displayNextImage(){
leftLinkActive = !leftLinkActive;
if(leftLinkActive){ console.log("first link selected"); }
else{ console.log("second link selected"); }
makeActive();
showImg();
// Let's do that again in 2 seconds
setTimeout(displayNextImage,2000);
}
// Add / remove the active class
function makeActive(){
addClass( links[ leftLinkActive ], 'active-class');
removeClass( links[ !leftLinkActive ], 'active-class');
}
// Change the image with a small fadeOut transition
function showImg(){
addClass(gallery,'fadeOut');
setTimeout(function(){
// Here we switch from img1 and img2
gallery.style.backgroundImage = 'url('+(leftLinkActive?'im1.jpg':'im2.jpg')+')';
removeClass(gallery,'fadeOut');
},200);
}
JS Fiddle Demo

Related

Show and Hide 1 row of elements with JavaScript and Bootstrap

I am making a new website. As is what I'm doing is a gallery of videos by clicking shows me a video in modal, in total only shows me 1 large video with text and small 3 videos below where you can display more items. I need you to click show me more out a new row with 3 computer elements by al-md-4 columns. This step I have done but I have 2 problems:
Default with Javascript shows me 2 rows instead of just one, will define in the JS 1 and showing me appear 2
I also wish there was another button to "hide" and was hiding whenever I click a row.
Then I attached the complete code to where I could do.
http://www.bootply.com/vLeA1VQoYF
Need help!!
Thank you so much! Greetings from Spain
Here is my fiddle
And JS:
$('.mydata:gt(0)').hide().last().after(
$('<a />').attr('href','#').attr('id','btn_less').text('Show less').click(function(){
var a = this;
$('.mydata:visible:gt(0)').last().fadeOut(function(){
if ($('.mydata:visible:gt(0)').length == 0) {
$(a).hide();
} else if($("#btn_more:not(:visible)")){
$("#btn_more").show();
}
});
return false;
})
).after($('<span />').text(' ')
).after(
$('<a />').attr('href','#').attr('id','btn_more').text('Show more').click(function(){
var a = this;
$('.mydata:not(:visible):lt(1)').fadeIn(function(){
if ($('.mydata:not(:visible)').length == 0) {
$(a).hide();
} else if($("#btn_less:not(:visible)")){
$("#btn_less").show();
}
}); return false;
}));
Tell me if I misunderstood you and you need something else.

Applying .click event only to links in a certain div-container

The code already creates a navigation based on a JSON-file. The url are accessible by writing data.chapter[].subchapter[].url, the according title through data.chapter[].subchapter[].title
In case you are interested in that part or want the complete code, I uploaded it there: http://fabitosh.bplaced.net/SkriptET_iFrame_v2/
The goal now is to create a right sidebar which shows the links to the next and previous files in the structure. My approach is below.
What confuses me, is that back() is called until subchap is zero, when a link in #left is being clicked on. It should only be called when the previous-link is being clicked on. What do I have to change in order to achieve that?
Thanks a lot already!
var chap; //position in the array of the currently open chapter
var subchap; //position in the array of the currently open subchapter
function update_right() {
var path = data.chapter[chap].subchapter;
//Previous Page
if(subchap > 0) {
$("#prev").html("<b>Previous:</b><a href='"+path[subchap-1].url+"'>"+path[subchap-1].title+"</a><br/>");
$("#prev > a").click(back());
} else { //subchap == 0
$("#prev").html("");
};
}
function back() {
subchap--;
update_right();
}
$(document).ready(function() // DOM needs to exist in order to be able to add stuff in there
{
...Navigation being built up...
//------ onClick Navigation
$('#left > ul > li > a').click(
function(e)
{
chap = $(this).attr("data-chap");
subchap = $(this).attr("data-subchap");
update_right();
}
);
});

jQuery Accordion | Open first element on pageload & active state confusion

I am using the Javascript below to animate an accordion (it's a slightly modified variant of the one explained here: http://tympanus.net/codrops/2010/04/26/elegant-accordion-with-jquery-and-css3/.
Now I wanted to have the first element to be open on pageload, so I figured I just give it some sort of extra-class via Javascript (and define that .active state via CSS) to have it open up.
This worked, however if I hover over any but the first-element with said .active class, the first element keeps its state, and stays open until I hover over it at least once.
So, what I want is: the first element of my accordion is open and collapses if the user hovers over any of the elements that are not the first. I think I need to add a line in the hover function to either take the class away of the first element or to give the new element the active state, but I don't know how to do it and keep breaking the thing.
<script type="text/javascript">
jQuery(function() {
activeItem = jQuery("#accordion li:first");
jQuery(activeItem).addClass('active');
jQuery('#accordion > li, #accordion > li.heading').hover(
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
},
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
}
);
});
</script>
Looks like this is happening because each accordion item has its own hover event that takes care of its own animation. You can refactor the code slightly to make this easier to understand and reuse:
var activeItem = jQuery("#accordion li:first");
jQuery('#accordion > li, #accordion > li.heading').hover(
function () { hoverMe(jQuery(this)); },
function () { unhoverMe(jQuery(this)); }
);
//This gets called when cursor hovers over any accordion item
var hoverMe = function(jQuerythis) {
//If the first item is still active
if (activeItem) {
contract(activeItem); //...Shrink it!
activeItem = false;
}
//Expand the accordion item
expand(jQuerythis);
};
//This gets called when cursor moves out of accordion item
var unhoverMe = function(jQuerythis) {
contract(jQuerythis);
};
//I have moved the hover animation out into a separate function, so we can call it on page load
var expand = function(jQuerythis) {
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
};
//I have moved the unhover animation out into a separate function, so we can contract the first active item from hoverMe()
var contract = function() {
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
};
//Now expand the first item
expand(activeItem);
I have put together a simplified version demonstrating the logic. Please let me know how you get on.

jQuery conditionally change events depending on .html( 'string' ) values

http://jsfiddle.net/motocomdigital/Qh8fL/4/
Please feel free to change the heading if you think I've worded it wrong.
General
I'm running a wordpress site with multilingual control. And my menu/navigation is dynamic, controlled via the wordpress admin. The multilingual language plugin also changes the dynamic menu/navigation content, as well as page content.
My Contact button, which is in the dynamic navigation, opens a sliding menu using jQuery. Very simple animation using top css. The contact button is on the page twice, hence why I'm not using the .toggle for iterations. See jsFiddle.
Script
var $button = $(".contact-button"),
// var for button which controls sliding div
$slide = $("#content-slide");
// var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close') {
// run this if button says 'Close'
$slide.stop().animate({ top: "-269px" }, 300);
// close slide animation
$button.html('Contact');
// change text back to 'Contact'
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// open slide animation
$button.html('Close');
// change text to 'Close'
}
});
Problem
Because I'm running multilingual on the site. The navigation spelling changes. See jsFiddle flag buttons for example. This is fine, the animation still runs OK, because it's using the button class 'contact-button'.
But because I'm using the .html to replace the text of the button to "Close" and then on the second iteration, back to "Contact" - obviously this is a problem for other languages, as it always changes to English 'close' and back to English 'Contact'
But my three languages and words that I need the iterations to run through are...
Contact - Close
Contatto - Cerca
Contacto - Chiudere
Can anyone help me expand my script to accommodate three languages, all my attempts have failed. The jsFiddle has the script.
The language functionality in the fiddle is only for demo purposes, so the iteration sequence can be tested from the beginning. I understand if you change the language whilst the menu is open (in the fiddle), it will confused it. But when the language is changed on my site, the whole page refreshes, which closes the slide and resets the sequence. So it does not matter.
Any pro help would be awesome thanks!!!
MY POOR ATTEMPT, BUT YOU CAN SEE WHAT I'M TRYING TO ACHIEVE
var $button = $(".contact-button"),
// Var for button which controls sliding div
$slide = $("#content-slide");
// Var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close' || 'Cerca'|| 'Chiudere' ) {
// run this if button says Close or Cerca or Chiudere
$slide.stop().animate({ top: "-269px" }, 300);
// Close slide animation
$(function () {
if ($button.html(== 'Close') {
$button.html('Contact'); }
else if ($button.html(== 'Cerca') {
$button.html('Contatto'); }
else ($button.html(== 'Chiudere') {
$button.html('Contacto'); }
});
// Change text back to Contact in correct language
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// Open slide animation
$(function () {
if ($button.html(== 'Contact') {
$button.html('Close'); }
else if ($button.html(== 'Contatto') {
$button.html('Cerca'); }
else ($button.html(== 'Contacto') {
$button.html('Chiudere'); }
});
// Change text back to Close in the correct language
}
});
See my attempt script above which is not working on this jsFiddle.
Here's a working example: http://jsfiddle.net/Qh8fL/2/
When one of the language buttons gets clicked, it stores the strings for Contact and Close using jQuery's .data() method. Then, when the contact/close button gets clicked, it refers to those strings rather than having it hard-coded.
Here are the relevant lines of code:
$("#english").click(function() {
$(".contact-button").html('Contact').data('langTxt',{contact:'Contact',close:'Close'});
});
$("#spanish").click(function() {
$(".contact-button").html('Contatto').data('langTxt',{contact:'Contatto',close:'Close'});
});
$("#italian").click(function() {
$(".contact-button").html('Contacto').data('langTxt',{contact:'Contacto',close:'Close'});
});
if ($button.html() == 'Close') {
//...
$button.html($button.data('langTxt').contact);
} else {
//...
$button.html($button.data('langTxt').close);
}
All you need to do to modify the "close" text appropriately is by editing the close property inside the calls to data() that occur in each of the click events.
You should never depend on label strings ... especially in a multilingual environment. Instead you should use placeholders that you store in an attribute (maybe using .data()). Then you write your own setters for the labels depending on the value of the attribute.
var myLabels = {'close': ['Close', 'Cerca', 'Chiudere'], 'contact' : ['Contact', 'Contatto', 'Contacto']};
var currLang = 2; // to select italian
....
// to set the label
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
....
if($button.data('mylabel') == 'close') {
$button.data('mylabel', 'contact');
$button.html(myLabels['contact'][currLang]);
} else {
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
}

More control when doing animations in Dashcode/Dashboard?

Recently I am giving another shot to Dashcode ;)
It's great. Is just I think is not well documented.
I have a stackLayout object with only two views in it, and a couple of buttons that interchange the views with a transition.(views show data of a large array, list)
Animations and transitions work perfect. The problem is, when I press a button while animating the animation starts again and it looks ugly (If I had n views for a datasource array of length n this should't be a problem, but this is not my case).
I want to disable buttons while animation is taking place.
Is there any callback, delegate, or any way I can get a notification when the animation is finished?
This is what I have done:
function _changeView(transitionDirection, newIndex){
//Create transition
var newTransition = new Transition(Transition.SWAP_TYPE, 0.9, Transition.EASE_TIMING);
newTransition.direction = transitionDirection;
//I only have two views. I use currentView's id to calculate not current view id and change text inside of it.
var stackLayout = document.getElementById('stackLayout').object;//stackLayout object
var nextViewId = (stackLayout.getCurrentView().id == 'view1')? '2':'1'; //
//change the text in the view that is going to appear
document.getElementById('text'+nextViewId).innerHTML = list[curIndex];
stackLayout.setCurrentViewWithTransition('view'+ nextViewId, newTransition, false);
}
function goPrevious(event)
{
curIndex--;
if(curIndex < 0){
curIndex = list.length-1;
}
_changeView(Transition.LEFT_TO_RIGHT_DIRECTION, curIndex);
}
function goNext(event)
{
curIndex++;
if(curIndex >list.length - 1){
curIndex = 0;
}
_changeView(Transition.RIGHT_TO_LEFT_DIRECTION, curIndex);
}
Eventually found the answer to this. Here's how I did it:
document.getElementById('stackLayout').object.endTransitionCallback=function(stackLayout, oldView, newView) {
//PUT CODE HERE USING stackLayout, oldView, newView to show params
}
In fact you can find all the stackLayout methods and properties in the StackLayout.js file in your project!!
Hope this helps

Categories

Resources