Expand/Collapse Menu not working at all - javascript

I am trying to cretae an expand/collapse menu using javascript. The structure something like this.
.menu
.subItem
.subItem
this a part of css
ul.menu {
display: none
}
but menu items not expandind from the collapse
this the js file
window.onload = initAll;
function initAll() {
var allLink = document.getElementsByTagName("a");
for (var i = 0; i < allLink.length; i++) {
if (allLink[i].className.indexOf("menuLink") > -1) {
allLink[i].onclick = togle;
}
}
}
function togle() {
var startMenu = this.href.lastIndexOf("/") + 1;
var stopMenu = this.href.lastIndexOf(".");
var thisMenuName = this.href.substring(startMenu, stopMenu);
var thisMenu = document.getElementById(thisMenuName).style;
if (thisMenu.display == "block") {
thisMenu.display = "none";
} else {
thisMenu.display = "block";
}
return false;
}
when I open up chrome developer tools I have realize that Its been pointed out
this line once click the menu
var thisMenu = document.getElementById(thisMenuName).style;
What am doing wrong again again again
#Edit:I forgot to add html file
<link rel="stylesheet" href="css.css">
<script src="js.js"></script>
a
</head>
<body>
<div>
trajedi
<ul class="menu" id="menu1">
<li>deneme</li>
<li>deneme</li>
</ul>
</div>

I don't know what you tried to do with the substring part in togle function. That's the only problem with your code. Change the line:
var thisMenu = document.getElementById(thisMenuName).style;
to
var thisMenu = document.getElementById('menu1').style;
and it will work. Take a look:
window.onload = initAll;
function initAll() {
var allLink = document.getElementsByTagName("a");
for (var i = 0; i < allLink.length; i++) {
if (allLink[i].className.indexOf("menuLink") > -1) {
allLink[i].onclick = togle;
}
}
}
function togle(e) {
// can't understand the use of the 3 lines below:
var startMenu = this.href.lastIndexOf("/") + 1;
var stopMenu = this.href.lastIndexOf(".");
var thisMenuName = this.href.substring(startMenu, stopMenu);
var thisMenu = document.getElementById('menu1').style;
if (thisMenu.display == "block") {
thisMenu.display = "none";
} else {
thisMenu.display = "block";
}
return false;
}
ul.menu {
display: none
}
<div>
trajedi
<ul class="menu" id="menu1">
<li>deneme</li>
<li>deneme</li>
</ul>
</div>
a much simpler and modern version of your code would be:
function initAll() {
Array.from(document.getElementsByTagName("a"))
.filter((link)=>link.className.indexOf("menuLink") > -1)
.forEach((link)=>link.onclick = ()=>{
var thisMenu = document.getElementById('menu1').style;
thisMenu.display = (thisMenu.display == "block") ? 'none' : 'block';
return false;
});
}
window.onload = initAll;
ul.menu {
display: none
}
<div>
trajedi
<ul class="menu" id="menu1">
<li>deneme</li>
<li>deneme</li>
</ul>
</div>

Related

How to show content when attribute is active

Here is the problem:
I have a slideshow containing 3 slides changing after 10 seconds which is generated by plugin so i don't have access to the html file.
<ul>
<li data-index="rs-101">
<li data-index="rs-102">
<li data-index="rs-103">
</ul>
<div class="content1">
content1
</div>
<div class="content2">
content2
</div>
<div class="content3">
content3
</div>
This slider is on the top of the screen and now I want to change the bottom of the screen according to the slides:
if rs-101 is selected: do this
if rs-102 is selected: do that
..
I found this which is not working:
function Content1(){
if ( $('html').attr('data-index') == 'rs-101' ) {
var x1 = document.getElementById("content1");
x1.style.display = "block";
} else {
x1.style.display = "none";
}
function Content2(){
if ( $('html').attr('data-index') == 'rs-102' ) {
var x1 = document.getElementById("content1");
x2.style.display = "block";
} else {
x2.style.display = "none";
}
function Content3(){
if ( $('html').attr('data-index') == 'rs-103' ) {
var x3 = document.getElementById("content1");
x3.style.display = "block";
} else {
x3.style.display = "none";
}
Please advice.
You could use something like this https://stackoverflow.com/a/18311216/9785689 to monitor the list for changes, when it detects a change call a single function changeContent(). If this doesn't work then you need to have a way to listen for the automated changes from the plugin (I would check with the author or the plugin).
function ChangeContent(){
var data = $('html').attr('data-index');
if ( data == 'rs-101' ) {
var x1 = document.getElementById("content1");
x1.style.display = "block";
} else {
x1.style.display = "none";
}
if ( data == 'rs-102' ) {
var x1 = document.getElementById("content1");
x2.style.display = "block";
} else {
x2.style.display = "none";
}
if ( data == 'rs-103' ) {
var x3 = document.getElementById("content1");
x3.style.display = "block";
} else {
x3.style.display = "none";
}
}

Javascript/jQuery Multi filtered gallery and arrays comparison

I'm sorry if this is a duplicate questions, but I've spent over 8hrs trying to figure out how to implement this, but it seems I haven't succeded so far.
I've got a photo gallery, each foto contains multiple tags. If multiple tags are active, it needs to show only items that include all the selected tags.
<ul class="tags-list container">
<li class="tag toate">Toate</li>
<li class="tag">Tag 3</li>
<li class="tag">Tag 2</li>
<li class="tag">Tag 4</li>
</ul>
<div class="grid">
<div class="grid-sizer"></div>
<div id="grid-item-0" class="grid-item " data-tag=" tag-1 tag-3 tag-7"></div>
<div id="grid-item-1" class="grid-item " data-tag=" tag-2 tag-1"></div>
<div id="grid-item-2" class="grid-item big" data-tag=" tag-3"></div>
<div id="grid-item-3" class="grid-item " data-tag=" tag-4 tag-2 tag-1"></div>
</div>
and JS:
function Gallery() {
this.tag = $('.tags-list .tag');
this.gridItem = $('.grid .grid-item');
this.activeTags = ['toate'];
this.itemsList = [];
this.activeItems = [];
this.init();
}
Gallery.prototype.init = function () {
this.masonry();
this.itemsListGen();
};
Gallery.prototype.itemsListGen = function () {
var _this = this;
$(this.gridItem).each(function () {
var tags = $(this).attr('data-tag');
tags = tags.trim();
// creates an array of objects with every item's id and tags
_this.itemsList.push({
'id': $(this).attr('id'),
'tags': tags.split(' ')
});
});
};
Gallery.prototype.masonry = function () {
$('.grid').masonry({
// options
columnWidth: '.grid-sizer',
itemSelector: '.grid-item',
percentPosition: true
});
};
Gallery.prototype.tagClick = function (e) {
e.preventDefault();
// currentTag has the clicked tag
var currentTag = $(e.currentTarget).attr('data-tag-slug');
$(e.currentTarget).toggleClass('active');
if ($(e.currentTarget).attr('data-tag-slug') === 'toate') {
this.toateClick();
} else {
// refresh current filters
this.refreshTags(currentTag);
// return validated items based on filters
this.returnValidItems();
// refresh the layout with the current items
this.refreshMasonry();
}
};
Gallery.prototype.refreshTags = function (e) {
// checks if the current tag is already active
// if it's active, it removes it and checks if there is any other active tag or should trigger 'toate'
// if it's not active, it adds it to the activeTags and removes 'toate'
if (this.activeTags.includes(e)) {
this.activeTags.splice(this.activeTags.indexOf(e), 1);
if (this.activeTags.length < 1) {
this.showAll();
}
} else {
this.activeTags.push(e);
if (this.activeTags.includes('toate')) {
this.removeToate();
}
}
};
Gallery.prototype.returnValidItems = function () {
for (var i = 0; i < this.itemsList.length; i++) {
var itemTags = this.itemsList[i].tags;
for (var j = 0; j < this.activeTags.length; j++) {
if (itemTags.includes(this.activeTags[j])) {
this.activeItems.push(this.itemsList[i].id);
} else {
this.activeItems.splice(this.activeItems.indexOf(this.itemsList[i].id), 1);
break;
}
}
}
};
Gallery.prototype.refreshMasonry = function () {
$('.grid-item').hide();
for (var i = 0; i < this.activeItems.length; i++) {
$('#' + this.activeItems[i]).show();
}
$('.grid').masonry();
};
Gallery.prototype.showAll = function () {
console.log('show all');
this.activeTags = ['toate'];
this.activeItems = [];
$('.grid-item').show();
$('.tags-list').find('.toate a').addClass('active');
$('.grid').masonry();
};
Gallery.prototype.toateClick = function (e) {
console.log('toate click');
$('.tags-list').find('.active').removeClass('active');
$('.tags-list .toate a').addClass('active');
this.showAll();
};
Gallery.prototype.removeToate = function () {
$('.tags-list li.toate > a').removeClass('active');
this.activeTags.splice(this.activeTags.indexOf('toate'), 1);
};
I am not capable of doing it. Please help? :)
Besides of helping me with the problem, any feedback regarding my code is welcomed.

Hide and show div with links

So I have this code that I will put in jsfiddle link bellow. Im making hide/show divs by clicking on links. Only problem is when I want to view a div (second, third or fourth div), lets say the third one, it doesnt show up on top but benith the first and second invisible divs. Anybody got any idea how to make this right and put any selected div on the top of the page?
<body>
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked" id="menu">
<li>Felge</li>
<li>Gume</li>
<li>Branici</li>
<li>Farovi</li>
</ul>
</div>
<div class="col-md-3">
<div class="div" id="content1">
<p>BBS</p>
<p>ENKEI</p>
<p>KONIG</p>
</div>
<div class="div" id="content2">
<p>Michelin</p>
<p>Hankook</p>
<p>Sava</p>
</div>
<div class="div" id="content3">
<p>AMG</p>
<p>Brabus</p>
<p>Original</p>
</div>
<div class="div" id="content4">
<p>Angel Eyes</p>
<p>Devil Eyes</p>
<p>Original</p>
</div>
</div>
`<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
function show(id) {
if (id == 'link1') {
document.getElementById("content1").style.visibility = 'visible';
document.getElementById("content2").style.visibility = 'hidden';
document.getElementById("content3").style.visibility = 'hidden';
document.getElementById("content4").style.visibility = 'hidden';
}
else if (id == 'link2') {
document.getElementById("content1").style.visibility = 'hidden';
document.getElementById("content2").style.visibility = 'visible';
document.getElementById("content3").style.visibility = 'hidden';
document.getElementById("content4").style.visibility = 'hidden';
}
else if (id == 'link3') {
document.getElementById("content1").style.visibility = 'hidden';
document.getElementById("content2").style.visibility = 'hidden';
document.getElementById("content3").style.visibility = 'visible';
document.getElementById("content4").style.visibility = 'hidden';
}
else if (id == 'link4') {
document.getElementById("content1").style.visibility = 'hidden';
document.getElementById("content2").style.visibility = 'hidden';
document.getElementById("content3").style.visibility = 'hidden';
document.getElementById("content4").style.visibility = 'visible';
}
}
function init() {
var divs = document.getElementsByTagName("div");
for (i = 0; i < divs.length; i++) {
if (divs[i].className == "div") {
divs[i].style.visibility = 'hidden';
}
}
var a = document.getElementsByTagName("a");
a.onclick = show;
}
window.onload = init;
`
https://jsfiddle.net/4qq6xnfr/
visibility: hidden hides element but leaves the space occupied by it. You need to hide element with display: none:
document.getElementById("content1").style.display = 'block';
document.getElementById("content2").style.display = 'none';
document.getElementById("content3").style.display = 'none';
document.getElementById("content4").style.display = 'none';
Also, you can optimize you code a little. Maybe like this:
function show(id) {
var number = id.replace('link', '');
var blocks = document.querySelectorAll("[id^=content");
for (var i = 0; i < blocks.length; i++) {
blocks[i].style.display = 'none';
}
document.querySelector('#content' + number).style.display = 'block';
}
Demo: https://jsfiddle.net/4qq6xnfr/3/
Use:
element.style.display = 'none'; // Hide
element.style.display = 'block'; // Show
The most efficient way to achieve this is as follows:
Change all the links from javascript:show('link1'), javascript:show('link2'), etc. to just #content1, #content2, etc.
You can now remove all of the javascript code.
Create a new CSS stylesheet (or use the <style> tags), and in the stylesheet, write the following -
.div {
display:none;
}
.div:target {
display:block;
}
That's it! I hope this helped you.

slideUp() all the elements but not the selected ones

All I want to do is:
there are 7 numbers and 7 divs, they are linked to each other (nr 0 it's in a relationship with div 0)
when one of the numbers is clicked, it should collapse all the other divs which are not selected
it can be selected more at one time
To sum up, basically, the page has some labels with numbers and 7 divs which are all displayed by default (the divs), but when one or more of them are chosen by clicking on the numbers, the page should display only the chosen divs.
This is what I've been trying to do:
for(var i = 0; i <= 6; i++) {
if(i != (floors[i])) {
$("#lvl" + floors[i]).slideUp();
}
}
More code:
http://jsfiddle.net/LSjg4/
Try
var floors = [];
var $lvls = $('.lvl'), $nrs = $(".nr");
$nrs.click(function () {
var $nr = $(this), index = $nrs.index($nr), $lvl = $lvls.eq(index);
$lvl.add($nr).toggleClass('active');
if($nr.hasClass('active')){
$lvls.not('.active').slideUp();
$lvl.slideDown();
$nr.css("background-color", "#1b7664");
$nr.css("border-color", "#236959");
floors.push(($nr).text());
} else {
$nr.css("background-color", "#02c099");
$nr.css("border-color", "#13a480");
if($nrs.filter('.active').length == 0){
$lvls.slideDown();
} else {
$lvls.not('.active').slideUp();
}
var text = $nr.text();
floors.splice($.inArray(text, floors), 1);
}
console.log('floors', JSON.stringify(floors))
});
Demo: Fiddle
I corrected a few things in your code. Here is the below working code and link to it in jsfiddle.
There was a data type mismatch(comparing string and int). When matching whether it exists in floors array, the code was checking floors[i] only whereas the i can be any position in floors.
var floors = [];
$(".nr").click(function () {
var state = $(this).data('state');
state = !state;
if (state) {
$(this).css("background-color", "#1b7664");
$(this).css("border-color", "#236959");
floors.push(parseInt($(this).text()));
console.log(floors);
for(var i = 0; i <= 6; i++) {
ret = $.inArray(i, floors);
if(ret==-1) {
$("#lvl" + i).slideUp();
}
else {
$("#lvl" + i).slideDown();
}
}
} else {
$(this).css("background-color", "#02c099");
$(this).css("border-color", "#13a480");
for (var i = 0; i < floors.length; i++) {
if (floors[i] == parseInt($(this).text()))
floors.splice(i, 1);
}
for(var i = 0; i <= 6; i++) {
ret = $.inArray(i, floors);
if(ret==-1) {
$("#lvl" + i).slideUp();
}
else {
$("#lvl" + i).slideDown();
}
}
}
$(this).data('state', state);
});
Demo Here: http://jsfiddle.net/bFe9T/
I believe this is what you're looking for:
$(".nr").click(function () {
$(this).toggleClass('selected');
$('.nr').each(function(){
var $target = $('#lvl'+$(this).text());
if($(this).is('.selected'))
$target.slideDown();
else
$target.slideUp();
});
});
Note that instead of changing the CSS properties I set up a class for the selected elements
Demo fiddle
Try this
$(".nr").click(function () {
//alert($(this).attr("data-select"));
if($(this).attr("data-select") === "1") {
$(this).attr("data-select","0");
} else {
$(this).attr("data-select","1");
}
$(".nr").each(function(){
if($(this).attr("data-select") === "1") {
var id = $(this).text();
$("div#lvl"+id).slideDown();
} else {
var id1 = $(this).text();
$("div#lvl"+id1).slideUp();
}
});
});
FIDDLE
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>slideUp demo</title>
<style>
.norm { background:#cccccc; margin:3px; width:80px;height:40px; float:left;color:#000000 }
.faded { background:#ffffff; margin:3px; width:80px;height:40px; float:left;color:#ffffff }
.btn{width:80px;}
</style>
<script src="http://code.jquery.com/jquery-1.8.1.js"></script>
</head>
<body>
<button class="btn" onClick="show(1)">1</button>
<button class="btn" onClick="show(2)">2</button>
<button class="btn" onClick="show(3)">3</button>
<button class="btn" onClick="show(4)">4</button>
<button class="btn" onClick="reset()">Reset</button>
<div class="norm" id="slide1">1</div>
<div class="norm" id="slide2">2</div>
<div class="norm" id="slide3">3</div>
<div class="norm" id="slide4">4</div>
<div></div>
<script>
var save = new Array();
function show(indx){
if($.inArray(indx, save)==-1){
save.push(indx);
for(var i=0;i<5;i++){
if($.inArray(i, save)==-1){
$('#slide'+i).attr('class','faded');
}
else{
$('#slide'+i).attr('class','norm');
}
}
}
}
function reset(){
save = new Array();
for(var i=0;i<5;i++){
$('#slide'+i).attr('class','norm');
}
}
</script>
</body>
</html>

JavaScript function works incorrectly

I have got 2 js functions and in a function show I want to get the index of the current visible element, but it always alerts 0. It doesn't seem to check, if function navigate_right() has changed the ids of the p elements or not.So how can I modify it so that it runs properly?
<html>
<style type="text/css">
p {
border:1px solid black;
width:100px;
height:30px;
display:none;
}
</style>
<p style="display:block" id="p">some text1</p>
<p>some text2</p>
<p>some text3</p>
<p>some text4</p>
<p>some text5</p>
<input type="button" value="left" onclick="show()" />
<input type="button" value="right" onclick="navigate_right()" id="right" />
<script>
var p = document.getElementsByTagName("p");
function navigate_right() {
for (var i = 1; i < p.length; i++) {
if (p[i - 1].style.display == 'block') {
p[i].style.display = 'block';
p[i - 1].style.display = 'none';
return;
}
}
}
function show() {
var c = document.getElementsByTagName("p");
var t;
for (var i = 0; i < p.length; i++) {
if (c[i].id = "vis") {
t = i;
alert(t);
return;
}
}
}
</script>
</html>
EDIT! there should be alert t;t is for index of a current paragraph visible
NOW IT WORKS!I have corrected some silly mistakes. But thanx everyone for help anyway
var p = document.getElementsByTagName("p");
function navigate_right() {
for(var i = 1; i <p.length; i++){
if(p[i-1].style.display == 'block') {
p[i].style.display = 'block';
p[i].id = "vis";
p[i-1].style.display ='none';
p[i-1].removeAttribute("id");
return;
}
}
}
function show(){
var c = document.getElementsByTagName("p");
var t;
for (var i = 0; i < p.length; i++) {
if(c[i].id == "vis") {
t = i;
alert(t);
return;
}
}
}
c[i].id = "vis" is setting the ID. The assignment evaluates to true so the code always goes into the if body first time round the loop. That's why i is always 0.
You want c[i].id === "vis" (or at least c[i].id == "vis").

Categories

Resources