Multiple uses of the same script causing functionality errors - javascript

Sorry for the lack of knowledge but I don't know where else to turn. I had been working on the CSS for a project while the javascript was handled by a colleague. That colleague has now left the company and I have to finish his work to hit a deadline with very little knowledge of javascript. He had created a simple function (show/hide) that allowed us to show and hide content with an unordered list. Namely when you click on a list item, the corresponding div shows and the rest hides.
This was working fine, however I have since been asked to duplicate this so that multiple (show/hides) can be used on the page. When I did this the first one works ok, but the next scripts intefere with eachother and also hide content in the other divs. I've tried to fix this using my non-existent knowledge of javascript but to know avail (attempt is below). Any help here would be massively appreciated. Thanks in advance!
function toggle(target) {
var artz = document.getElementsByClassName('history');
var targ = document.getElementById(target);
var isVis = targ.style.display == 'block';
// hide all
for (var i = 0; i < artz.length; i++) {
artz[i].style.display = 'none';
}
// toggle current
targ.style.display = isVis? 'none' : 'block';
return false;
}
function toggle2(target) {
var artz2 = document.getElementsByClassName('vision');
var targ2 = document.getElementById(target2);
var isVis2 = targ.style.display == 'block';
// hide all
for (var i = 0; i < artz2.length; i++) {
artz2[i].style.display = 'none';
}
// toggle current
targ2.style.display = isVis2? 'none' : 'block';
return false;
}
jQuery(document).ready(function($) {
$('.slide-menu li a').on('click', function(){
$(this).parent().addClass('current').siblings().removeClass('current');
});
});
.container {
float: left;
}
.display-item {
display: none;
}
.display-item:first-of-type {
display: block;
}
.slide-menu li.current a {
color: #75aaaf;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="container">
<ul class="slide-menu" id="first">
<li class="current">1348</li>
<li>1558</li>
<li>1590</li>
</ul>
<div class="display-item history" id="1348" style="display:block;">History Content</div>
<div class="display-item history" id="1558">History Content2</div>
<div class="display-item history" id="1590">History Content3</div>
</div>
<div class="container">
<ul class="slide-menu" id="second">
<li class="current">Introduction</li>
<li>Highways</li>
<li>Transport</li>
</ul>
<div class="display-item vision" id="base" style="display:block;">Vision Content</div>
<div class="display-item vision" id="highways">Vision Content2</div>
<div class="display-item vision" id="transport">Vision Content3</div>
</div>

I think your code is okay if you intend duplicating the first toggle function in toggle2 function all you have to do is
Change the onclick event function from toggle to toggle2
<div class="container">
<ul class="slide-menu" id="second">
<li class="current"><a href="#/"
onclickk="toggle2('base');">Introduction</a></li>
<li><a href="#/"
onclick="toggle2('highways');">Highways</a></li>
<li><a href="#/"
onclick="toggle2('transport');">Transport</a></li>
</ul>
<div class="display-item vision" id="base"
style="display:block;">Vision Content</div>
<div class="display-item vision" id="highways">Vision
Content2</div>
<div class="display-item vision" id="transport">Vision
Content3</div>
</div>

This really isn't the way to set this up as it just causes the code to grow as more items need to be shown/hidden and the new code is largely the same as the old code. The original code also is more complex than it need be.
The following code will work no matter how many container structures you put on the page as long as you keep the structure the same as it is now. No ids are needed. No JQuery is needed either. You'll never need to touch the JavaScript, just add/remove HTML containers as you see fit.
See comments inline for details on what's happening.
.container {
float: left;
border:1px solid #e0e0e0;
margin:10px;
width:25%;
padding:3px;
}
/* Don't use hyperlinks <a></a> when you aren't
navigating anywhere. If you just need something
to click on, any element will do.
We'll just style the clickable elements to look like links
*/
.slide-menu > li {
text-decoration:underline;
cursor:pointer;
color: #75aaaf;
}
.hidden { display: none; } /* This class will be toggled upon clicks */
<!--
Don't use hyperlinks <a></a> when you aren't
navigating anywhere. If you just need something
to click on, any element will do.
The elements that should be hidden by default
will be so because of the "hidden" class that
they start off with.
No JQuery needed for this. Keep the HTML clean and
do all the event binding in JavaScript (no onclick="...")
-->
<div class="container">
<ul class="slide-menu">
<li class="current">1348</li>
<li>1558</li>
<li>1590</li>
</ul>
<div class="history" id="1348">History Content</div>
<div class="history hidden" id="1558">History Content2</div>
<div class="history hidden" id="1590">History Content3</div>
</div>
<div class="container">
<ul class="slide-menu">
<li class="current">Introduction</li>
<li>Highways</li>
<li>Transport</li>
</ul>
<div class="vision" id="base">Vision Content</div>
<div class="vision hidden" id="highways">Vision Content2</div>
<div class="vision hidden" id="transport">Vision Content3</div>
</div>
<!-- The following function will run automatically when this script element
is reached. Always keep the script just before the closing body tag (</body>). -->
<script>
(function(){
// Get any/all slide-menu elements into an array
let menus =Array.prototype.slice.call(document.querySelectorAll(".slide-menu"));
// Loop over the menus
menus.forEach(function(menu){
// Loop over the list items in the menu
Array.prototype.slice.call(menu.querySelectorAll("li")).forEach(function(item, index){
let idx = index;
// Set up a click event handler for each item
item.addEventListener("click", function(){
// Get all the <div> items in this menu into an Array
let divs = Array.prototype.slice.call(menu.parentElement.querySelectorAll("div"));
// Hide any item that was previously showing
divs.forEach(function(div){ div.classList.add("hidden"); });
// Query the parent element (the container) for all the
// corresponding <div> items and make it visible
divs[idx].classList.remove("hidden");
});
});
});
}());
</script>

Related

simplifying a javascript click count menu controlling 3 individual dropdowns

I've got 3 individual slide down menu's at the top of my page.
Page Menu
Account dropdown
Cart Dropdown
I've created individual open and close functions for each one
function menu_open(){
document.getElementById("myNav_overlay").style.height = "100%";
document.getElementById("myNav").style.height = "100%";
$('.menu-link').text("menu_open");
}
function menu_close() {
document.getElementById("myNav_overlay").style.height = "0%";
document.getElementById("myNav").style.height = "0%";
$('.menu-link').text("menu");
}
function account_open(){
document.getElementById("myAccount_overlay").style.height = "100%";
document.getElementById("myAccount").style.height = "100%";
$('.account-link').text("person");
}
function account_close() {
document.getElementById("myAccount_overlay").style.height = "0%";
document.getElementById("myAccount").style.height = "0%";
$('.account-link').text("person");
}
function cart_open(){
document.getElementById("myCart_overlay").style.height = "100%";
document.getElementById("myCart").style.height = "100%";
$('.cart-link').text("shopping_cart");
}
function cart_close() {
document.getElementById("myCart_overlay").style.height = "0%";
document.getElementById("myCart").style.height = "0%";
$('.cart-link').text("shopping_cart");
}
and then 3 individual click count functions to determine if the menu needs to open or close.
$(function() {
var menuclickCount = 0;
var accountclickCount = 0;
var cartclickCount = 0;
$('.menu-link').click(function () {
if(menuclickCount%2==0){
//do when open
menu_open();
account_close();
cart_close();
}else{
//do when closed
menu_close();
}
clickCount++;
});
$('.account-link').click(function () {
if(accountclickCount%2==0){
//do when open
account_open();
menu_close();
cart_close();
}else{
//do when closed
account_close();
}
accountclickCount++;
});
$('.cart-link').click(function () {
if(cartclickCount%2==0){
//do when open
cart_open();
menu_close();
account_close();
}else{
//do when closed
cart_close();
}
cartclickCount++;
});
});
This seems rather large compared to what it has to be and seems like there may be a better/simpler way of doing it. But honestly not sure how this would typically be done.
Is it better to leave a setup like this as is where each one is controlled individually and manually closes the other? OR, is it better to combine these into a more robust, smaller function that still controls them as needed?
If it is better to combine into a simpler function, how would this be done to where it still opens and closes each dropdown section?
I took 1 working function and duplicated it to make this work as is. So now I'm curious to see how this compares to what is considered industry standard and practical.
The HTML is simple....
Menu content
<div id="myNav_overlay" class="overlay_background"></div>
<div id="myNav" class="nav-overlay">
<div class="overlay-content">
MENU
</div>
</div>
Account content
<div id="myAccount_overlay" class="overlay_background"></div>
<div id="myAccount" class="account-overlay">
<div class="overlay-content">
ACCOUNT
</div>
</div>
Cart content
<div id="myCart_overlay" class="overlay_background"></div>
<div id="myCart" class="cart-overlay">
<div class="overlay-content">
CART
</div>
</div>
Without getting into styling the example too much, using the wonder of jQuery, you can do this:
(1) On click, select all menu containers (class .ddown in my example)
(2) return all menu containers to their default height of zero (by removing the .showMenu class with its new height)
(3) for the clicked container only, apply a style that increases container height.
$('.ddown').click(function(){
$('.ddown').removeClass('showMenu');
$(this).addClass('showMenu');
});
.container{height:100px;}
.ddown{display:inline-block;width:100px;border:1px solid #ccc;overflow:hidden;}
.mnuTitle{height:20px;}
.mnuContent{height:0;background:white;}
.showMenu{height:100px;background:palegreen;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="container">
<div id="myNav" class="ddown">
<div class="mnuTitle">Menu</div>
<div class="mnuContent">
MENU CONTENT
</div>
</div>
<div id="myAccount" class="ddown">
<div class="mnuTitle">Account</div>
<div class="mnuContent">
ACCOUNT CONTENT
</div>
</div>
<div id="myCart" class="ddown">
<div class="mnuTitle">Cart</div>
<div class="mnuContent">
CART CONTENT
</div>
</div>
</div><!-- .container -->

Javascript show/hide, show first div on page load

Can you help me to make the first div show on page load?
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].style.display = 'none';
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).style.display = 'block';
}
.tabContent {
display:none;
}
<div tabindex="1" class="tabs"><div id="tabs1" onclick="showStuff(this)">CARATTERISTICHE</div><div class="triangle-down-tab"></div></div>
<div id="tabs2" onclick="showStuff(this)">DESTINATARI</div><div class="triangle-down-tab"></div></div>
<div tabindex="3" class="tabs"><div id="tabs3" onclick="showStuff(this)"><i class="fa fa-calendar" style="color:#000000;"></i> CALENDARIO</div><div class="triangle-down-tab"></div></div>
<a name="contenuto"><hr></a>
<div id="tabs-1" class="tabContent">
<p>tab 1</p>
</div>
<div id="tabs-2" class="tabContent">
<p>tab 2 tab 2 </p>
</div>
<div id="tabs-3" class="tabContent">
<p>tab 3 tab 3 tab 3</p>
</div>
This is my actual code. jsFiddle
Thanks!
You could try running a function when the document is ready.
$(document).ready(function () {
showTab("tabs-1");
function showTab(divId) {
//Get the element
var divElement= document.getElementbyId(divId);
//Set the css property "display" from "none" to be "block";
divElement..style.display = "block";
}
}):
The function should run once the page has fully loaded.
Let me know how it goes.
I sure can. When you do this kind of stuff best use css. That way when the dom loads the css will kick in and your desired effect will show.
Further more its easier to understand and easier to code up.
.tabContent {
display:none;
}
.tabContent.active {
display:block;
}
Then in the HTML
<div id="tabs-1" class="tabContent active">
So when the page loads tab one is active
Then in your JS
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].className="tabContent";
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).className="tabContent active";
}
Updated fiddle!
https://jsfiddle.net/rb5c5095/3/
We could improve things since we know all the tabs will be made invisible at boot up and tab 1 will show. So when a tab is clicked we could just search the tab who has .active class and remove it, then apply the .active class to the new tab. This would have the benefit that any extra css you add in your html markup would not be removed by the JS code, but i reckon you can work that out and if you can't get back to me i can show you :-)
Here I am invoking the function (upon page load) that tweaks the css of the desired block;
Same can be achieved by $(document).ready;
I took this approach to avoid jquery;
window.onload = showDivOne();
function showDivOne() {
document.getElementById("tabs-1").style.display = "block";
}

Show specific div when atag is click. And hide other divs

I'm faily new to jquery and coding in general. I'm having a few troubles with this.
What i want is for when the page loads, the 'Vlogging' link is active and 'Details 1' is shown. Then when you click on either 'Filmmaking' or 'Beme'... 'Details 2 or 3 is shown and which ever one was there goes away.
I have everything set up right so far just need to get it to where when you click on one of the other links the correct 'Details' text shows itself.
Thank you so much and i have it in a fiddle right now!
http://jsfiddle.net/t1huc43d/
Here is the code than needs tuned:
$(function() {
$("togglediv1").click(function() {
$("#togglediv1").removeClass("display-start");
$("li").removeClass("display");
$(this).addClass("display");
});
});
This code will save you a lot of time. I added a custom attribute called "data". This attribute is used to tie the link to the tab you wish to display. This code will make it a lot easier to add additional tabs and etc. Look at the bottom for the changed HTML and JavaScript.
<div id="wrap">
<ul id="divtoggle">
<li><a class="link" data="1">Vlogging</a></li>
<li><a class="link" data="2"> Filmmaking</a></li>
<li><a class="link" data="3"> Beme</a></li>
</ul>
<div class="text">
<div class="tab" data="1">Details 1</div>
<div class="tab" data="2">Details 2</div>
<div class="tab" data="3">Details 3</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(function () {
$(".link").click(function () {
$(".active").removeClass("active");
$(this).addClass("active");
dataAttr = $(this).attr("data");
$(".tab").hide();
$(".tab[data="+dataAttr+"]").show();
});
$(".link:first").click();
});
</script>
$(function() {
$("#togglediv1").click(function() {
$("#one").removeClass("display");
$("#one").addClass("display-start");
$("#two").removeClass("display-start");
$("#two").addClass("display");
$("#three").removeClass("display-start");
$("#three").addClass("display");
});
});
$(function() {
$("#togglediv2").click(function() {
$("#one").removeClass("display-start");
$("#one").addClass("display");
$("#two").removeClass("display");
$("#two").addClass("display-start");
$("#three").addClass("display");
$("#three").removeClass("display-start");
});
});
...
Updated jsfiddle: http://jsfiddle.net/t1huc43d/3/
Since your ids aren't that conducive in tracking what is clicked and what isn't, I decided to just use this to find what you've clicked in correspondence with the details.
Your updated javascript:
$(function() {
$("li").click(function() {
$("#togglediv1").removeClass("active-start");
$("li").removeClass("active");
$(this).addClass("active");
let temp = $("#divtoggle").children();
var index;
for (let i = 0; i < temp.length; i++)
{
if (this == temp[i] )
{
index = i;
break;
}
}
$(".display-start").addClass("display");
$(".display-start").removeClass("display-start");
let text_children = $(".text").children()
let the_child = text_children[index];
$(text_children[index]).addClass("display-start");
$(text_children[index]).removeClass("display");
});
});
JQuery actually has some components to help you out, but to me, the shortest and CLEANEST way of doing this is the following:
The first thing I'd do is set an id of each of the titles, incrementing them by 1. Then, I'd do the same for the details like so:
<div id="wrap">
<ul id="divtoggle">
<li><a class="title" id="title-1">Vlogging</a></li>
<li><a class="title" id="title-2"> Filmmaking</a></li>
<li><a class="title" id="title-3"> Beme</a></li>
</ul>
<div class="text">
<div class='display' id="detail-1">Details 1</div>
<div class='display' id="detail-2">Details 2</div>
<div class='display' id="detail-3">Details 3</div>
</div>
</div>
After that, the JQuery is pretty simple. Setup a click event on the class title. The first thing to do is to parse the id of the clicked title. Once you have that, target the related detail and show it:
$(document).ready(function() {
$(".title").click(function() {
//*** get id
var id = $(this).attr("id").split("-")[1];
if (typeof id != "undefined"){
//*** hide other descriptions and show yours
$(".display").hide();
$("#detail-" + id).show();
}
});
});
DEMO: http://jsbin.com/volikofihe/edit?html,js,console,output
Here you go. Simplified your CSS a little. Toggling a .active class on the top links, and a .display class on the text divs. When you click on a link, the code uses the $.index() of that link in the list as the index of the text div to show. So if you click on the 2nd link, it will show the 2nd text box.
$(function() {
$toggleLinks = $('#divtoggle a'),
$displays = $('.text div');
$toggleLinks.on('click', function(e) {
e.preventDefault();
$toggleLinks.removeClass('active');
$(this).addClass('active');
$displays.removeClass('display');
$displays.eq($(this).closest('li').index()).addClass('display');
});
});
li {
color: grey;
font: effra;
font-weight: bold;
}
a:hover {
color: #aaaaaa;
cursor: pointer;
}
.active {
color: orange;
}
.text div {
display: none;
}
.text .display {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<ul id="divtoggle">
<li><a class="active">Vlogging</a></li>
<li><a>Filmmaking</a></li>
<li><a>Beme</a></li>
</ul>
<div class="text">
<div class='display'>Details 1</div>
<div>Details 2</div>
<div>Details 3</div>
</div>
</div>
Preserved as much of your existing code as possible. Updated fiddle.
I added a data-controls custom attribute to each of your li elements so as to associate them to each of the corresponding data divs:
<li data-controls="one"><a id="togglediv1" class="active-start">Vlogging</a></li>
<li data-controls="two"><a id="togglediv2"> Filmmaking</a></li>
<li data-controls="three"><a id="togglediv3"> Beme</a></li>
Then I updated the JavaScript to remove and add the classes, as needed.

How to simultaneously hide and show content and vice versa?

I have a problem and I need your help. I have several links (in <aside>) leading to several different menus (in <section>). On click over the link, only the relevant div in <section> is shown, the rest are hidden. This part is ok and working. What is not working is when I click over an image:
the current div (.menu) in <section> should be hidden;
the same picture (with bigger size) should be shown;
when you click once again over the big image, the big image should disappear and the current div in .menu (the one that was hidden on the first step) should appear one more time. Sort of toggling between content.
So if I click on a picture on the "second div" content, the same picture with bigger size should be show (the "second div" content should be hidden) and when I click once again over the big picture it should disappear and the "second div" content to be returned.
I tried with toggle() but had no success. Either I did not use it correctly, or it is not suitable for my case. This is where I managed to reach to.
I will really appreaciate your support - how to show only the hidden div, not all hidden div's. Right now, when you click on the big image it did not show the hidden div.
$(window).on("load", function() {
$("div.menu:first-child").show();
});
$(".nav a").on("click", function() {
$("div.menu").fadeOut(30);
var targetDiv = $(this).attr("data-rel");
setTimeout(function() {
$("#" + targetDiv).fadeIn(30);
}, 30);
});
var pictures = $(".img-1, .img-2").on("click", function() {
$("div.menu:active").addClass("hidden");
//how to reach out only the current, active div (not all div's in .menu)?
$(".menu").hide();
var par = $("section")
.prepend("<div></div>")
.append("<img id='pic' src='" + this.src + "'>");
var removePictures = $("#pic").on("click", function() {
$(this).hide();
$(".hidden").show();
});
});
.menu {
width: 100%;
display: none;
}
.menu:first-child {
display: block;
}
.row {
display: inline-block;
width: 100%;
}
.img-1,
.img-2 {
width: 120px;
height: auto;
}
<!doctype html>
<html>
<head>
</head>
<body>
<aside>
<ul class="nav">
<li>To first div
</li>
<li>To second div
</li>
<li>To third div
</li>
</ul>
</aside>
<section>
<div class="menu" id="content1">
<h3>First Div</h3>
<div class="present">
<div class="row">
<div>
<p>Blah-blah-blah. This is the first div.</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>Blah-blah-blah. This is the first div.</p>
</div>
</div>
</div>
</div>
<div class="menu" id="content2">
<h3>Second Div</h3>
<div class="present">
<div class="row">
<div>
<p>
Blah-blah-blah. This is the second div.
</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>
Blah-blah-blah. Yjis is the second div.
</p>
</div>
</div>
</div>
</div>
<div class="menu" id="content3">
<h3>Third Div</h3>
<div class="present">
<div class="row">
<div>
<p>
Blah-blah-blah. This is the third div.
</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>
Blah-blah-blah. This is the third div.
</p>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</body>
</html>
Sorry for the ugly sketch and pictures - it is only to get an idea what it should look like....
In general, it's poor form to ask on Stack Overflow how to code for a specific behavior. However, that takes some understanding of the libraries you're using, and what you are trying to achieve. Hopefully, my answer will help you better articulate and form your questions in the future.
Here's a fiddle for you: https://jsfiddle.net/hwd4b0ag/
In particular, I've modified your last click listener:
var pictures = $(".img-1, .img-2").on("click", function() {
var parentDiv = $(this).closest('div.menu').hide();
var blownUpPic = $("<img>").attr({
id: 'pic',
src: this.src,
'data-parent': parentDiv.attr('id')
})
.appendTo("section")
.on('click', function() {
$('#' + $(this).attr('data-parent')).show();
$(this).remove();
});
});
Now, let's review it!
First,
var parentDiv = $(this).closest('div.menu').hide();
In a jQuery listener, the this variable stores the current javascript DOM element that is the recipient of the event listener. In your case, it refers to an element that matches ".img-1, .img-2".
.closest(selector) will traverse up the DOM (including the current element) and find the first matching element for the provided selector. In this case, it finds your container div with class menu. Then we hide that div and save a reference to it in a variable.
Next, we create a full-sized version of the picture and assign it some attributes:
var blownUpPic = $("<img>").attr({
id: 'pic',
src: this.src,
'data-parent': parentDiv.attr('id')
})
We set the data-parent attribute to the id of our container div, so we have a reference back to it later.
We then add our image to the DOM:
.appendTo("section")
And declare a new click listener for it:
.on('click', function() {
$('#' + $(this).attr('data-parent')).show();
$(this).remove();
});
With $(this).attr('data-parent') we use the reference to our container div that we assigned earlier, and then retrieve that element by its id. We unhide the container div and remove the full-sized image.
All done!
There are better ways to code this, but I think this is a good next step for you that's analogous to your current code.

Conflict between some JavaScript and jQuery on same page

I am using a JavaScript function and some jQuery to perform two actions on a page. The first is a simple JS function to hide/show divs and change the active state of a tab:
This is the JS that show/hides divs and changes the active state on some tabs:
var ids=new Array('section1','section2','section3');
function switchid(id, el){
hideallids();
showdiv(id);
var li = el.parentNode.parentNode.childNodes[0];
while (li) {
if (!li.tagName || li.tagName.toLowerCase() != "li")
li = li.nextSibling; // skip the text node
if (li) {
li.className = "";
li = li.nextSibling;
}
}
el.parentNode.className = "active";
}
function hideallids(){
//loop through the array and hide each element by id
for (var i=0;i<ids.length;i++){
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
//safe function to show an element with a specified id
document.getElementById(id).style.display = 'block';
}
The html:
<ul>
<li class="active"><a onclick="switchid('section1', this);return false;">ONE</a></li>
<li><a onclick="switchid('section2', this);return false;">TWO</a></li>
<li><a onclick="switchid('section3', this);return false;">THREE</a></li>
</ul>
<div id="section1" style="display:block;">TEST</div>
<div id="section2" style="display:none;">TEST 2</div>
<div id="section3" style="display:none;">TEST 3</div>
Now the problem....
I've added the jQuery image gallery called galleria to one of the tabs. The gallery works great when it resides in the div that is intially set to display:block. However, when it is in one of the divs that is set to display: none; part of the gallery doesn't work when the div is toggled to be visible. Specifically, the following css ceases to be written (this is created by galleria jQuery):
element.style {
display:block;
height:50px;
margin-left:-17px;
width:auto;
}
For the life of me, I can't figure out why the gallery fails when it's div is set to display: none. Since this declaration is overwritten when a tab is clicked (via the Javascript functions above), why would this cause a problem? As I mentioned, it works perfectly when it lives the in display: block; div.
Any ideas? I don't expect anybody to be familiar with the jQuery galleria image gallery... but perhaps an idea of how one might repair this problem?
Thanks!
If you are including jQuery then you can shorten your javascript to this:
$(function() {
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would also remove the inline styles that set display:none. Then you can in your javascript you can initialize galleria then hide your sections.
Something like:
$(function() {
$('#section2, #section3').hide();
$('#section2 .images').galleria();
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would even go further and change your html to be something like this:
<ul class="sectionlinks">
<li class="active">ONE</li>
<li>TWO</li>
<li>THREE</li>
</ul>
<div id="section1" class="section">TEST</div>
<div id="section2" class="section">TEST 2</div>
<div id="section3" class="section">TEST 3</div>
Then you javascript could just be:
$(function() {
$('#section2 .images').galleria();
$('#section2, #section3').hide();
var sections = $('.section');
$('.sectionlinks a').click(function(e){
e.preventDefault();
sections.hide();
$($(this).attr('href')).show();
$(this).closest('ul').find('li').removeClass('active');
$(this).closest('li').addClass('active');
});
});
Working example: http://jsfiddle.net/cdaRu/2/
Set them all to 'block' by default, initialize the galleria image gallery, and afterwards hide the divs you want hidden and see if that fixes it. Or try initializing the gallery again after every switchid.
My first recommendation would be to re-write your original Javascript function to use jQuery. It already has built-in visibility toggle functions ... using the same system will minimize conflicts and make for smoother code.
This is just "off the cuff" but perhaps the box model is incomplete: "The element will generate no box at all" with display: none;
Perhaps change that back to "block" and set visibility: hidden; would be better?

Categories