event.stopPropagation() doesnt work - javascript

I have some buttons close to eachother. when hovering on them their child pop out and when hover done the effect is gone.
The problem is with css (:hover) I cant prevent jittery state. so I try to use mouseenter and mouseleave and use stopPropagation function to prevent jittery state when unwanted hover on child trigger parent eventListener.
but it doesnt work, I checked the other answers but dont know what is my problem
here is the link of my work
full code on >> https://jsfiddle.net/fe3m74xn/
var el = document.querySelectorAll('#slideShow_control a');
var slideShow_control_hoverIn = function(e, i) {
e.stopPropagation();
var bool = e.target.classList.contains('hover');
el.forEach.call(el, function(e){e.classList.remove('hover')});
if(!bool) {
e.target.classList.toggle('hover');
}
};
var slideShow_control_hoverOut = function(e, i) {
e.stopPropagation();
el.forEach.call(el, function(e){e.classList.remove('hover')});
};
el.forEach.call(el,function(e){e.addEventListener('mouseenter',slideShow_control_hoverIn,false)});
el.forEach.call(el,function(e){e.addEventListener('mouseleave',slideShow_control_hoverOut,false)});

Forget about event.stopPropagation() and use the pointer-events CSS property instead : it's able to set any element transparent to mouse interactions.
Only use it on the "pop out" element when the <a> is not hovered:
#slideShow_control figure {
/* ... */
pointer-events: none;
}
#slideShow_control a:hover figure {
/* ... */
pointer-events: all;
}
I also added an invisible pseudo-element to the <a> when it's hovered, just to make the link to the "pop out" element if your mouse cursor goes up over it and you want it to stay visible:
#slideShow_control > a:hover:after {
content: '';
position: absolute;
width: 20px;
height: 20px;
left: 0;
top: -20px;
/* background-color: red; */ /* uncomment to understand */
}
Here is the link to your edited Fiddle: https://jsfiddle.net/m6ephL81/

Related

CSS: Is it possible to make the ::after selector behave like a button?

Look at the code of below, as you can see there is a close icon floated to the right of a span element.
span {
width: 100%;
display: inline-block;
}
span:after {
content: "\2715";
float: right;
position: absolute;
}
span:hover:after {
cursor: pointer;
}
<span>Content</span>
I want the :after to behave like a button. As you could see, it makes the cursor a pointer on hover. How can I make it to behave like a button? For example, how can I add an onclick function to it?
Generally speaking, the pseudo element will inherit the events and event behavior assigned to the non-pseudo element that "owns" it.
So for instance, adding a click event listener to the above <span> will cause any pseudo elements of that span elemenet to inherit the same click event behavior.
If you wanted to achieve independence between the pseudo element and the "owner" element, in terms of click behavior (ie click behavior for the "pseudo" element only) you could use the pointer-events CSS property as shown below:
const span = document.querySelector("span");
span.addEventListener("click", () => alert("hey!"));
span {
display: inline-block;
position: relative;
background:red;
/* Blocks the click event from firing when span is clicked */
pointer-events:none;
}
span:after {
content: "'Pesudo button' - click me!";
position: absolute;
margin-left:1rem;
background:green;
width:15rem;
text-align:center;
color:white;
/* Allows the click event to fire when the pesudo element is clicked */
pointer-events:all;
}
span:hover:after {
cursor: pointer;
}
<span>I own the pesudo element</span>

Is there a property or workaround for padding-radius?

I am using a circular button,
border-radius:50%;
And I have an element inside of my element, in order to make the entire button clickable, and not just the content inside of my element.
When I add padding to the element, it makes it so that the entire button is clickable, but due to the fact that the border-radius is 50%, the corners of the button that shouldn't be clickable, are clickable.
I hope this outlines my problem enough, I'll include a jsfiddle if possible.
https://jsfiddle.net/nmcloota/7c95q1ov/5/
add overflow: hidden; to your parent button, so child's content will be hidden
button {
height:200px;
width:200px;
background-color:gold;
border-radius: 50%;
overflow: hidden;
}
https://jsfiddle.net/nd5po7rg/1/ I updated your fiddle
EDIT:
I applied some more styles to make text more centered
take a look: https://jsfiddle.net/1fd5rksg/19/
Hi If I understand correctly, what you're looking for is something like that:
// Show an element
var show = function (elem) {
elem.classList.add('is-visible');
};
// Hide an element
var hide = function (elem) {
elem.classList.remove('is-visible');
};
// Toggle element visibility
var toggle = function (elem) {
elem.classList.toggle('is-visible');
};
// Listen for click events
document.addEventListener('click', function (event) {
// Make sure clicked element is our toggle
if (!event.target.classList.contains('toggle')) return;
// Prevent default link behavior
event.preventDefault();
// Get the content
var content = document.querySelector(event.target.hash);
if (!content) return;
// Toggle the content
toggle(content);
}, false);
.toggle-content {
display: none;
}
.toggle-content.is-visible {
display: block;
}
button {
height:200px;
width:200px;
background-color:gold;
border-radius: 50%;
cursor: pointer;
}
.with-padding {
padding:50px;
}
<button>
<a class="toggle with-padding" href="#example">
Click me to make my friend appear/disappear
</a>
</button>
<button class="toggle-content" id="example">
I am friend</button>
I hope this will help you.

How to close a side bar when i pressed anywhere

What I want to do is to dismiss the sidebar when I press anywhere on the screen.
How can it be done? How can I make it so that when I hover over my image, my text would appear instead of it being visible the whole time?
function openNav() {
document.getElementById("mySidenav").style.width = "300px";
document.getElementById("toggle").style.position = "static";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("toggle").style.marginRight = "0";
document.getElementById("toggle").style.position = "relative";
}
#toggle {
position: relative;
left: 400px;
font-size: 1.2em;
visibility: visible;
}
#toggle:hover {
color: white;
transition: 0.5s;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
right: 0;
background-color: transparent;
overflow-x: hidden;
transition: 0.5s;
padding-top: 50px;
}
.sidenav a {
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
.sidenav a:hover,
.offcanvas a:focus {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
<div>
<ul id="topBar">
<li id="ixora">Ixora</li>
<li class="lists">2014</li>
<li class="lists">2015</li>
<li id="toggle" onclick="openNav() ">☰</li>
</ul>
</div>
<div id="mySidenav" class="sidenav">
×
<span class="textImage">Outing</span>
<img src="outing.jpg">
<span class="textImage">Prom Night</span>
<img src="prom.jpg">
<span class="textImage">PortDickson Trip</span>
<img src="pd.jpg">
<span class="textImage">Merdeka</span>
<img src="merdeka%20(2).jpg">
</div>
I honestly think you should be using jQuery here as it's fantastic for DOM manipulation. If for some reason you have to use vanilla js then it's going to be a little trickier.
Adding jQuery to your project is easy and well explained on the jQuery site. Here;s a comparison of selecting an element in js/jquery:
Vanilla JS:
document.getElementById("mySidenav")
jQuery:
$('#mySidenav')
To get things to happen when events happen (i.e. button press, or clicking away from a menu) you set up event handlers.
It's hard to picture from your code as there seems to be CSS missing for #topBar so I can't see your site very well (here's your code running in jsfiddle).
But lets say you have a button with ID of #openToggle. You would set up your sideNav in css with the correct width, height, etc, and leave it as display: none. Then we create an event handler to do something when you click that button:
//event handlers go at the bottom of your js file or script tag
$('#openMenu').on('click', openMenu);
That example is basically saying when the element with ID 'openMenu' is 'clicked' the run the 'openMenu' function - simple! :)
The openMenu function would look something like (basic example):
function openMenu() {
var $menu = $('#sideNav');
$menu.show();
};
A better way would be to have a toggle function that toggles the menu based on whether it's already open or closed:
function toggleMenu() {
var $menu = $('#sideNav');
if (($menu).is(':visible')) { //if it's visible
$menu.hide(); //hide the menu
} else { //else it's hidden
$menu.show(); //so show it
}
};
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
With regards to closing the menu when you click away from it, you could bind an event handler to the body of the page and use jQuery's .one() function (runs only once) which will detect if the body is clicked and then run the menuToggle funtion - you'd end up with 2 handlers for this:
// event handler for menu toggle button
$('#menuToggle').on('click', toggleMenu);
$('body').one('click', toggleMenu);
Alternatively you could have the menu close when your mouse pointer leaves the menu?:
//event handlers
$('#menuToggle').on('click', toggleMenu);
$('#sideNav').mouseleave(toggleMenu);
The mouseleave handler is basically saying, once the mouse pointer leaves the element with ID of 'sideNav' then run the toggleMenu function.
I'm a newb too so my examples may not be great, but I hope I helped at least a little. Hopefully some real javascript devs will be along shortly to add to this or give better examples.
Cheers,
Dave
JQuery
$( document ).onclick(function() {
$("#mySidenav").hide();
}
Reference documentation:
JQuery .on
JQuery .hide
With javascript, you can do the following:
document.onclick = function(e){
if(e.target.id == "mySidenav"){
return false;
}
closeNav();
}
I see that you already have functions to open and close your sidebar,
clicking "anywhere" is the same as "clicking on the body", But I guess that you don't want your sidebar to close when you're clicking on it.
So, here's what you can do :
var myNav = document.getElementById("mySidenav");
myNav.onclick = function(e) {
e.stopPropagation();
}
document.body.onclick = function(e) {
closeNav();
}
So, when you click on your sidebar, you won't click on the body because the event propagation is stopped, and when you click elsewhere, it will close your sidebar.
Hope it helps,
best regards

Imagemap with overlying div: Mouseover disappears on div

Could anyone give me a hint how to solve this?
Fiddle: http://jsfiddle.net/9Br6h/
Have a look at the part left under... with the flag. On the area the mouseover is visible.. but it disappears on the flag - that is the thing I want to remove. It should stay visible.
But please keep in mind that this is a very simple example. In real I've tons of areas and flags. ;o)
jQuery(document).ready(function($) {
// add div for showing dates
$('body').append('<div id="mo_termin"></div>');
// show div on mouseover
$('area').mouseover(function(event) {
var left = event.pageX + 30;
var top = event.pageY + 5;
display = '<div class="views-field-field-body">Keine Termine</div>';
$('#mo_termin').css({top: top,left: left}).html(display).show();
});
$('area').mouseout(function() {
$('#mo_termin').html('').hide();
});
});
you can use the css property pointer-events: none;as well.
#karte .flag {
pointer-events: none; /*Added line*/
position: absolute;
background: url('http://static.netzwelt.de/farcade/images/capturetheflag1.gif') no-repeat;
width: 50px;
height: 50px;
top: 200px;
left: 50px;
}
Here is the Demo http://jsfiddle.net/9Br6h/2/.
Assuming that the flag completely covers the 'hover' area underneath it, you can modify your code so that the line that sets the mouseover event reads as follows:
// show div on mouseover
$('area, .flag').mouseover(function(event) {
Here is an example: http://jsfiddle.net/9Br6h/1/

Issues with toggle, hide and show (Jquery)

I've been looking all over for a script that will take care of the following issues:
http://jsfiddle.net/k7E9V/3/
Close the div when clicking outside of it.
Close one div when the other one is clicked.
Close the div when "More info" is clicked again.
I'm wondering why the minus icon won't stay put when the div is active and also how to restore the plus icon in all the above scenarios.
The functionality of :active is different than what you have in mind. To be able to toggle the icon, first add a CSS rule like this, instead of the :active one:
a.trigger.isshown{
background:#fff url(http://icons.iconarchive.com/icons/deleket/sleek-xp-basic/24/Close-icon.png) 95% 65% no-repeat;
}
Now, you can use .toggleClass('isshown');, .removeClass('isshown'); and .addClass('isshown'); the same way you're toggling/hiding/showing div panels to change the icon as well.
Final version: jsFiddle
I made the :active selector a subclass of .trigger as #Christopher commented and fixed the behavior of the .trigger X button to toggle the class accordingly:
$('.trigger').click(function(event) {
event.preventDefault();
var panel = $(this).next('.panel');
$('.panel').not(panel).hide();
panel.toggle("fast");
$('.trigger').not(this).removeClass('active'); //remove active class from other X buttons
$(this).toggleClass('active'); //toggle the clicked button's active class
});
This way it will remove the active class from the other X buttons, and toggle the current one as requested.
To close the boxes when you click outside the .panel and .trigger, add this inside of your DOM Ready handler:
$(document).click('click', function(e) {
if (!$('.panel').is(':visible')) return;
var targ = $(e.target);
//doesn't close the boxes if target is .panel/.trigger or their descendant
if (targ.closest('.panel').length || targ.is('.panel')
|| targ.closest('.trigger').length || targ.is('.trigger')) return;
$('.panel').hide('fast');
$('.trigger').removeClass('active');
});
http://jsfiddle.net/dwZnG/
Try this out for size.
a.trigger{
position: absolute;
text-decoration: none;
bottom:0;
right: 0;
font-size: 17px;
letter-spacing:-1px;
font-family: verdana, helvetica, arial, sans-serif;
color:#333;
padding: 20px 30px 10px 15px;
font-weight: 600;
background:#fff url(http://icons.iconarchive.com/icons/deleket/sleek-xp-basic/24/Add-icon.png) 95% 65% no-repeat;
display: block;
}
/* Change active to a class name*/
a.trigger.active {
background:#fff url(http://icons.iconarchive.com/icons/deleket/sleek-xp-basic/24/Close-icon.png) 95% 65% no-repeat;
}
Then your JS:
$(document).ready(function() {
$('.trigger').click(function(event) {
event.preventDefault();
var me = $(this);
var panel = me.next('.panel');
//If active is there, remove it
if (me.hasClass("active")) {
me.removeClass("active");
}
//If it ain't...add it
else {
me.addClass("active");
}
$('.panel').not(panel).hide();
panel.toggle("fast");
$(document).ready(function() {
$('.panel').hover(function() {
mouse_inside_div = true;
}, function() {
mouse_inside_div = false;
});
$('body').mouseup(function() {
if (!mouse_inside_div) $('.panel').hide();
});
});
});
});​
Basically the same thing as Abody said. Once you have this down, you should be able to figure out the rest of the functionality.

Categories

Resources