How to fire links with jQuery? - javascript

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()
})
})

Related

in html captures click event on element that was displayed only on focus of another element

in html, sometimes I have elements that I display only when another one gain focus : you click on a button, to make another one appear.
If then you click on this newly displayed element, it disappears immediately because the focus gets away from the first one.
EDIT : And this is what I want. That could be a drop down menu for example, and I want the list to appears when clicking the title, and I want it to disappear when clicking on an element in the list.
but I also want to capture the click event before the element go away, and I can't do that ! example :
function make_action(element) {
console.log(element);
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
#buttons:focus p {
display: block;
}
#buttons p {
border: 1px solid blue;
display: none;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>
I can workaround with the use of opacity and visibility with transition :
opacity to have the ux of the instantaneous hide of the element but it's still present so you can click on it
visibility is being delayed (sort of) with the transition, so for a moment you still have the element because it's still 'visible', but for human eyes it's not visible anymore
like that :
function make_action(element) {
console.log(element);
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
#buttons:focus p {
/*
display: block;
*/
visibility: visible;
opacity: 1;
}
#buttons p {
border: 1px solid blue;
/*
display: none;
*/
opacity: 0;
visibility: hidden;
transition: visibility 0.5s;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>
but, I'm not sure it's a good practice because the element is actually still on the page, so it can impact accessibility and maybe other things.
do you know a way to capture the click on the element, before it disappears ?
what I don't understand, is the following : the buttons disappears because the div lose it's focus. But, it loses it's focus BECAUSE a click occurred on one button, so why isn't this click on the button detected ? or how is it detectable ?
You can replace you :focus with :focus-within which was created specially for this purpose.
And to do so that when clicked the elements loses focus, you can use the blur method to do so :
function make_action(element) {
console.log(element);
element.blur()
document.getElementById("output").innerHTML += `<p>detected ${element.innerHTML}</p>`;
};
#buttons {
width: 100px;
padding: 10px;
border: 1px solid black;
}
/* there is the change */
#buttons:focus-within p {
display: block;
}
#buttons p {
border: 1px solid blue;
display: none;
}
p {
margin: 5px;
padding: 0px;
}
<div id="buttons" tabindex=0>
<p onclick="make_action(this)" tabindex=0>onclick</p>
<p onfocus="make_action(this)" tabindex=0>onfocus</p>
<p onfocusin="make_action(this)" tabindex=0>onfocusin</p>
</div>
<div id="output">
</div>

'mouseenter' and 'mouseleave' event keeps triggering with div as cursor

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.

Implementing a parent selector in CSS with jQuery that applies automatically to new elements in DOM

CSS does not support parent selectors, e.g. "select all <p> that contain an <img>".
One solution proposed here is to use jQuery, for example:
$('#parent:has(#child)').addClass('my-special-class');
However, I have a <div> that is periodically updated with new content, and I need to keep reapplying the my-special-class to new elements that match the selector '#parent:has(#child)' inside that <div>.
How could one do that?
I am styling a third-party plugin so I don't have much control over its styling, events and so on.
One solution is to bind the DOMSubtreeModified event on the container div and add your code inside.
$('.container').on("DOMSubtreeModified",function(){
$('.parent:has(.child)').addClass('special-child');
});
// find elements
var parent = $("#parent")
var button = $("button")
// handle click and add class
button.on("click", function() {
const el = '<div class="parent"><p class="child">Hello World</p></div>';
parent.after(el);
})
$(function() {
$('.parent:has(.child)').addClass('special-child');
$('.continer').on("DOMSubtreeModified", function() {
$('.parent:has(.child)').addClass('special-child');
});
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.child {
background: #fff;
border-radius: 4px;
padding: 10px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 4px auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
.special-child {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="continer">
<div class="parent" id="parent">
<p class="child">Hello World</p>
</div>
</div>
<button>Add Child</button>
If you add the following jquery and just one class, it will work like :visited:
$("div.my-div").click(function(){
$(this).addClass("visited");
});
And just add one class to the css:
.visited:hover{
outline: 2px solid orange;
}
If you add this code with the current code of yours, you will get the same functionality as the one for :visited.
Here is a fiddle that I tried on your code:
https://jsfiddle.net/thisisdg/27srmuy6/

Remove shadow from a button when its active

I have a button with javascript attached. When you click the button a hidden box will appear, when you click another one, the first box gets replaced with the second and so on. When my button is active, when the box is visible, it gets a shadow around. And i donĀ“t want that! I tried to use the following css codes:
.nav > button{
width: auto;
font-family: 'OpenSansBold';
color: #000;
padding: 3px;
border: none;
margin-right: 10px;
margin-top: 5px;
font-size: 15px;
text-align: left;
background-color: #fff;
}
button:hover{
cursor: pointer;
border: none;
color: #7b1a2c;
}
button:visited{
font-family: 'OpenSansBold';
box-shadow: none;
}
button:active{
box-shadow: none;
}
But with no luck. Is there another CSS code for buttons when its active?
I have no clue about javascript, just copy pasted this thing. Maybe this is something that can be fixed in the js code? Just in case, I can show you guys:
$('div.box').slice(1).addClass('hidden');
$('.nav').children('button').on('click', function(){
// console.log('klikk');
$(this).data('content');
$('.box').not('hidden').addClass('hidden');
$( $(this).data('content')).removeClass('hidden');
});
Maybe you talk about outline property or :focus pseudo-class?
Try this one:
button:active, button:focus {
box-shadow: none;
outline: 0;
}
To give you a working example, play around with the following snippet, I think this behaves like you would want it to.
To completely remove the shadow, just remove the second JS rule.
// :active rules
$('button').on('mousedown', function () {
$(this).css('box-shadow', 'none');
});
// :visited rules
$('button').on('mouseup', function () {
$(this).css('box-shadow', '10px 10px 5px #888888');
});
button {
width: 300px;
height: 100px;
background-color: yellow;
box-shadow: 10px 10px 5px #888888;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<body>
<button>test</button>
</body>

Prevent div from showing after slideUp() - jQuery

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();
});

Categories