In my website I would like to change some style properties of a div when user moves the mouse over it. I would also like to hide/show some child elements of this div. I don't have any experience with JavaScript, I'm experimenting with some code I found in the Internet.
Let's say my div looks like that:
<div class="Advertisement">
<h2 class="Title">title</h2>
</div>
And I want to hide this h2 element after moving the mouse over the div. My JS Script looks like this:
window.onload = function() {
var lis = document.getElementsByClassName("Advertisement");
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.style.backgroundColor = "green";
this.style.width = "800px";
var children = lis[i].childNodes.getElementsByClassName("Title");
for (var j = 0; j < children.length; j++) {
children[j].onmouseover = function() {
this.style.visibility = "hidden";
};
}
};
}
};
Changing of size and background color works fine, but the "h2" element doesn't disappear. What did I do wrong?
Actually you don't need JavaScript for that task. Why not use plain HTML/CSS?
Try this:
<style>
div.advertisement:hover > h2, div.advertisement:focus > h2 {
color: red;
}
div.advertisement > h3 {
display: none;
}
div.advertisement:hover > h3, div.advertisement:focus > h3 {
display: block;
}
</style>
<div class="advertisement" tabindex="-1">
<h2>title</h2>
<h3>hidden text</h3>
</div>
This one actually shows something, but of course it works vice versa with hiding your h2.
Extension by RyanB
This is similiar to an answer I'd give. I would say the hidden text should be a <p>, <span> or a <div> versus a <h3> to have better semantics. Also add tabindex="-1" to the div if it is that important. Adding tabindex="-1" allows the <div> to receive focus.
lis[i] is undefined here and no need of childnode
So,instead of this
var children = lis[i].childNodes.getElementsByClassName("Title");
Write
var children = this.getElementsByClassName("Title");
Related
I am trying to create tabs with vanilla JavaScript, each tab has an icon and a title inside the link
<div class="tabs-bar-item">
<a href="#tab3">
<img class="icon" src="img/school.png">
<h3 class="title">Instruktāžas datu aizsardzībā</h3>
</a>
</div>
It should open the tab content
<div id="tab3" class="tabs-content-item">
The problem is that .getAttribute("href"); returns null when I have <img> and <h3> elements inside the link.
Everything works if I change the tab to
<div class="tabs-bar-item">
<img class="icon" src="img/school.png">
Instruktāžas datu aizsardzībā
</div>
but I want the tab content to open when clicked anywhere on .tabs-bar-item. How can it be done in vanilla JavaScript?
Full JS code:
let tabs = document.querySelectorAll('.tabs-bar .tabs-bar-item');
function tabClicks(tabClickEvent) {
for (let i = 0; i < tabs.length; i++) {
tabs[i].classList.remove("active");
}
let clickedTab = tabClickEvent.currentTarget;
clickedTab.classList.add("active");
tabClickEvent.preventDefault();
let contentPanes = document.querySelectorAll('.tabs-content-item');
for (i = 0; i < contentPanes.length; i++) {
contentPanes[i].classList.remove("active");
}
let anchorReference = tabClickEvent.target;
let activePaneId = anchorReference.getAttribute("href");
let activePane = document.querySelector(activePaneId);
activePane.classList.add("active");
}
for (i = 0; i < tabs.length; i++) {
tabs[i].addEventListener("click", tabClicks)
}
Css for tab content:
.tabs-content .tabs-content-item {
display: none;
}
.tabs-content .tabs-content-item.active {
display: block;
}
Element.closest searchs up the DOM to find an element matching the selector passed as argument. If Element already matches the selector, Element (the node on which closest is called) is returned.
Hence try changing
let anchorReference = tabClickEvent.target;
to
let anchorReference = tabClickEvent.target.closest('a');
as for example in
let tabs = document.querySelectorAll('.tabs-bar .tabs-bar-item');
function tabClicks(tabClickEvent) {
for (let i = 0; i < tabs.length; i++) {
tabs[i].classList.remove("active");
}
let clickedTab = tabClickEvent.currentTarget;
clickedTab.classList.add("active");
tabClickEvent.preventDefault();
let contentPanes = document.querySelectorAll('.tabs-content-item');
for (i = 0; i < contentPanes.length; i++) {
contentPanes[i].classList.remove("active");
}
let anchorReference = tabClickEvent.target.closest('a');
console.log( anchorReference);
let activePaneId = anchorReference.getAttribute("href");
let activePane = document.querySelector(activePaneId);
activePane.classList.add("active");
}
for (i = 0; i < tabs.length; i++) {
tabs[i].addEventListener("click", tabClicks)
}
.tabs-content .tabs-content-item {
display: none;
}
.tabs-content .tabs-content-item.active {
display: block;
}
<div class="tabs-bar">
<div class="tabs-bar-item">
<a href="#tab3">
<img class="icon" src="img/school.png">
<h3 class="title">Instruktāžas datu aizsardzībā</h3>
</a>
</div>
</div>
<div class=tabs-content>
<div id="tab3" class="tabs-content-item">
content of tab3 with self contained link: <a id="here" href="#here">here</a>. Clicking "here" should not close the tab!
</div>
</div>
First off : you can do this in pure CSS with the :target pseudo-class, no JS needed.
.tabs-content .tabs-content-item {
display: none;
}
.tabs-content .tabs-content-item:target {
display: block;
}
In the near future, you can also style the tab link for the currently open tab by using the :local-link pseudo-class.
In your code, tabClickEvent.currentTarget always refers to the DIV element that you attached the listener to. That element has no href. There are multiple ways to fix that. Removing the DIV altogether would be a good start, then you can attach a listener to the links, or make a global listener that checks if it's been clicked on a link or its descendant (using element.closest('a')).
Either way, properly implementing navigation with JavaScript is not as easy as you might think (this is also why the pure CSS solution is good). For example, if the user wants to open the link in a new (browser) tab, you'd have to add some code to read the page's fragment on load and open the correct tab without user interaction.
I have several hidden divs inside large div, they can be shown one by one or all at once
It looks like this:
<div class="maindiv">
Print "<a href=javascript:show()>Click here to show all</a>
Show/hide div1
<div id="div1" style="display:none;">.....</div>
Show/hide div2
<div id="div2" style="display:none;">.....</div>
....
</div>
showhide() function is ok showing/hiding given div, show() works too but like this:
function show(){
div1.style.display="block";
div2.style.display="block";
...
}
so if I'll have 100 divs I'll have to enter it there 100 times
so my question is, how can I find all hidden divs in div with class maindiv and show em other way than enumerate? Or is the way I do ok?
Try using a generic css class name that is defined similarly:
.hidden{
display:none;
}
Then all you have to do is select the elements that have that class and remove that class. Assuming you are using at least IE9 you can try:
var divs = document.getElementsByClassName("hidden");
for(var i = 0; i < divs.length; i++)
{
divs[i].className = ""; //assuming you only have that class set else you will need to do a search and replace
}
If you have to support earlier versions there are other methods that will work to gather all the divs you need such as document.getElementsByTagName("div")
LIVE DEMO
Try this:
JQuery
$('.maindiv div a').click(function(){
$(this).next().toggle();
});
$('#showAll').click(function(){
$('.maindiv div div').show();
});
HTML
<div class="maindiv">
Click here to show all
<div>
Show/hide div1
<div>.....</div>
Show/hide div2
<div>.....</div>
</div>
</div>
CSS
.maindiv div a{
display:block;
}
.maindiv div div{
display:none;
}
Please try with the below code snippet.
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++){
//You can also write here if condition
divs[i].style.display = "block";
}
I think this can work
http://jsfiddle.net/rtu75/
function show() {
var divs = document.getElementsByClassName("maindiv");
var l = divs.length;
for( var i = 0; i < l; i++) {
divs[i].setAttribute("class", "show");
}
}
In your css
.show div {
display: block !important;
}
Added important since you have inline styles
Using jQuery, try
$("*").show();
or
$(parentElem).find("*").show();
or
$(":not(:visible)").show();
// This selects "*". Not I expected.
See w3 - css selectors, MDN - css pseudo classes, and jQuery $(), $().find(), $().filter() methods.
As I saw your code below, I saw it's almost work. You need to change id='div1' to class='hid' after that read my below step >> Go down
Show/hide div1
<div id="div1" style="display:none;">.....</div>
Here is my step, I am in same problem but now I can solve this because I read https://stackoverflow.com/a/24192071/10618118 then try to solve until done.
Read below,it's my code.It's work as I want.
in My Style for CSS be like this
<style>
.hid {}
</style>
Next is My Button to control it hidden or visible, Simple.
<button id="see" type="button" onclick="clickSee();">Show More ...</button>
Next step, look at my Javascript Code below,
I use JQuery 3.2.1 to change function in onclick of button.
when user want to hide or see more
just click Show More ... or ... Show less,
Actually it's the same button but user don't know.
If you didn't use JQuery yet and decide to use just copy
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
and paste in <head></head>
<script>
function clickSee() {
document.getElementById("see").innerHTML = "... Show Less";
var divs = document.getElementsByClassName("hid");
for (var i = 0; i < divs.length; i++){
divs[i].style.display = "block";
}
//I use JQuery
$("#see").attr("onclick", "clickHide()");
}
function clickHide() {
document.getElementById("see").innerHTML = "Show More ... ";
var divs = document.getElementsByClassName("hid");
for (var i = 0; i < divs.length; i++){
divs[i].style.display = "none";
}
//I use JQuery
$("#see").attr("onclick", "clickSee()");
}
</script>
If you have any issues just comment below, I will try to help because when done.
There are many way to make your idea work. but I see here is my basic way.
Feel free for new recommendation. Thank you.
I have the div structure
<div id="navigate">
<div class="menu">
<div class="group">Mail</div>
<div class="item">Folders</div>
<div class="item">Messages</div>
</div>
<div class="menu">
<div class="group">Contacts</div>
<div class="item">Friends</div>
<div class="item">Work</div>
</div>
<div class="menu">
<div class="group">Setting</div>
<div class="item">General</div>
<div class="item">Account</div>
</div>
</div>
Right now all items are hidden, and only divs with class 'group' is shown. What I would like to do is if I mouse over a specific menu div, only items of that menu would appear.
Right now I have this code:
function initialise()
{
hideAllItems();
setMouseOvers();
}
function hideAllItems()
{
var nav = document.getElementById("navigate");
var items = nav.getElementsByClassName("item");
for(var i = 0; i < items.length; i++)
{
items[i].style.visibility = "hidden";
items[i].style.display = "none";
}
}
function setMouseOvers()
{
var nav = document.getElementById("navigate");
var menuArr = nav.getElementsByClassName("menu");
for(var x = 0; x < menuArr.length; x++)
{
var itemArrs = menuArr[x].getElementsByClassName("item");
/*var show = function(){ show(itemArrs); };
var hide = function(){ hide(itemArrs); };*/
menuArr[x].onmouseover=function(){ show(itemArrs); };
menuArr[x].onmouseout=function(){ hide(itemArrs); };
}
}
function show(itemArr)
{
for(var i = 0; i < itemArr.length; i++)
{
alert(itemArr[i].innerHTML);
itemArr[i].style.visibility = "visible";
itemArr[i].style.display = "block";
}
}
function hide(itemArr)
{
for(var i = 0; i < itemArr.length; i++)
{
itemArr[i].style.visibility = "hidden";
itemArr[i].style.display = "none";
}
}
And this works, thought it only displays General and Account no matter which menu I hover over. I vaguely understand whats going wrong, but I can't see anyway to fix it. Any ideas? I do not want to change the html structure (e.g. add ids, or create specific classes) if i can help it!
I know that you most probably are looking for a javascript solution, but you could use a simple CSS solution:
.group:hover ~ .item {
display: block;
}
Working Fiddle
But be aware that it is not supported by older IE (< 8) browsers SUPPORT. It depends on your target group if you want to use it.
Why not simply using CSS: DEMO
.menu .item{
display:none;
}
.menu:hover .item{
display:block;
}
As you ask for an JavaScript Only solution (no change in HTML/css) i suggest the following:
The problem is using "itemArrs" in an anonymous function, as only the latest written "itemArrs" is used for all of them, use "this" instead.
for example:
...
groups[x].onmouseover=function(){ show(this); };
...
and
function show(item) {
var items = item.parentNode.getElementsByClassName("item");
...
A complete JS-only solution that works can be found here:
http://jsfiddle.net/Wn4d4/3/
i am trying to implement accessibility tools and i have managed to change the font size of a paragraph once the button has been clicked but i tried altering the code so that it will work on all the paragraph and it does not work
<script>
function myFunction()
{
var p =document.getElementsByTagName('p'); // Find the element
p.style.fontSize="1.5em"; // Change the style
}
</script>
<button type="button" style="background: #ccc url(images/small.jpg); padding: 0.3em 1em" onclick="myFunction()"></button>
this is how it worked before for just one paragraph but i am trying to more than one:
<script>
function myFunction()
{
x=document.getElementById("demo") // Find the element
x.style.fontSize="3.0em"; // Change the style
}
</script>
getElementsByTagName returns a NodeList, which is like an array, so you have to loop through them and apply the style to each element:
function myFunction() {
var arr = document.getElementsByTagName('p');
for (var i = 0; i < arr.length; i++) {
arr[i].style.fontSize = "1.5em";
}
}
Your issue in the first code block is that getElementsByTagName returns an nodeList of elements (which you can pretend is an array). So you would need to do this:
var p =document.getElementsByTagName('p'); // Find the element
for(var i=0; i<p.length; i++) {
p[i].style.fontSize="1.5em"; // Change the style
}
However, a better approach would be to define some css classes to do this job for you.
<style>
body { /*normal size*/
font-size: 1em;
}
body.largeFont {
font-size: 1.5em;
}
</style>
<script>
function largeFont() {
document.body.className="largeFont";
}
</script>
I want to hide the <h1> element using plain javascript, not jQuery, without adding id="whatever" or class="whatever" to the tag. Is this possible?
Why can't I just add id="whatever" to the tag?
I'm using a UIButton in xCode that when clicked, it injects javascript into a UIWebView. Inside that UIWebView is a H1 element that is on a website that I do not have access to to add <h1 id="whatever">. I hope it makes sense.
document.getElementsByTagName('h1')[0].style.display = 'none';
You can use getElementsByTagName method:
var h = context.getElementsByTagName('h1');
for (var i = h.length; i--; ) {
h[i].style.display = 'none';
}
Where context is document or more specific parent node you want to search your headers within.
However there is better solution. You could add specific class to some parent node and hide child headers with CSS:
.without-headers h1 {display: none;}
Use getElementsByTagName to hide the first h1 on your page:
document.getElementsByTagName("h1")[0].style.display = "none";
// ^ index 0, so that's the first `h` that's found.
Or to hide them all:
var headers = document.getElementsByTagName("h1");
for (var i = 0, l = headers.length; i < l; i++; ) {
headers[i].style.display = "none";
}
Or even better yet, if you can modify the CSS:
h1{
display:none;
}
For the JavaScript solutions, please keep in mind that they will only work when the DOM has been loaded.
Add a domready event listener, like this:
window.addEvent('domready', function() {
// modify your DOM here.
});
you can use getElementsByTagName
document.getElementsByTagName("h1")
But it will access all h1 elements, so to be more specific access it by index like this
document.getElementsByTagName("h1")[0].style.display = "none";
just small change in dfsq's code
var h = document.getElementsByTagName('h1');
for (var i =0; i<h.length; i++) {
document.getElementsByTagName('h1').item(i).style.display = 'none';
}