does javascript remove event listeners? - javascript

On a test webpage I have, there is a link like so:
HOME
The style for it is like so:
nav > a {
text-decoration: none;
color: #0000aa;
display: inline-block;
width: 80px;
padding: 0 10px;
}
nav > a:hover {
background-color: #eeeeee;
}
and switchf() (switch field) is like so:
function switchf(field,tab) {
document.getElementById("home").style.display = "none";
document.getElementById("about").style.display = "none";
document.getElementById("account").style.display = "none";
document.getElementById("contact").style.display = "none";
document.getElementById("t1").style.backgroundColor = "#dddddd";
document.getElementById("t2").style.backgroundColor = "#dddddd";
document.getElementById("t3").style.backgroundColor = "#dddddd";
document.getElementById("t4").style.backgroundColor = "#dddddd";
document.getElementById(field).style.display = "inline-block";
tab.style.backgroundColor = "#cccccc";
}
The link basically acts as a tab, to show a different thing. There are three others like it.
The JavaScript works fine switching tabs, but when I hover over a tab after I've used switchf(), it doesn't change color anymore.
Is there something wrong with my code?
thanks.
EDIT
this is how I fixed mine:
first, I added class="tab" to all the links, so they looked like this:
HOME<br />
second, I changed the javascript so that the function switchf() was like this:
function switchf(field,tab) {
document.getElementById("home").style.display = "none";
document.getElementById("about").style.display = "none";
document.getElementById("account").style.display = "none";
document.getElementById("contact").style.display = "none";
var t = document.getElementsByClassName("tag"); // here is different
for(var i = 0; i < t.length; i++) {
t[i].style.backgroundColor = "#dddddd";
t[i].addEventListener("mouseover");
t[i].addEventListener("mouseout");
}
document.getElementById(field).style.display = "inline-block";
tab.style.backgroundColor = "#cccccc";
}
and it worked.

Inline CSS takes precedence over stylesheets. Once you click on a link, it will set the background-color property for all links, hence all links will not change color when you hover over it.
A better alternative than hard-coding the style in your elements, you can try adding a CSS class to your links (like page-active) and style those elements as needed.
Yet another alternative that saves you from clearing old classes is adding a class or ID to the page and use that to hide/show links as needed.
<style>
nav > a {
display: none;
}
#page-about nav > a#link-home {
display: inline-block;
}
<body id="page-about">
<nav>
Home
About
</nav>
</body>
This should give you a general idea, polishing it is an exercise for the reader.

Related

Removing JavaScript behavior

I need to remove the JavaScript behavior that I set on a div.
First, I set the CSS (it's an simple example) :
#redBloc {
width: 100px;
height: 50px;
background-color: #ad3232;
}
#redBloc:hover {
background-color: #3270ad;
}
Okay, for some reasons I need to override the behavior when the mouse is over my div.
var redBloc = document.getElementById('redBloc');
redBloc.onmouseover = function() {
this.style.backgroundColor = 'red';
};
It works like I want.
But later in my process, I need to reset the JavaScript behavior, to retrieve the behavior written in my CSS file.
How can I do this ?
Thank you
EDIT
I didn't need to override the behavior on the onmouseleave event, but later in my code, by the press of a button "disable behavior" for example.
That was solved by the solution of #T.J.Crowder.
Thank you all !
I think you mean you want to remove the specific background color so that the one from CSS can show through again (rather than "behavior").
If so, assign "" to it:
theElement.style.backgroundColor = "";
If you really do mean behavior and you don't want that mouseover handler to fire anymore, since you've used onmouseover to assign it, you can remove it by assigning null:
theElement.onmouseover = null;
Make your element null on mouseout, like:
var redBloc = document.getElementById('redBloc');
redBloc.onmouseover = function() {
this.style.backgroundColor = 'red';
};
redBloc.onmouseout = function() {
this.style.backgroundColor = '';
};
Have a look at the snippet below:
var redBloc = document.getElementById('redBloc');
redBloc.onmouseover = function() {
this.style.backgroundColor = 'red';
};
redBloc.onmouseout = function() {
this.style.backgroundColor = '';
};
#redBloc {
width: 100px;
height: 50px;
background-color: #ad3232;
}
#redBloc:hover {
background-color: #3270ad;
}
<div id="redBloc"></div>
Hope this helps!
You can remove the effect when user leaves your element using onmouseleave & null the style attribute:
var redBloc = document.getElementById('redBloc');
redBloc.onmouseover = function() {
this.style.backgroundColor = 'red';
};
redBloc.onmouseleave = function() {
this.style.backgroundColor = "";
};
<span id="redBloc">Hover me & leave me!</span>
You need to remove the style attribute by running the this code
var redBloc = document.getElementById('redBloc');
redBloc.removeAttribute('style')
You can have functionality on onmouseleave
redBloc.onmouseleave = function(){
this.removeAttribute('style');
}
You want to give redBloc the style with id #redBloc defined in Your css ... What You can do is create a css class and put all the styles in it that you want to apply on redBloc
.redBloc {
width: 100px;
height: 50px;
background-color: #ad3232;
}
then in your javascript you can add this class to redBloc on mouseover
var redBloc = document.getElementById('redBloc');
redBloc.onmouseover = function() {
this.className += " redBloc";
};
and this will add those styles defined in redBloc css class on your redBloc div. Hope this helps !

How do I allow JS onclick with pointer-events:none;?

I have a div over the whole page to close a dropdown menu when the big divis clicked. The thing is that I need pointer-events: none; because if I don't use it, the whole page gets blocked by the big div.
JS onclick won't work when I have pointer-events:none; So, I don't really know how to solve this.
function test() {
if (document.getElementById('div1').style.display == 'block') {
document.getElementById('div1').style.display = 'none';
}
else{
}
}
#big_div{
width: 100%;
height: 100%;
display: block;
pointer-events:none;
}
<div id="big_div" onclick="test()"></div>
Instead of using a div covering your whole page, put a click listener on the document, check to see if the clicked element is the menu or a child of the menu, if not then hide the menu
document.addEventListener("click",function(e){
var menu = document.getElementById("myMenu");
var target = e.target;
if(target !== menu && !menu.contains(target)){
menu.style.display = "none";
}
});
Demo
document.addEventListener("click",function(e){
var menu = document.getElementById("myMenu");
var target = e.target;
var openBtn = document.querySelector("button");
if(target !== menu && !menu.contains(target) && target !== openBtn){
menu.style.display = "none";
}
});
document.querySelector("button").addEventListener("click",function(){
document.getElementById("myMenu").style.display = "block";
});
menu {
width:120px;
height:300px;
background:#88DDFF;
display:none;
}
<menu id="myMenu"><span>some item</span></menu>
<button>Open menu</button>
pointer-events: none means no events will come through. Instead, you should close the menu by listening to click/mousedown events on the entire document (and remove your div that is set to pointer-events: none).
document.addEventListener('mousedown', function(e) {
// You may need a better check involving e.target because
// you won't want to close the menu when clicking inside the menu
// or on the button (if the menu is not open)
if (!e.target.contains(menuNode)) {
document.getElementById('div1').style.display = 'none';
}
});
Sorry, I didn't read your question carefully so I got downvotes for my wrong answer.
But, according to your question, you want to cover the whole page with that div to block the click event but you still want to receive the click event then you can do like this actually:
1) Remove pointer-events:none; from that div and add the cursor:
#big_div {
width: 100%;
height: 100%;
display: block;
cursor: none;
}
2) Add the listener to your div like I previously mentioned and prevent the click from there:
document.getElementById("big_div").addEventListener("click", function(e) {
e.preventDefault();
// Do whatever you want to do
if (document.getElementById('div1').style.display == 'block') {
document.getElementById('div1').style.display = 'none';
}
});

How to display items of a particular div on mouseover

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/

Toggle multiple divs on and off (almost working)

I have this:
function toggleCharts() {
var x, divArray = ["item_4746983", "item_4491867"];
for (x in divArray) {
if (x) {
document.getElementById(divArray[x]).style.display = 'block';
}
}
<button onClick="toggleCharts();">Charts</button>
and this:
#item_4746983 {
display:none;
}
#item_4491867 {
display:none;
}
item_4746983 & item_4491867 are thumbnails that I want to show or hide when you click on charts
The code works and they display when I click the button but I can't figure out the code to hide them by clicking on it again.
Instead of styling by id, style by class:
.hiddenThumbnail {
display:none;
}
Then apply and remove the hiddenThumbnail class to and from the two items. This makes your css code smaller, and makes everything generally more maintainable. See this excellent answer for a guide on how to modify the classes.
Alternatively, use a library like YUI to do it (I'm sure jquery has similar functions also).
Check if the div is shown already and change the display. The following code should work.
var div = document.getElementById(divArray[x])
var shown = div.style.display;
if ("block" == shown) {
div.style.display = none;
} else {
div.style.display = block;
}
Here is a link that shows various ways of doing what you want:
http://www.dustindiaz.com/seven-togglers/
Check the demo.
function toggleCharts() {
var divArray = ["item_4746983", "item_4491867"], i, ele;
for (i=0; i < divArray.length; i++) {
ele = document.getElementById(divArray[i]);
ele.style.display = ele.style.display === 'block' ? 'none' : 'block';
}
}

How to change visibility of div's child elements in "onmouseover" function

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");

Categories

Resources