I'm trying to make a small piece of code, so when I click on the question mark, it shows another div. However, when I click on the body, it should hide the just revealed div.
The problem I am running into, is that even though I use .slideUp() when the person clicks on the body (note: the body is only clickable on the height of the ?), it also shows after clicking on the body again. How do I make it so clicking on body won't show the .popover again? If I add .hide() after .slideUp(), it just hides it directly and the slideUp effect is gone.
CodePen
HTML
<div class="center">
<span class="qs">? <span class="popover above">Voeg toe aan wensenlijst</span></span>
</div>
CSS
body {
background-color: #e3fbff;
}
/* Just to center things */
.center {
margin: 100px auto;
width: 30px;
}
/* The element to click on */
.qs {
background-color: #02bdda;
border-radius: 16px;
color: #e3fbff;
cursor: default;
display: inline-block;
font-family: 'Helvetica',sans-serif;
font-size: 18px;
font-weight: bold;
height: 30px;
line-height: 30px;
position: relative;
text-align: center;
width: 30px;
.popover {
background-color: rgba(0,0,0,0.85);
border-radius: 5px;
top: 42px;
box-shadow: 0 0 5px rgba(0,0,0,0.4);
color: #fff;
font-size: 12px;
display:none;
font-family: 'Helvetica',sans-serif;
left: -95px;
padding: 7px 10px;
position: absolute;
width: 200px;
z-index: 4;
}
}
jQuery
$(".qs").click(function(){
$(".popover ").slideToggle();
});
$('body').click(function() {
// Hide all hidden content
$('.popover').slideUp();
});
$('.popover').click(function(e) { e.stopPropagation() });
$('.qs').click(function(e) {
// this stops the event from then being caught by the body click binding
e.stopPropagation();
});
Hide the tooltip when clicking, if it is visible.
You don't need more code than this:
var popover = $('.popover');
var qs = $('.qs');
qs.click(function(e){
e.stopPropagation();
popover.slideToggle();
});
$('html').click(function() {
if(popover.is(':visible')) {
popover.slideUp();
}
});
$('.popover').click(function(e) { e.stopPropagation() });
Codepen
You can check if .popover is visible like:
$('body').click(function() {
// Hide all hidden content
if($('.popover').is(":visible"))
$('.popover').slideUp();
});
Also you don't need to use slideup() and hide() together.
codepen
You need to make sure the popup is not click on you can do a check like this
var mouse_is_inside = false;
$('.popover').hover(function() {
mouse_is_inside=true;
}, function() {
mouse_is_inside=false;
});
$("body").live('mouseup', function() {
if(! mouse_is_inside)
$('.popover').slideUp();
});
Related
I want to fire a link if the div around gets clicked.
This is the general logic:
$("div").click(function() {
$("div a").click();
});
div {
background-color: yellow;
padding: 20px;
margin: 10px;
}
div:active {
background-color: blue;
}
div a {
pointer-events: none;
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>London</div>
<div>Paris</div>
<div>Almaty</div>
Unfortunately, it does not work. I think I would need the different href as variable or something like that. For now, probably all links would be fired at the same time, and not only the belonging one.
How is it possible to do that?
Would be thankful for help! <3
If your code would work, you would end up clicking every link that is in side of a div. It is not going to just click the link in the div you are in. So first thing you need to do is select the link in the div you clicked.
After that, you need to trigger click on the DOM element, not the jQuery object. When you trigger it on the jQuery object, it only triggers the click event listeners you bound to it.
$("div").click(function() {
$(this).find("a").get(0).click();
});
div {
background-color: yellow;
padding: 20px;
margin: 10px;
}
div:active {
background-color: blue;
}
div a {
pointer-events: none;
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>London</div>
<div>Paris</div>
<div>Almaty</div>
Or just make the anchor take up the whole div so you do not need JavaScript at all.
div {
background-color: yellow;
margin: 10px;
}
div:active {
background-color: blue;
}
div a {
padding: 20px;
display :block;
width: 100%;
height: 100%;
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>London</div>
<div>Paris</div>
<div>Almaty</div>
You can select the <a> of the clicked div by selecting the first <a> children of the this clicked element.
$("div").click(function() {
$(this).children('a')[0].click();
});
div {
background-color: yellow;
padding: 20px;
margin: 10px;
}
div:active {
background-color: blue;
}
div a {
pointer-events: none;
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>London</div>
<div>Paris</div>
<div>Almaty</div>
Add an event listener to the elements you are clicking, and in the "onclick" callback, select the a element and click it.
Array.from(document.getElementsByTagName("div")).forEach(e=>{
e.addEventListener("click",(el)=>{
el.target.querySelector("a").click()
})
})
I made a 'custom cursor' by hiding the users cursor and displaying a div where the original cursor would normally be displayed on the screen.
Now the problem is I'd like to add some animations when hovering over an element (e.g. scale the 'cursor', or in this case the div that acts as the cursor).
In this example I made a button, and gave it a 'mouseenter' and 'mouseleave' event.
When you enter the button with your cursor, I console.log("enter");
When you leave the button, console.log("leave");
You can quickly see the problem: the two events are being triggered numerous times when hovering over the button, while the cursor is not actually leaving the element.
Also note that this problem doesn't occur when you're very slowly hovering to the left, or to the top (in a straight line), which is probably because of the 'left: e.pageX and top: e.pageY' piece of code in the script.
What can you do to fix this so the two events trigger properly?
$(document).ready(function() {
var cursor = $(".cursor");
/* Cursor */
$(document).on("mousemove", function(e) {
cursor.css({
left: e.pageX,
/*Or clientX and clientY */
top: e.pageY,
});
});
/* Button */
$(".btn").on("click", function(e) {
e.preventDefault();
});
$(".btn").on("mouseenter", function() {
console.log("entered");
});
$(".btn").on("mouseleave", function() {
console.log("left");
});
});
* {
cursor: none;
}
.cursor {
width: 10px;
height: 10px;
border-radius: 50%;
position: absolute;
background-color: black;
}
.btn {
text-decoration: none;
font-family: sans-serif;
font-weight: bold;
text-transform: uppercase;
color: black;
background-color: white;
border: 4px solid black;
padding: 0.5rem 0.8rem;
display: inline-block;
margin: 100px 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<!--Button-->
<div class="center marginB">
<a id="startChat" class="btn">Button</a>
</div>
<!--Cursor-->
<div class="cursor"></div>
Add pointer-events: none to your .cursor to make the cursor (black dot) never a target of any mouse events, and so it will never affect the mouse enter and mouse leave events. You can read more about pointer events here
See working example below:
$(document).ready(function() {
var cursor = $(".cursor");
/* Cursor */
$(document).on("mousemove", function(e) {
cursor.css({
left: e.pageX,
/*Or clientX and clientY */
top: e.pageY,
});
});
/* Button */
$(".btn").on("click", function(e) {
e.preventDefault();
});
$(".btn").on("mouseenter", function() {
console.log("entered");
});
$(".btn").on("mouseleave", function() {
console.log("left");
});
});
* {
cursor: none;
}
.cursor {
width: 10px;
height: 10px;
border-radius: 50%;
position: absolute;
background-color: black;
pointer-events: none;
}
.btn {
text-decoration: none;
font-family: sans-serif;
font-weight: bold;
text-transform: uppercase;
color: black;
background-color: white;
border: 4px solid black;
padding: 0.5rem 0.8rem;
display: inline-block;
margin: 100px 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--Button-->
<div class="center marginB">
<a id="startChat" class="btn">Button</a>
</div>
<!--Cursor-->
<div class="cursor"></div>
The problem is because there is a delay between the actual hidden cursor being moved by the user and the .cursor element moving to match its position, simply due to the performance of JS. As such the real cursor can, for a split second, go outside the bounds of .cursor and cause a mouseenter on the underlying button. The .cursor is then moved and the actual cursor then causes a mouseleave on the button as it's now over the .cursor element.
The simplest workaround would be to use CSS to set the cursor style to an image which matches the dot, as it performs far better than JS:
$(document).ready(function() {
$(".btn").on("click", function(e) {
e.preventDefault();
});
$(".btn").on("mouseenter", function() {
console.log("entered");
});
$(".btn").on("mouseleave", function() {
console.log("left");
});
});
* {
cursor: url('https://i.imgur.com/SyBk5p5.png'), auto;
}
.cursor {
width: 10px;
height: 10px;
border-radius: 50%;
position: absolute;
background-color: black;
}
.btn {
text-decoration: none;
font-family: sans-serif;
font-weight: bold;
text-transform: uppercase;
color: black;
background-color: white;
border: 4px solid black;
padding: 0.5rem 0.8rem;
display: inline-block;
margin: 100px 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="center marginB">
<a id="startChat" class="btn">Button</a>
</div>
You should be able to do this with just pure CSS.
Since the div that houses your button and cursor are both part of the body they are siblings of the same container. You could use this to detect the hover on the button and then in turn change the styles of the cursor.
.marginB:hover ~ .cursor { background-color: yellow; }
https://jsfiddle.net/4nrtgx8o/
EDIT: If you remove your 100px margins from your button the hover effect wouldn't happen until you actually hover on the button. With your current CSS the button itself appears much smaller than the space it actually occupies as a piece of code. That's why the hover action happens before actually reaching the button.
I want some action to be performed when the child element .menuitems is hovered. Currently I've replaced the action with an alert to make it simple.
Now the problem is that when I use selector ("#result_row .menuitems"), nothing works. But if I use ("#result_row"), it works fine i.e., alert works.
Why is it so? It should work in both cases? I want the hover to work on child as well as grandchilds (.menu1).
Here's my code:
HTML
<div id="result_row"><div class="menuitems">
<div class="menu1">sfsdsf<span id="srno">4</span></div>
<div class="menu2">sfsdfs#saf</div>
<div class="menu3">sdfsdf<span id="cross">X</span></div>
<div class="clear"></div>
</div>
</div>
CSS
.menuitems{
margin-bottom: 5px;
background: #007fad;
}
.resultmenu > .menuitems{
background: #004068;
}
.menuitems div{
background: #00aeef;
color: white;
font-family: sans-serif;
text-align: center;
font-size: 14px;
padding-top: 3px;
padding-bottom: 3px;
position: relative;
}
.menu1{
float: left;
width: 25%;
margin-right: 2px;
}
.menu2{
float: left;
width: 40.4%;
}
.menu3{
float: right;
width: 34%;
}
.clear{
clear: both;
padding: 0 !important;
}
JavaScript
$(document).ready(function(){
$("#result_row .menuitems").hover(function(){
//var tarparent=$(event.target).parent().find("#cross");
//$(tarparent).toggle();
alert("Hello");
});
});
NOTE: This code won't render fine as it is missing many other styles, parent elements etc. So I've put a screenshot to describe the problem.
Red rectangle is .result_row. Green is child, .menuitems.
EDIT:
If you want to know something else, here it is: when I use .menuitems:hover in CSS (not jQuery), the hover works.
EDIT2:
One more thing that can be important to you while answering is: The window "EMAIL" you're seing in this image is no loaded when open the main page(site). It is loaded only when I click a button on the page, and the content you're seeing in 2nd and 3rd row are loaded ALONG WITH IT, i.e., they're not static!
I entered everything you had into jsfiddle and it worked (hit F12 to see console.log)
https://jsfiddle.net/bLjmocza/
I also replaced
$("#result_row .menuitems").hover(function(){
with
$(".menuitems").hover(function(){
as that seemed to be more what you were trying to achieve in the first place
use this code:
$(document).ready(function(){
$("#result_row .menuitems").mouseover(function(){
alert("Hello");
});
});
Your problem is float in your CSS. See: http://wtfhtmlcss.com/#floats-computed-height.
The quick and diry fix ist to float the parent. But you are better off applying a clearfix to the parent. The added bonus is you can then get rid of your clear div.
Below is clearfix option:
$(document).ready(function(){
$("#result_row .menuitems").hover(function(){
//var tarparent=$(event.target).parent().find("#cross");
//$(tarparent).toggle();
alert("Hello");
});
});
.menuitems{
margin-bottom: 5px;
background: #007fad;
}
.resultmenu > .menuitems{
background: #004068;
}
.menuitems div{
background: #00aeef;
color: white;
font-family: sans-serif;
text-align: center;
font-size: 14px;
padding-top: 3px;
padding-bottom: 3px;
position: relative;
}
.menu1{
float: left;
width: 25%;
margin-right: 2px;
}
.menu2{
float: left;
width: 40.4%;
}
.menu3{
float: right;
width: 34%;
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix { display: inline-block; }
/* start commented backslash hack \*/
* html .clearfix { height: 1%; }
.clearfix { display: block; }
/* close commented backslash hack */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result_row"><div class="menuitems clearfix">
<div class="menu1">sfsdsf<span id="srno">4</span></div>
<div class="menu2">sfsdfs#saf</div>
<div class="menu3">sdfsdf<span id="cross">X</span></div>
</div>
</div>
Updated: This won't work in jQuery 1.9 onwards!
http://api.jquery.com/on/#additional-notes. Use mouseenter/mouseleave instead
A second anser as this one addresses binding handlers to dynamic elements
As you are dynamically adding elements to the page you want to use jquery's on method
Change gour jquery to
$(document).ready(function(){
$("#result_row").on(".menuitems", "hover", function(){
//var tarparent=$(event.target).parent().find("#cross");
//$(tarparent).toggle();
alert("Hello");
});
});
The main difference is this will attatch the hover event handler any child of resultrow with a class of menuitems that exist now or that are added later.
Say I have divA that partially overlaps divB. How can I allow clicks on divA to pass through to divB but still have hover fired when hovering over divA?
I'm aware of pointer-events:none; and this makes the clicks pass through but it also prevents the hover.
I have also tried the below, but it did not allow clicks to fall through
$(document).on('click', '.feedback-helper', function(e){
e.preventDefault();
})
Picture the relation of the divs like:
Here is the why of it (read as: "let's avoid an X Y problem"):
I'm working on an implementation of feedback.js
To see the issue:
view the feedback.js demo
click the feedback button in the bottom right
draw a box on the screen to highlight a section
click the "black out" button
try to draw a box inside the first box you can't because the click is blocked by the first box
I need to allow drawing a blackout box over a highlighted area but if I set pointer-events:none; I will lose other hover functionality I have on those elements.
Here is a jsFiddle example
All solutions welcome
I checked your example page and if you set a slightly lower z-index on data-type="highlight" that could take care of the problem, try a z-index of 29990 in comparison to your current 30000. This should allow you to target the highlighted feedback area and overlay it with the blackout elements.
You could get the click event for the overlaying element to initiate the click event for the underlying element.
Native JS Example:
document.getElementById('divA').addEventListener('click', function() {
alert('Clicked A');
});
document.getElementById('divB').addEventListener('click', function() {
var event = document.createEvent('HTMLEvents');
event.initEvent('click', true, false);
document.getElementById('divA').dispatchEvent(event);
});
div {
cursor: pointer;
border: 1px solid black;
}
#divA {
height: 300px;
width: 300px;
background: whitesmoke;
}
#divB {
height: 30px;
width: 30px;
background: grey;
position: absolute;
left: 100px;
top: 100px;
}
#divB:hover {
background: green;
}
<div id="divA"></div>
<div id="divB"></div>
jQuery Example:
$('#divA').on('click', function() {
alert('Clicked A');
});
$('#divB').on('click', function() {
$('#divA').trigger('click');
});
div {
cursor: pointer;
border: 1px solid black;
}
#divA {
height: 300px;
width: 300px;
background: whitesmoke;
}
#divB {
height: 30px;
width: 30px;
background: grey;
position: absolute;
left: 100px;
top: 100px;
}
#divB:hover {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divA"></div>
<div id="divB"></div>
Another option is to use a pseudo element instead. Perhaps that will do what you need.
$('#toggleBlack').on('click', function() {
$('#divA').toggleClass('hidden');
});
div {
border: 1px solid black;
}
#divA {
background: whitesmoke;
position: relative;
}
#divA.hidden:before {
position: absolute;
content: ' ';
top: 0;
left: 0;
right: 0;
bottom: 0;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divA">Highlight the text once I'm hidden and cut/copy/drag</div>
<br />
<br />
<button id="toggleBlack">Toggle Hidden</button>
I have html:
<div>
<div id='icon_zoom_in' class='icon'>+</div>
<div id='icon_zoom_out' class='icon'>-</div>
</div>
And I add CSS:
.icon{
color: white;
font-size: 100px;
background-color: black;
opacity: 0.7;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
width: 70px;
height: 70px;
text-align: center;
line-height: 50px;
cursor: pointer;
}
The result is nice (ignore the font, I installed a Chrome extension):
But when I add click event on their "buttons", strange things happen:
var $ = function(id) {
return document.getElementById(id);
}
$("icon_zoom_in").addEventListener("click", function() {
console.log("zoom in");
}, false);
$("icon_zoom_out").addEventListener("click", function() {
console.log("zoom out");
}, false);
When I click the "+" button, I got zoom out! I have to click the outer space of it to get zoom in.
jsfiddle: http://jsfiddle.net/wong2/w2dRB/
Super simple: in Chrome the text is overflowing. Actually when you click the plus you are clicking the minus because of this. Use overflow: hidden; and the plus and minus will stick inside the buttons.
Here (JSFiddle) you can test the correct behaviour.