Disable click propagation for href - javascript

This code snippet explains my case:
$("#b").click(function(e) {
e.stopPropagation();
});
$("#b").click(function() {
alert("trigger div");
});
a {
display: block;
position: relative;
width: 100px;
height: 100px;
background-color: gray;
}
div {
position: absolute;
width: 50px;
height: 50px;
top: 0;
left: 0;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="stackoverflow.com" id="a">
<div id="b">Test</div>
</a>
The problem is that I only want to trigger the click function from the div and not the href from the a tag. In a similar question I found event.stopPropagation(), but that does not work in this case.

You need to prevent the default click event action using event.preventDefault() method.
$("#b").click(function(e) {
e.preventDefault();
alert("trigger div");
});
a {
display: block;
position: relative;
width: 100px;
height: 100px;
background-color: gray;
}
div {
position: absolute;
width: 50px;
height: 50px;
top: 0;
left: 0;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="stackoverflow.com" id="a">
<div id="b">Test</div>
</a>

$("#a").click(function (event) {
event.preventDefault();
});
$("#b").click(function (event) {
event.stopPropagation();
alert("trigger div");
});

without javascript:
#a {
display: block;
position: absolute;
width: 100px;
height: 100px;
background-color: gray;
}
div {
position: absolute;
width: 50px;
height: 50px;
background-color: red;
}
<a href="stackoverflow.com" id="a">
<div onclick="alert('trigger div')">test</div>
</a>

Related

Click function on div inside div with click function

So I wanted to know how you could stop the outer divs click function, and only have the inner divs click function be triggered. But, I want to stay using the $(document).on('click',selector) method for use in my application. I have see a few answers, but none that work with that method. Maybe An oversight by me?
$(document).ready(function() {
$('.Name').text('A veery long namemmmmmmeehhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhheeeee');
$(document).on("click", ".task", function() {
alert("click");
});
$(document).on("click", ".Name", function() {
alert("click");
});
});
.one {
height: 495px;
flex-basis: 50%;
max-width: 50%;
min-width: 35%;
position: relative;
top: 20px;
margin-right: 20px;
margin-left: 10px;
outline: solid red 1px;
}
.two {
height: 210px;
top: 20px;
position: relative;
margin-left: 10px;
margin-right: 10px;
flex-basis: 50%;
max-width: 50%;
min-width: 15%;
outline: solid red 1px;
}
.flex {
height: 100%;
width: 100%;
display: flex;
}
.Box {
cursor: pointer;
width: 85%;
padding-left: 8px;
}
.Name {
margin: 0px;
width: 85%;
max-height: 25px;
font-size: 18px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.Date {
margin: 0px;
}
.task {
width: 100%;
height: 55px;
cursor: pointer;
background-color: white;
border-top: solid #eaeaea 1px;
border-bottom: solid #eaeaea 1px;
}
.Details {
position: relative;
top: 10%;
display: inline-block;
margin-left: 15px;
width: 85%;
}
.three {
height: 210px;
top: 20px;
position: relative;
margin-left: 10px;
margin-right: 10px;
flex-basis: 50%;
max-width: 50%;
min-width: 35%;
outline: solid red 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex">
<div class="one">
one
<div class="task task-container" data-type="yes">
<div class="Details">
<div class="Box">
<p class="Name">A very long nameeeeeeeeeeeeeeeeeeeeeeeeeeeeemmmmmmmmmmmmmmmmee</p>
<p class="Date">Due: 4/10/2018</p>
</div>
</div>
</div>
</div>
<div class="two">
two
</div>
<div class="three">
three
<div class="task task-container" data-type="yes">
<div class="Details">
<div class="Box">
<p class="Name"></p>
<p class="Date">Due: 4/10/2018</p>
</div>
</div>
</div>
</div>
</div>
LINK- https://jsfiddle.net/t29ffzan/35/
First you need to capture the event within the function call:
function(event) {}
Next you call a function to stopPropagation within the function, like so:
$(document).on("click", ".Name", function(event) {
event.stopPropagation()
alert("click");
});
docs
In your second event handler, do the following:
$(document).on("click", ".Name", function(e) {
e.stopPropagation();
alert("click");
});
It will prevent the event from bubbling, i.e. being also called on parent tags.
Look here for moar info: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation.
In the click handler for the inner element, stop the click from propagating outward (bubbling up).
$(document).on("click", ".task", function() {
alert("click");
});
$(document).on("click", ".Name", function(e) {
e.stopPropagation();
alert("click");
});
https://jsfiddle.net/t29ffzan/36/

jQuery animation sticking on quick hover

If you hover over the element slowly, the animation works correctly. The green layer overlaps from the left and then, from the top, the yellow layer overlaps the green layer. This overlapping should undo itself when the mouse leaves the element, starting with undoing the yellow overlap and then the green one.
But if the cursor hovers over it too quickly, the animation gets stuck on the yellow overlap until you re-mousover and then mouseout. I've tried adding .stop(false, true) jQuery method before each of the .animate methods, which is what I read has remedied similar problems but this didn't work. I tried it by chaining it right before the .animate function, I tried just about all variations of this, on all of the functions, and also with .stop(true,true);.
Is there a way I can stop the mouseout portion from firing if the mouseover portion doesn't finish before the cursor leaves the element?
$(document).ready(function() {
$('#con').hover(
function() { // handlerIn
$('#crossX').animate({'width': '115px'}, function() {
$('#crossY').animate({'height': '115px'})
})
},
function() { // handlerOut
$('#crossY').animate({'height': '15px'}, function() {
$('#crossX').animate({'width': '15px'})
})
}
)
});
#con {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 130px;
height: 130px;
overflow: hidden;
//background-color: black;
}
#one {
width: 100px;
height: 100px;
background-color: lightgrey;
color:black
}
#crossX {
position: absolute;
top: 15px;
left: 0px;
width: 15px;
height: 100px;
background-color: green;
color: yellow;
}
#crossY {
position: absolute;
top: 0px;
left: 15px;
width: 100px;
height: 15px;
background-color: yellow;
color: white;
}
#black {
position: absolute;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
border: 15px solid black;
z-index: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="con">
<div id="one"></div>
<div id="crossX"></div>
<div id="crossY"></div>
<div id="black"></div>
</div>
With the following solution it is guaranteed that the "mouse leave part" only runs after the "mouse enter part" is fullfilled and (vice versa).
Additionally the script takes care for the case that on quick user action: "enter > leave > enter" the state remains as if the user haven't done the "quick leave". So actually this should do what you want to achieve (I hope so at least).
var mouseEnter = function() {
// console.log('in');
sPosition = 'in';
if ( !mouseEnterIsDone || !mouseLeaveIsDone ) return mouseEnterIsWaiting = true;
mouseEnterIsDone = false;
$('#crossX').animate({'width':'115px'}, function(){
$.when($('#crossY').animate({'height': '115px'})).then(function(){sanitizeAnimation('enter')})
})
},
mouseLeave = function() {
// console.log('out');
sPosition = 'out';
if ( !mouseEnterIsDone || !mouseLeaveIsDone ) return mouseLeaveIsWaiting = true;
mouseLeaveIsDone = false;
$('#crossY').animate({'height':'15px'}, function(){
$.when($('#crossX').animate({'width': '15px'})).then(function(){sanitizeAnimation('leave')})
})
},
sanitizeAnimation = function( sMode ){
if ( 'enter' == sMode )
mouseEnterIsDone = true;
else
mouseLeaveIsDone = true;
if ( 'in' == sPosition ) {
if ( mouseEnterIsWaiting ) {
mouseEnterIsWaiting = false;
mouseEnter();
}
} else {
if ( mouseLeaveIsWaiting ) {
mouseLeaveIsWaiting = false;
mouseLeave();
}
}
},
mouseEnterIsDone = true,
mouseLeaveIsDone = true,
mouseEnterIsWaiting = false,
mouseLeaveIsWaiting = false,
sPosition = 'out';
$(document).ready(function(){
$('#con').hover(mouseEnter, mouseLeave);
});
body {
padding: 5%;
}
#con {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 130px;
height: 130px;
overflow: hidden;
//background-color: black;
}
#one {
width: 100px;
height: 100px;
background-color: lightgrey;
color:black
}
#crossX {
position: absolute;
top: 15px;
left: 0px;
width: 15px;
height: 100px;
background-color: green;
color: yellow;
}
#crossY {
position: absolute;
top: 0px;
left: 15px;
width: 100px;
height: 15px;
background-color: yellow;
color: white;
}
#black {
position: absolute;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
border: 15px solid black;
z-index: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="con">
<div id="one"></div>
<div id="crossX"></div>
<div id="crossY"></div>
<div id="black"></div>
</div>
If you need further explanations feel free to leave a comment
$("#con").mouseenter(function() {
$('body').addClass('Hover');
$('#crossX').stop().animate({'width':'115px'},500, function(){
$('#crossY').stop().animate({'height': '115px'},500);
});
});
$("body").mouseenter(function() {
$('body').addClass('Hover');
$('#crossY').stop().animate({'height':'0px'},500,function(){
$('#crossX').stop().animate({'width':'0px'},500);
});
});
#con {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 130px;
height: 130px;
overflow: hidden;
//background-color: black;
}
#one {
width: 100px;
height: 100px;
background-color: lightgrey;
color:black
}
#crossX {
position: absolute;
top: 15px;
left: 0px;
width: 15px;
height: 100px;
background-color: green;
color: yellow;
}
#crossY {
position: absolute;
top: 0px;
left: 15px;
width: 100px;
height: 15px;
background-color: yellow;
color: white;
}
#black {
position: absolute;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
border: 15px solid black;
z-index: 10;
}
body{
background-color:#dcdcdc;
height:500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="con">
<div id="one"></div>
<div id="crossX"></div>
<div id="crossY"></div>
<div id="black"></div>
</div>
</body>

Mouseover Mouseout with overlapping content

When I mouseover the div with class=background (the little green square in the demo) I fade in the div with class=hover (displaying the grey and blue divs in the demo).
The grey partially overlaps the .background and I can move the mouse around inside it without triggering the mouseout on .background.
But..
If I move the mouse outside the grey div (to hover over the blue for example) then the mouseout on .background gets triggered.
How can I prevent this from happening so that as long as I am hovering over the newly displayed .hover div the mouseout on '.background' will not be triggered?
$('.AddDiv').on('click', function() {
var html = '<div class="container"><div class="background"></div><div class="hover"></div></div>';
$('.Wrap').prepend(html);
});
$(".Wrap").on("mouseover", ".background", function() {
$(this).next(".hover").fadeIn(500);
});
$(".Wrap").on("mouseout", ".hover", function() {
$(this).fadeOut(200);
});
.Wrap {
width: 650px;
height: 800px;
}
.container {
position: relative;
top: 5px;
left: 5px;
width: 200px;
height: 200px;
background-color: red;
float: left;
margin-left: 5px;
margin-top: 5px;
}
.AddDiv {
position: absolute;
top: 0px;
}
.background {
width: 20px;
height: 20px;
background-color: green;
position: absolute;
left: 170px;
top: 10px;
}
.content {
width: 170px;
height: 120px;
background-color: grey;
position: relative;
left: 15px;
top: 15px;
}
.navigation {
width: 190px;
height: 40px;
background-color: blue;
position: relative;
top: 30px;
left: 5px;
}
.hover {
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 0.8);
position: absolute;
z-index: 1001;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Wrap">
<div class="container">
<div class="background"></div>
<div class="hover">
<div class="content"></div>
<div class="navigation"></div>
</div>
</div>
</div>
<button class=AddDiv>AddDiv</button>
Use mouseleave instead of mouseout:
$('.AddDiv').on('click', function() {
$('.Wrap').prepend($('<div class="container"><div class="background"></div><div class="hover"></div></div>'));
});
$(".Wrap").on("mouseover", ".background", function () {
$(this).next(".hover").fadeIn(500);
});
$(".Wrap").on("mouseleave", ".hover", function () {
$(this).fadeOut(200);
});

How to catch event on a parent div?

I would like to ask:
How to make the group displays OVER the divs a and b?
I want to catch event mousedown on group even if a user click on a div a or b.
Basically the group should visually cover the two other divs, so when I click inside the are covered by the group, only group div should detect mousedown.
Notes: I cannot change HTML structure.
document.getElementById('group').addEventListener('click', function(event) {
event.stopPropagation();
alert('click on: ' + event.target.id);
});
#group {
position: absolute;
width: 250px;
height: 250px;
background-color: yellow;
z-index: 2;
opacity: 0.5;
}
#a {
position: absolute;
left: 80px;
width: 50px;
height: 50px;
margin: 10px;
background-color: blue;
z-index: 0;
}
#b {
position: absolute;
width: 50px;
height: 50px;
margin: 10px;
background-color: blue;
z-index: 0;
}
<div id="group">
<div id="a">A</div>
<div id="b">B</div>
</div>
Use opacity 0 for the children.
Use event.currentTarget instead of event.target.
With this config children are actually above groups, but are not visible and events are caught by groups elem, not children.
document.getElementById('group').addEventListener('click', function(event) {
event.stopPropagation();
alert('click on: ' + event.currentTarget.id);
});
#group {
position: relative;
width: 250px;
height: 250px;
background-color: yellow;
z-index: 2;
opacity: 0.5;
}
#a {
position: relative;
left: 80px;
width: 50px;
height: 50px;
margin: 10px;
background-color: blue;
z-index: 0;
opacity: 0
}
#b {
position: relative;
width: 50px;
height: 50px;
margin: 10px;
background-color: blue;
z-index: 0;
opacity: 0;
}
<div id="group">
<div id="a">A</div>
<div id="b">B</div>
</div>

Menu error caused by HTML or JS?

Im trying to get the menu to be horizontal and then the flags to be shown below the menu when you press the flag-name.
When doing changes to the menu in my code, which of my files should I be editing?
The flags location is correct right now, but the menu is missplaced.
What can be done to get the menu to be horizontal instead of a list?
JSFiddle: http://jsfiddle.net/528k9z8m/
HTML:
<body>
<h1>Kmom03 sandboxen</h1>
<div id="content">
<div id="menu">
<ul>
<li> Elfenbenskusten
<div id="flag-elfenbenskusten"></div>
</li>
<li> Sverige
<div id="flag-sverige"></div>
</li>
<li> Maruritius
<div id="flag-maruritius"></div>
</li>
<li> Japan
<div id="flag-japan"></div>
</li>
</ul>
</div>
</div>
<script type="text/javascript" src="js/main.js"></script>
CSS
body {
}
h1 {
text-align: center;
}
h3 {
color: green;
}
#menu {
width: 500px;
height: 50px;
border: 1px solid black;
}
#content {
border: 1px solid black;
background-color: #eee;
padding: 4em;
margin: 0 auto;
height: 800px;
width: 800px;
border-radius: 30px;
}
.flagga1 {
position: relative;
width: 800px;
height: 500px;
}
.sverige {
background-color: #FECC00;
}
.sverige .box1 {
position: absolute;
width: 250px;
height: 200px;
background-color: #006AA7;
}
.sverige .box2 {
position: absolute;
bottom: 0;
left: 0;
width: 250px;
height: 200px;
background-color: #006AA7;
}
.sverige .box3 {
position: absolute;
top: 0;
right: 0;
width: 425px;
height: 200px;
background-color: #006AA7;
}
.sverige .box4 {
position: absolute;
bottom: 0;
right: 0;
width: 425px;
height: 200px;
background-color: #006AA7;
}
.flag {
position: relative;
width: 300px;
height: 200px;
}
.elfenbenskusten {
background-color: #fff;
}
.elfenbenskusten .part1 {
width: 100px;
height: 200px;
background-color: #F77F00;
}
.elfenbenskusten .part2 {
position: absolute;
top: 0;
left: 200px;
width: 100px;
height: 200px;
background-color: #009e60;
}
.flagga2 {
position: relative;
width: 300px;
height: 200px;
}
.maruritius {
background-color: #EEE;
}
.maruritius .box1 {
position: absolute;
top: 0;
width: 300px;
height: 50px;
background-color: #EA2839;
}
.maruritius .box2 {
position: absolute;
top: 50px;
left: 0;
width: 300px;
height: 50px;
background-color: #1A206D;
}
.maruritius .box3 {
position: absolute;
top: 100px;
width: 300px;
height: 50px;
background-color: #FFD500;
}
.maruritius .box4 {
position: absolute;
bottom: 0;
right: 0;
width: 300px;
height: 50px;
background-color: #00A551;
}
.maruritius .box5 {
position: absolute;
bottom: 0;
right: 0;
background-color: #006AA7;
}
.flagga3 {
position: relative;
height: 200px;
width: 300px;
border-style: solid;
border-width: 1px;
border-color: black;
}
.japan .box1 {
background-color: #FFFFFF;
}
.japan .cirkel1 {
border-radius: 50%;
position: absolute;
top: 40px;
left: 90px;
width: 125px;
height: 125px;
background-color: #BC002D;
}
JS:
(function () {
'use strict';
//var myContent = document.getElementById('content');
//elfenbenskusten
var flagTarget = document.getElementById('flag-elfenbenskusten');
var flagLink = document.getElementById('draw-elfenbenskusten');
function drawFlagElfenbenskusten() {
var flagElfenbenskusten = '<div class="flag elfenbenskusten"><div class="part1"></div><div class="part2"></div></div>'
flagTarget.innerHTML = flagElfenbenskusten;
}
flagLink.addEventListener("click", function () {
console.log("event for clicking link elfenbenskusten.")
drawFlagElfenbenskusten();
});
//sverige
var flagTargetSverige = document.getElementById('flag-sverige');
var flagLinkSverige = document.getElementById('draw-sverige');
function drawFlagSverige() {
var flagSverige = '<div class="flagga1 sverige"><div class="box1"></div><div class="box2"></div><div class="box3"></div><div class="box4"></div></div>'
flagTarget.innerHTML = flagSverige;
}
flagLinkSverige.addEventListener("click", function () {
console.log("event for clicking link elfenbenskusten.")
drawFlagSverige();
});
//maruritius
var flagTargetMaruritius = document.getElementById('flag-maruritius');
var flagLinkMaruritius = document.getElementById('draw-maruritius');
function drawFlagMaruritius() {
var flagMaruritius = '<div class="flagga2 maruritius"><div class="box1"></div><div class="box2"></div><div class="box3"></div><div class="box4"></div><div class="box5"></div></div>'
flagTarget.innerHTML = flagMaruritius;
}
flagLinkMaruritius.addEventListener("click", function () {
console.log("event for clicking link elfenbenskusten.")
drawFlagMaruritius();
});
//japan
var flagTargetJapan = document.getElementById('flag-japan');
var flagLinkJapan = document.getElementById('draw-japan');
function drawFlagJapan() {
var flagJapan = '<div class="flagga3 japan"><div class="box1"></div><div class="cirkel1"></div></div>'
flagTarget.innerHTML = flagJapan;
}
flagLinkJapan.addEventListener("click", function () {
console.log("event for clicking link elfenbenskusten.")
drawFlagJapan();
});
})();
#menu li {
list-style-type: none;
float: left;
margin-right: 10px;
position: relative;
}
#menu ul li>div {
position: absolute;
top: 20px;
}
Fiddle
Guess it's what you want to achieve
you have to edit the css, try this:
ul {
float: left;
width: 100%;
}
a {
float: left;
width: 6em;
text-decoration: none;
padding: 0.2em 0.6em;
}
li {
display: inline;
}

Categories