Is there a way to show these hidden element with mouseover? - javascript

In my html code I have a list of these <li> elements:
<li class="liitem" id="183"><span> Google </span><br>
<ul><li><span>gmail.com </span><span id="183" style="float:right;display:none;">delete</span></li></ul></li>
I want this:
When there is a mouseover on a <li> element of the "liitem" class, then set display:block of the span with the same id ( 183 in this case ).
I have writed this code but it's incomplete and I don't know how to do:
var elms = document.getElementsByTagName('li');
for (var i = 0; i < elms.length; i++){
if (elms[i].getAttribute('class') === 'liitem'){
elms[i].onmouseover = function(){
//set display:block
}
elms[i].onmouseout = function(){
//set display:none
}
}
}

you have set an id with the same value id should be unique. so you could add a value to the id to make it diferent for the liitem's id. like.
Just make sure there is no space to be safe between the a and span.
<ul>
<li class="liitem" id="183"><span> Google </span><br>
<ul><li><span>gmail.com</span><span style="float:right;display:none;">delete</span></li></ul>
<ul><li><span>docs</span><span style="float:right;display:none;">delete</span></li></ul>
</li>
</ul>
.
var elms = document.getElementsByTagName('li'),
emls_len = elms.length;
for (var i = 0; i < emls_len; i++){
if (elms[i].className == 'liitem'){
var arr_sub_uls = document.getElementById(elms[i].id).getElementsByTagName('ul');
// for each UL within the liitem
for (var j = 0; j < arr_sub_uls.length; j++){
// assign id's to the span around delete
var actionis = arr_sub_uls[j].childNodes[0].childNodes[1].id = elms[i].id + "_" + j; // elms[i].id is the liitem id and j is the number of uls'
// attach the event handler
addEventHandler(arr_sub_uls[j].childNodes[0],actionis)
}
}
}
function addEventHandler(s, actionis){
s.onmouseover = function(){ document.getElementById(actionis).style.display = "block" }
s.onmouseout = function(){ document.getElementById(actionis).style.display = "none" }
}
see fiddle: http://jsfiddle.net/EW2cm/1/

You can do this:
elms[i].style.display = "block";
and
elms[i].style.display = "none";

Related

Javascript passing info from one function to another

I've created a JS function that hides a certain amount of breadcrumbs if there are too many. They are replaced by a button (ellipsis), when you click the button the hidden breadcrumbs are revealed.
The Problem: I loop through the breadcrumbs to see if there are enough to hide. If there are I hide them. But I can't figure out how to then call the code to create the button. If I call the button code in the loop I get more than 1 button generated.
Right now the button will always appear whether there are enough breadcrumbs to hide or not.
In my mind, I would have the for loop with the if statement return true to what would then be the button function. But I can't figure out how to do this. Please offer any pointers for restructuring this code if you can.
Here's a Codepen: https://codepen.io/sibarad/pen/GRvpEbp
Basic HTML:
<nav aria-label="breadcrumb">
<ol class="c-breadcrumb mb-7 md:mb-8">
<li class="c-breadcrumb-item">
Breadcrumb 1
</li>
<li class="c-breadcrumb-item">
Breadcrumb 2
</li>
<li class="c-breadcrumb-item">
Longer Breadcrumb Name 03
</li>
</ol>
</nav>
Javascript:
function breadcrumb() {
// Target specific breadcrumbs, not 1st or last 2
let hiddenbreadcrumb = document.querySelectorAll('.c-breadcrumb-item:nth-child(1n+2):nth-last-child(n+3)');
// Loop through select breadcrumbs, if length is greater than x hide them.
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
if(hiddenbreadcrumb.length >= 3) {
hiddenbreadcrumb[i].style.display = "none";
}
}
// This would be the button function, but I don't know how to engage this only if the if statement above was met.
let li = document.createElement('li');
li.className = 'c-breadcrumb-item';
let ellipbutton = document.createElement('button');
ellipbutton.type = 'button';
ellipbutton.innerHTML = '...';
ellipbutton.className = 'c-breadcrumb_btn u-btn-clear';
ellipbutton.onclick = function() {
console.log("clicked");
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
hiddenbreadcrumb[i].style.display = "flex";
}
li.style.display = "none";
};
li.appendChild(ellipbutton);
let container = document.querySelector('.c-breadcrumb-item:first-child');
container.insertAdjacentElement("afterend", li);
}
breadcrumb();
We can refactor your code slightly to achieve this - the if statement which checks whether there are more than 3 breadcrumbs doesn't need to be inside the for loop - it's redundant to keep checking the same value multiple times.
If we move that outside the loop then it can
a) prevent unnecessary looping when there aren't enough breadcrumbs, and
b) wrap around the button creation code as well, which should solve your problem.
For example:
if (hiddenbreadcrumb.length >= 3) {
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
hiddenbreadcrumb[i].style.display = "none";
}
let li = document.createElement('li');
li.className = 'c-breadcrumb-item';
let ellipbutton = document.createElement('button');
ellipbutton.type = 'button';
ellipbutton.innerHTML = '...';
ellipbutton.className = 'c-breadcrumb_btn u-btn-clear';
ellipbutton.onclick = function() {
console.log("clicked");
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
hiddenbreadcrumb[i].style.display = "flex";
}
li.style.display = "none";
};
let container = document.querySelector('.c-breadcrumb-item:first-child');
container.insertAdjacentElement("afterend", li);
}
It looks like some small initialization issues. This should correct it:
Change this:
let hiddenbreadcrumb = document.querySelectorAll('.c-breadcrumb-item:nth-child(1n+2):nth-last-child(n+3)');
// Loop through select breadcrumbs, if length is greater than x hide them.
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
if(hiddenbreadcrumb.length >= 3) {
hiddenbreadcrumb[i].style.display = "none";
}
}
to this:
let hiddenbreadcrumb = document.querySelectorAll('.c-breadcrumb-item');
if(hiddenbreadcrumb.length < 3)
return
for (var i = 1; i < hiddenbreadcrumb.length - 1; i++) {
hiddenbreadcrumb[i].style.display = "none";
}
Try this... it allows 3 li items as item1 ... item2ndLast, itemLast
(function () {
"use strict";
function breadcrumb() {
let hiddenbreadcrumb = document.querySelectorAll(".c-breadcrumb-item:nth-child(1n+2)");
if (hiddenbreadcrumb.length <= 3) return;
for (var i = 1; i < hiddenbreadcrumb.length - 1; i++) {
hiddenbreadcrumb[i].style.display = "none";
}
let li = document.createElement("li");
li.className = "c-breadcrumb-item";
let ellipbutton = document.createElement("button");
ellipbutton.type = "button";
ellipbutton.innerHTML = "...";
ellipbutton.className = "c-breadcrumb_btn u-btn-clear";
ellipbutton.onclick = function () {
console.log("clicked");
for (var i = 0; i < hiddenbreadcrumb.length; i++) {
hiddenbreadcrumb[i].style.display = "flex";
}
li.style.display = "none";
};
li.appendChild(ellipbutton);
let container = document.querySelector(".c-breadcrumb-item:first-child");
container.insertAdjacentElement("afterend", li);
}
breadcrumb();
})();

How to Change Color of Div within a for statement?

Inside my php while loop I output a div with id divborder, and class div-border
Inside that div i have another div with id title
<div id='divborder' class='div-border'>
<div id='Title'>This is Title</div> <br/> video elements
</div>
I have a JavaScript function that get called when the video ends
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader2 = document.getElementsByClassName("divborder")[3];
divBoader2.style.borderColor = "#b1ff99";
}
My Question is how do i change the border color of the div and the title of second div?
I can do it like this:
var divBoader2 = document.getElementsByClassName("divborder")[3];
divBoader2.style.borderColor = "#b1ff99";
which works but its not dynamic
Save the value of value at i in another variable declared with let
for (var i = 0; i < videos.length; i++) {
let index = i; //save the value as let so that its binding stays
videos[i].addEventListener("ended", function(event)
{
var divBoader = document.querySelectorAll("div-border")[index];
divBoader.style.borderColor = "#b1ff99";
}
}
Or if the video elements are within the div-border, then use closest
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader = event.currentTarget.closest(".div-border");
divBoader.style.borderColor = "#b1ff99";
}
}
A little less verbose code
[...videos].forEach( s => s.closest( ".div-border" ).style.color = "#b1ff99" )
Try this,
Give class name div-border instead of divborder
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader2 = document.getElementsByClassName("div-border")[3];
divBoader2.style.borderColor = "#b1ff99";
}
What you need is probably a videos[i].parentNode instead of document.getElementsByClassName("div-border")[3] (see https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)

Show class div and hide previous - pure javascript

I was actually using a script which allowed me to Show a div onclick and hide others but now I need to do the same with "class" instead of "id".
My current script:
function layout(divName){
var hiddenVal = document.getElementById("tempDivName");
if(hiddenVal.Value != undefined){
var oldDiv = document.getElementById(hiddenVal.Value);
oldDiv.style.display = 'none';
}
var tempDiv = document.getElementById(divName);
tempDiv.style.display = 'block';
hiddenVal.Value = document.getElementById(divName).getAttribute("class");}
What I tried using getElementsByClassName :
function layoutNEW(divName){
var hiddenVal = document.getElementById("tempDivName");
if(hiddenVal.Value != undefined){
var oldDiv = document.getElementById(hiddenVal.Value);
oldDiv.style.display = 'none';
}
var tempDiv = document.getElementsByClassName(divName);
for ( var i=0, len=tempDiv.length; i<len; ++i ){
tempDiv[i].style.display = 'block';
}
hiddenVal.Value = document.getElementById(divName).getAttribute("id");}
Any ideas ?
EDIT : A working example of my current script with "id" : JSFiddle
EDIT 2: It works great, but when the div (class) is cloned, only one of them is showing the div. Do you have an idea about this ? Where is a JSFiddle demonstrating the situation: JSFiddle
I think this is what you'd need. The idea is that you can use a data property on your <a> tags that will tell your click handler which classname to look for when showing an element. From there, you just hide the others. Here's a working demo:
var toggleControls = document.querySelectorAll("[data-trigger]");
var contentDivs = document.querySelectorAll(".toggle");
for (var i = 0; i < toggleControls.length; i++) {
toggleControls[i].addEventListener("click", function(event) {
var trigger = event.target;
var selector = "." + trigger.getAttribute("data-trigger");
var divToShow = document.querySelector(selector);
for (j = 0; j < contentDivs.length; j++) {
contentDivs[j].style.display = "none";
}
divToShow.style.display = "block";
});
}
.toggle {
height: 100px;
width: 100px;
display: none;
}
.div1 {
background-color: red;
}
.div2 {
background-color: blue;
}
.div3 {
background-color: purple;
}
.div4 {
background-color: green;
}
Show Div1
<br/>
Show Div2
<br/>
Show Div3
<br/>
Show Div4
<div class="toggle-container">
<div class="toggle div1"></div>
<div class="toggle div2"></div>
<div class="toggle div3"></div>
<div class="toggle div4"></div>
</div>
EDIT - As per updated question
In order to get this to work with dynamically created elements, you will have to put the var contentDivs = ... inside of the click handler, so you get a live version of that array. Also, you will need to change .querySelector to .querySelectorAll as the former only grabs the first matching element, not all as the latter does.
Here's what the code would look like: (note - I also moved the click handler into an outside function so it was not being recreated for every iteration of the loop, as is good practice)
function clickHandler(event) {
var contentDivs = document.getElementsByClassName("toggle"); // get live set of contentDivs in case any were added dynamically
var trigger = event.target;
var selector = "." + trigger.getAttribute("data-trigger");
var divsToShow = document.querySelectorAll(selector); // grab all matching divs
for (var i = 0; i < contentDivs.length; i++) {
contentDivs[i].style.display = "none";
}
for (var j = 0; j < divsToShow.length; j++) {
divsToShow[j].style.display = "block";
}
}
var toggleControls = document.querySelectorAll("[data-trigger]");
for (var i = 0; i < toggleControls.length; i++) {
toggleControls[i].addEventListener("click", clickHandler);
}
function cloneDiv() {
var elmnt = document.getElementsByClassName("container");
for ( var i=0; i<elmnt.length; i++ ) {
var cln = elmnt[i].cloneNode(true);
}
document.body.appendChild(cln);
document.getElementById("clone").appendChild(cln);
}
window.onload = cloneDiv();

Changing classes in a menu with Javascript

I am looking to create a very simple functionality of clicking on a menu tab and it changes color to let you know what page you are on. I am a novice so please take it easy on me...lol
/Menu in php header file/
<ul class="tabs" id="tabs">
<li class="selected">Home</li>
<li class="inactive">Bio</li>
<li class="inactive">Photo</li>
<li class="inactive">Thank</li>
<li class="inactive">Contact</li>
</ul>
/*This is the JavaScript file*/
window.onload = initPage;
function initPage() {
var tabs = document.getElementById("tabs").getElementsByTagName("li");
for (var i=0; i<tabs.length; i++){
var links = tabs[i];
links.onclick = tabClicked;
}
}
function tabClicked(){
var tabId = this.id;
document.getElementById(tabId).classList.toggle("selected");
var tabs = document.getElementById("tabs").getElementsByTagName("li");
for (var i=0; i < tabs.length; i++){
var currentTab = tabs[i];
if (currentTab.id !== tabId){
currentTab.class = "selected";
} else {
currentTab.class = "inactive";
}
}
}
element.setAttribute("class", "className");
You are using ids in your code but you don't have provided it in your markup. so give ids to li elements and try this.
function tabClicked(){
var tabId = this.id;
document.getElementById(tabId).classList.toggle("selected");
var tabs = document.getElementById("tabs").getElementsByTagName("li");
for (var i=0; i < tabs.length; i++){
var currentTab = tabs[i];
if (currentTab.id !== tabId){
currentTab.className = "inactive";
} else {
currentTab.className= "selected";
}
}
}
JS Fiddle Demo
Store a reference to each of the list items.
Create a variable to keep track of the current tab.
In an onclick function for each element (or you could use one onclick and just use some conditions), change the class attribute of the element by using the setAttribute() method.
Like this:
function onFirstTabClick() {
clearSelected();
tabVariable1.setAttribute("class","some-new-class");
}
function() clearSelected() {
switch(currentSelectedTrackerVariable) {
case 1: tabVariable1.setAttribute("class","some-new-class");
break;
// Do this for the amount of tabs that you have.
}
}
Working FIDDLE Demo
There is no need to define functions globally. Write all them in one package. The code below, works correctly with your HTML markup.
<script>
window.onload = function () {
var tab = document.getElementById('tabs');
var lis = tab.getElementsByTagName('li');
for (var i = 0, l = lis.length; i < l; i++) {
lis[i].onclick = function () {
for (var j = 0; j < l; j++) {
lis[j]["className"] = "inactive";
}
this["className"] = "selected";
};
}
};
</script>
If you use jQuery, then tabClicked can run:
jQuery('.selected').removeClass('selected').addClass('inactive');
jQuery(this).removeClass('inactive').addClass('selected');

How to increment div id value?

I have got a task to set the menu as selected. For that I use dynamic id.
So I want to increment it with respect to the selection
My code is
<div class="menuHeader ui-corner-top" id="menu"+ i>
<span>Home</span>
</div>
<div class="menuHeader ui-corner-top" id="menu"+ i>
<span>New Transaction</span>
</div>
<div class="menuHeader ui-corner-top" id="menu"+ i>
<span>Portfolio</span>
</div>
javascript is
$(document).ready(function () {
alert(document.URL);
var list = $("#menu");
for (var i = 1; i <= list.length; i++) {
list[i].innerHTML = i;
}
var str = document.URL.toLowerCase().indexOf("portfolio/index");
alert(str);
if (str >= 0) {
$('#menu').addClass("menuHeaderActive");
}
});
How can I do this?
var i=0;
$('.menuHeader').each(function(){
i++;
var newID='menu'+i;
$(this).attr('id',newID);
$(this).val(i);
});
This is the way to do it with Jquery
val elementList = $(".menu");
for (var i = 1; i <= list.length; i++) {
elementList[i].attr("id", "menu" + i);
}
Just use a class name instead of an id, you will be able to reuse the code you have just added but in this way.
var list = $(".menu");
One advice, don't do the highlighting of the item menu with javascript, do it server-side, and you can add the "activating" class directly in the HTML of the LI.

Categories

Resources