React link OnClick prevent href - html

I have a link with a href and onClick function.
<a href={menuItem.url} onClick={e => {
var checkedItems = document.querySelectorAll("input:checked") as NodeListOf<HTMLInputElement>;
for (let i = 0; checkedItems[i]; i++) {
checkedItems[i].checked = false;
}
window.location.href = menuItem.url; }}>
I want the href link the be there so users can see the url when hovering, but I want only the onclick to be executed.
I have tried
e.stopPropagation();
e.preventDefault();
e.nativeEvent.stopImmediatePropagation();
return false;
But none of those seem to work.

One solution would be to add a new "internal element" such as a <span> inside of the <a> element, and bind the onClick event handler with event.stopPropagation() to that internal element.
This would cause the <span> to intercept and stop the propagation of the click event before it bubbles up to the parent <a> (which would by default cause the browser to navigate to the href url).
You should find this method still preserves visibility of the url assigned to the href attribute of <a> for the user when it is hovered with the mouse cursor:
<a href={menuItem.url}>
<span onClick={e => {
// Intercepts and prevents the event from propagating up to the parent <a>
e.stopPropagation();
// Your existing logic for the onClick event
var checkedItems = document.querySelectorAll("input:checked") as NodeListOf<HTMLInputElement>;
for (let i = 0; checkedItems[i]; i++) {
checkedItems[i].checked = false;
}
window.location.href = menuItem.url;
}}> The text label for your link </span>
</a>
For this method to work, it assumed that there is no padding between the box border (outer boundary) of the <a> and the box border of the inner <span>. Here's a jsFiddle (non-jsx) demonstrating the general idea.
Hope that helps!

Related

How do I create 3 buttons that change the webpage background to red, green, or blue on-click in HTML?

I'm trying to create a webpage where there are three working buttons that are labelled "Red", "Green", and "Blue". When the user clicks on one of the buttons, the entire webpage should change to the color of the specific button that was clicked.
This is what I have so far, but I'm pretty sure I'm doing something wrong:
function myFunction() {
document.getElementById("H1").style.color = "#ff0000";
}
<h1 id="H1">H1</h1>
<button type="button" onclick="myFunction()">Set H1 to Red</button>
We begin with creating three radio buttons named red, green, blue inside the form tag and use attribute named on Click and assign value document. bgcolor=color name to it.
There is only one problem here that you changed color but you want to change background color.
Hope this will help you.
function myFunction() {
document.body.style.backgroundColor = "#ff0000";
}
onClick the button will invoke the changeColor function which will take the innerText
of the button as style value and set it as background color of the body.
function changeColor (element){
document.body.style.backgroundColor = element.innerText
}
console.log(document.body.style.backgroundColor)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button onclick="changeColor(this)" >Red</button>
<button onclick="changeColor(this)" >Green</button>
<button onclick="changeColor(this)" >Blue</button>
</body>
</html>
You can also use class or id selector to select the element instead of using tag name.
const element = document.getElementsByClassName(".class")
In this case the element will be an array of nodes that have the same class. You can use forEach loop to trigger color change on all of them.
or use an Id if the target is a single element.
const element = document.getElementById("id")
You can also use onclick event listener to change the color.
First the "problems," which I'm not convinced are problems since clicking the <button> does exactly what the <button> says – in its text – that it will do. However:
function myFunction() {
// as the button-text implies this JavaScript retrieves
// the element with the id of 'H1', and updates its
// CSS - via the inline style element - to the colour
// of '#ff0000' (or '#f00'), which is red.
document.getElementById("H1").style.color = "#ff0000";
}
<h1 id="H1">H1</h1>
<!-- Obviously you know that this element is intended to set
the colour of the <h1> element, given the text of the
<button>; also you're using an inline event-handler
(the 'onclick' attribute) to bind a function to an event,
which is considered bad practice due to the obtrusive
nature of the event-binding, and difficulty of updating
function calls: -->
<button type="button" onclick="myFunction()">Set H1 to Red</button>
To do as you ask, and instead set the background-color of a given element, we must:
retrieve that element in the JavaScript,
update the correct – background-color – property,
find a means by which the <button> can "communicate" the correct value to which that property must be set, and ideally
use unobtrusive JavaScript to bind the function to the 'click' event.
To do that:
// assigning a meaningful name to the function
// in order to make future maintenance easier:
function setBackgroundColor(evt) {
// retrieving the element we wish to style:
const body = document.querySelector('body')
// accessing the style interface, and
// updating the background-color, via the
// JavaScript camelCased property-name:
body.style.backgroundColor = evt.currentTarget.value;
}
// retrieving the <button> elements:
const buttons = document.querySelectorAll('button');
// iterating over that NodeList of <button>
// elements, using NodeList.prototype.forEach():
buttons.forEach(
// using an Arrow function, passing in a reference
// to the current Node of the NodeList over which
// we're iterating. Here we use the
// EventTarget.addEventListener() method to bind the
// setBackgroundColor() functiona as the 'click'
// event-handler when the node is clicked (also fired
// on keyboard navigation if the user hits spacebar
// or enter):
(node) => node.addEventListener('click', setBackgroundColor)
)
<h1 id="H1">H1</h1>
<!-- here we're adding a "value" attribute to hold
the colour to set; we're using a colour-name
('red'), a hexadecimal ('#87cefa'), and
a hsl() ('120deg 93% 80%') value as the colour: -->
<button type="button" value="red">Red</button>
<button type="button" value="#87cefa">Blue</button>
<button type="button" value="hsl(120deg 93% 80%)">Red</button>
There is, of course, an alternative and that's to use a colour-picker <input>, which allows the user to pick any colour of their choice and simply pass the chosen value to the function:
// assigning a meaningful name to the function
// in order to make future maintenance easier:
function setBackgroundColor(chosenColor) {
// caching the <body> element:
const body = document.querySelector('body');
// updating the background-color via the
// 'style' interface:
body.style.backgroundColor = chosenColor;
}
// retrieving the <input> element with a type-attribute
// equal to "color":
const input = document.querySelector('input[type=color]');
// using EventTarget.addEventListener() to use the anonymous
// function to call the setBackgroundColor() function, passing
// the value of the evt.currentTarget node (the color <input>)
// as the argument:
input.addEventListener('change', (evt)=> setBackgroundColor(evt.currentTarget.value));
<h1 id="H1">H1</h1>
<input type="color">
References:
Arrow functions.
CSSStyleDeclaration.
document.querySelector().
document.querySelectorAll().
EventTarget.addEventListener().

icon not clickable with onclick event

The onclick event only works with the button. If I click on the icon in the button the function does not work.
enter code here
<div class="dropdown">
<button onclick="myFunction()" class="elementor-button-link elementor-button elementor-size-md elementor-animation-grow" id="dropbtn">
<i onclick="myFunction() "class="far fa-arrow-alt-circle-down">
<script>/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('#dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
enter code here
Short answer: Try using element.closest() instead of element.matches().
I suspect it's the condition in your if statement. By the looks of it, element.matches() will match exactly the ID provided - I.e., it'll match if the element clicked on has that ID, but not if you click on a child element that does not explicitly have the ID, even if the parent does.
According to Mozilla web docs, element.closest() should also match any elements whose parents match the condition provided, even if the element itself doesn't.
Bear in mind this will change the type of the returned value - matches() returns a boolean, while closest() returns the 'closest' element matching the condition.

JQuery populate div with link content but also need to move (like anchor link) to area where div located

I have unordered list of links. Using JQuery, when clicked, the link's contents (a div with image and text) are loaded into the section specified. This all works beautifully. But I'm wondering how to also get the onclick function to move the view to the div's location on the page similarly to how anchor tag works. Here is the site where you can see the div being populated, but not moving down to view it. https://www.thecompassconcerts.com/artists.php
My JQuery knowledge is not awesome (I'm being generous).
I followed Osama's suggestion to add event listener and I got almost correct results. Upon first click...contents are loaded but do not move. But on every successive click, it functions perfectly: Contents loaded and move to div (like an anchor link) works! BUT...not on Safari or Mobile Safari.
Here is my jQuery. I assume if first click is not working that I must add listener before the first click?? Can the event listeners be added on page load BEFORE the function to prevent default click, etc.?
<script>
// BEGIN FUNCTION TO CAPTURE AND INSERT CONTENT
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
</script>
Here is the HTML with links in unordered list
<!-- CONTRIBUTING ARTISTS LIST AND BIOS -->
<section id="artists">
<h2>Contributing Artists</h2>
<ul class="cols">
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
</ul>
</section>
Here is HTML of Section where code is being inserted by function
<!-- Performer Bios Dynamically updated -->
<section id="performbio">
</section>
Here is div contents that are being inserted
<div class="artistbio">
<p class="artistname">First Last</p>
<img class="artistimg" src="performers/img/name.jpg">
<p>lots of text here</p>
</div>
If I understand it right, you want to scroll to the section where the details appear on clicking any item in the list but through js and not HTML. In that case, you would add an onclick listener on to the list elements like so:
listElement.onclick = moveToDiv;
The function:
function moveToDiv() {
document.location = "#performbio";
}
A simple way to add a listener to all of the elements:
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
For the edited post, you need to move the function definition out of the document.ready function. you would change the script to:
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
Another Solution: Using scrollIntoView
First, get all the elements into a variable using querySelectorAll
var elements = document.querySelectorAll(".bio");
Then create a function, for the scrolling part:
function scroll(element) {
element.scrollIntoView();
}
Then just add the onclick listener:
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
scroll(elements[i]);
});
}
I found it very frustrating to try to accomplish these two tasks so instead of a jQuery solution I opted for a CSS solution.
I populated my DIV with all the php includes, gave them unique id's for the anchors to work and then used CSS to hide them by default until clicked and it works like a charm....shows only what I need to show and goes there like an anchor is supposed to.
I must thank Ghost for all of your help and efforts to try and solve this via jQuery. You were very kind and generous.
Here is the code I used:
My collection of links.
<li><a class="bio" href="#artist-name1">Name 1</a></li>
<li><a class="bio" href="#artist-name2">Name 2</a></li>
which anchors to these divs
<div class="bio-container" id="artist-name1">
<?php include('performers/name-lastname.html'); ?>
</div>
<div class="bio-container" id="artist-name2">
<?php include('performers/name-lastname.html'); ?>
</div>
Then I use this CSS to hide those divs until the anchors are clicked.
I'm using [id*="artist-"] to target only links with such text...very easy. Not ideal for a massive list...but mine is not so large so it will do for this situation.
[id*="artist-"] {display: none;}
[id*="artist-"]:target {display: block;}

Disabled button is clickable on Edge browser

I have problem with Edge browser. In my web site I have buttons with span tags inside them. In this span tags I bind text and icons. So far I had no problem but on Edge browser it is possible to click on disabled buttons. After investigating problem I found out that, when button contains span tags inside, it is possible to click on button. Here is how it looks on my web site:
<button id="btnRefresh" type="button" class="btn btn-primary" ng-click="refresh()" ng-disabled="performingAction">
<span ng-class="performingAction && action == 'refresh' ? 'fa fa-cog fa-spin' :'fa fa-refresh'"></span>
<span>{{ refresh }}</span>
</button>
Here is example to testing:
<button type="button" disabled="disabled" onclick='alert("test");'>
<span>Click me!</span>
</button>
One option would be to hide buttons instead of disabling, but I prefer to disable them. Please suggest solution to over come this issue.
Just set
pointer-events: none;
for disabled buttons.
Here's CSS to disable all disabled elements everywhere:
*[disabled] {
pointer-events: none !important;
}
pointer-events documentation
This is a bug in Microsoft Edge. Disabled buttons accept clicks if they contain any HTML elements (i.e. if they contain anything else than just text).
Reported multiple times via Microsoft Connect:
Event bubbles from child element into element (by SO user Ryan Joy)
Bootstrap/Jquery disabled buttons generate click events and show tooltips even disabled
The bug was still present in Build 10565 (16 October 2015).
It was fixed in the November update, Build 10586.
A possible (but ugly) workaround is to call some Javascript in onclick for every button, which then checks if the button is disabled and returns false (thus suppressing the click event).
One work around I've come up with using angularjs is inspired by Ben Nadel's blog here
So for example:
angular.module('myModule').directive(
"span",
function spanDirective() {
return ({
link: function (scope, element, attributes) {
element.bind('click', function (e) {
if (e.target.parentNode.parentNode.disabled || e.target.parentNode.disabled) {
e.stopPropagation();
}
})
},
restrict: "E",
});
}
);
Since you're not always going to be using a span element and probably don't want to create a new directive for every element type, a more general workaround would be to decorate the ngClick directive to prevent the event from reaching the real ngClick's internal event handler when the event is fired on a disabled element.
var yourAppModule = angular.module('myApp');
// ...
yourAppModule.config(['$provide', function($provide) {
$provide.decorator('ngClickDirective', ['$delegate', '$window', function($delegate, $window) {
var isEdge = /windows.+edge\//i.test($window.navigator.userAgent);
if (isEdge) {
var directiveConfig = $delegate[0];
var originalCompileFn = directiveConfig.compile;
directiveConfig.compile = function() {
var origLinkFn = originalCompileFn.apply(directiveConfig, arguments);
// Register a click event handler that will execute before the one the original link
// function registers so we can stop the event.
return function linkFn(scope, element) {
element.on('click', function(event) {
if (event.currentTarget && event.currentTarget.disabled) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
}
});
return origLinkFn.apply(null, arguments);
};
};
}
return $delegate;
}]);
}]);

Prevent page from going to the top when clicking a link

How can I prevent the page from "jumping up" each time I click a link? E.g I have a link somewhere in the middle of the page and when I click it the page jumps up to the top.
Is the anchor href="#"? You can set it to href="javascript:void(0);" instead.
If you are going to a prevent default please use this one instead:
event.preventDefault ? event.preventDefault() : event.returnValue = false;
Let's presume that this is your HTML for the link:
Some link goes somewhere...
If you're using jQuery, try like this:
$(document).ready(function() {
$('a#some_id').click(function(e) {
e.preventDefault();
return false;
});
});
Demo on: http://jsfiddle.net/V7thw/
If you're not on jQuery drugs, try with this pure DOM JavaScript:
window.onload = function() {
if(document.readyState === 'complete') {
document.getElementById('some_id').onclick = function(e) {
e.preventDefault();
return false;
};
}
};
It will jump to the top if you set the link href property to # since it is looking for an anchor tag. Just leave off the href property and it won't go anywhere but it also won't look like a link anymore (and make sure to handle the click even in javascript or else it really won't be of much use).
The other option is to handle the click in javascript and inside your event handler, cancel the default action and return false.
e.preventDefault();
return false;