Detecting Href Is Clicked - javascript

I'm trying to detect if certain element is clicked on onbeforeunload. I can't get it to work. Below is examples of the Javascript code and HTML code on the project (Please note that I have no control over the HTML element as it is not my site)
function checkLeave() {
var p = document.getElementByElementById('yeah');
if (p.href.onclick) {
//do something
}
else {
//do something else
}
}
window.onbeforeunload = checkLeave;
HTML CODE
//The goSomewhere goes to another page
<a id="yeah" href="javascript:goSomewhere();">
<img src="smiley.png">
</a>
Thanks in advance,
J

What you need to do is bind an event handler to each on the page.
This can be done with the following:
// Select all links
//var allLinks = document.querySelectorAll('a[href]');
var allLinks = document.links;
// Bind the event handler to each link individually
for (var i = 0, n = allLinks.length; i < n; i++) {
//allLinks[i].addEventListener('click', function (event) {});
allLinks[i].onclick = function () {
// Do something
};
}

You are testing for the presence of the onclick property to the <a> tag. It isn't present in the markup. Rather than using the onclick, the markup calls a script as the element's href. So you need to look for a script in the href instead:
var p = document.getElementByElementById('yeah');
if (p.href.indexOf("javascript") === 0) {
//do something
}
else {
// do something else
}

Maybe something like this? (just the idea)
document.getElementById('yeah').onclick = function() {
clicked = this.href;
};

Related

How can I toggle between 2 classes on click on the same element on JS

Need your help on something,
Trying to toggle between classes when I click on an element on an HTML page but unfortunately once toggled I cannot change it back.
Even tried returning the querySelector but no luck.
Here is the code I wrote;
let fetchNumbers = document.querySelectorAll(`.cardnumber`);
for (let index = 0; index < fetchNumbers.length; index++) {
if (fetchNumbers[index].classList.contains('unselected') === true) {
fetchNumbers[index].addEventListener(`click`, function() {
fetchNumbers[index].classList.add(`selected`);
fetchNumbers[index].classList.remove(`unselected`);
fetchNumbers = document.querySelectorAll(`.cardnumber`);
return fetchNumbers;
});
} else {
fetchNumbers[index].addEventListener(`click`, function() {
fetchNumbers[index].classList.add(`unselected`);
fetchNumbers[index].classList.remove(`selected`);
fetchNumbers = document.querySelectorAll(`.cardnumber`)
return fetchNumbers;
});
}
}
Thank you in advance
Have You tried using the toggle() method? I think that it might be what You're looking for
Give it a shot!
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_toggle_class
Another example that might be helpful
https://codepen.io/StrengthandFreedom/pen/ZOGVLg
I've created an Asp.NET Core application to test/debug your code with a fresh html page and javascript with your code snippet.
If this code block below is the only code in your Javascript file,
let fetchNumbers = document.querySelectorAll(`.cardnumber`);
for (let index = 0; index < fetchNumbers.length; index++) {
if (fetchNumbers[index].classList.contains('unselected') === true) {
fetchNumbers[index].addEventListener(`click`, function () {
fetchNumbers[index].classList.add(`selected`);
fetchNumbers[index].classList.remove(`unselected`);
fetchNumbers = document.querySelectorAll(`.cardnumber`);
return fetchNumbers;
});
} else {
fetchNumbers[index].addEventListener(`click`, function () {
fetchNumbers[index].classList.add(`unselected`);
fetchNumbers[index].classList.remove(`selected`);
fetchNumbers = document.querySelectorAll(`.cardnumber`)
return fetchNumbers;
});
}
Info
Javascript files are loaded statically, which means they are ran immediately after the html page is loaded into the DOM, so this code is run immediately after the html page is loaded.
Problem
Based upon the classes defined by your html elements (in this case - class="cardnumber unselected"), once the page loads, your code block above would hit the first if statement, then assign the click event to all cardnumber elements, then proceed to change the class from unselected to selected.
When you go to click your html element the second time, the click event from the if block in your if/else block will NOT be ran as the page has already loaded. This means the else block will never execute.
This is the reason you are not seeing any functionality on the second click.
note
Javascript events can only be defined once, so you'd never be able to bind both the click events in the if block AND else block.
Solution
Define the click event for your cardnumber. Move your if/else logic into your new click event like below:
let fetchNumbers = document.querySelectorAll('.cardNumber');
for (let index = 0; index < fetchNumbers.length; index++) {
fetchNumbers[index].addEventListener('click', function () {
if (fetchNumbers[index].classList.contains('unselected') === true) {
fetchNumbers[index].classList.add('selected');
fetchNumbers[index].classList.remove('unselected');
fetchNumbers = document.querySelectorAll('.cardNumber');
return fetchNumbers;
} else {
fetchNumbers[index].classList.add('unselected');
fetchNumbers[index].classList.remove('selected');
fetchNumbers = document.querySelectorAll('.cardNumber')
return fetchNumbers;
}
});
}

Set JS Variable to href of clicked anchor dynamically

I need to set a variable's value based on the href of a clicked link.
I know that I can set the variable using an event listener that would run this when the link is clicked
var x = document.getElementById("myAnchor").href
But that is set to a single element. I need it to work dynamically based on which link is clicked. For example:
Partner A
Partner B
Partner C
// function to attach click event to all links
function attachClickEvent() {
var linklist = document.getElementsByTagName('a');
var listLength = linklist.length;
var i = 0;
for (; i < listLength; i++) {
linklist[i].addEventListener("click", ClickedLinkEvent);
}
}
window.onload = attachClickEvent;
// function that creates click event
function ClickedLinkEvent() {
var anchor = obj.href;
console.log(anchor);
if (anchor.includes('clientdomain')) {
//do nothing
} else {
SendLinkEvent();
}
}
// function to run on click event
function SendLinkEvent() {
ga('send', {
hitType: 'event',
eventCategory: 'Affiliate Link',
eventAction: 'Click',
eventLabel: anchor
});
}
The anchor variable needs to be set to /link1 if Partner A is clicked, but /link2 if Partner B is clicked.
So, is there a way to do this with vanilla JS?
If you adjust the ClickedLinkEvent method declaration and add an argument to the method signature, then you will have the event object. The event object has a target parameter. If I understood you correctly, this is what you need. Don't you?
function ClickedLinkEvent(e) {
console.log('hello', e);
var anchor = e.target.href;
console.log(anchor);
if (anchor.includes('clientdomain')){
//do nothing
}
else {
SendLinkEvent(anchor);
}
}
You can set custom attributes to the a element like this:
Link A
Then in your js file:
var data_partner= document.getElementById('myAnchor').getAttribute('data-partner');

Can I add onmouseover attribute to run only once?

Say I have a link like the following:
<a class="link" href="www.rich.com" onmouseover="go(this)">Link</a>
Is there a way to configure the onmouseover event, calling go(this) to run only a single time while still using the inline onmouseover=<some code> notation? I want it defined inline, not with a JavaScript call.
Currently, I have this, but it is not what I want:
$(".link").one('mouseover', function(e) {
// do something
});
You can nullify the onmouseover binding afterwards:
<a class="link" href="www.rich.com" onmouseover="go(this); this.onmouseover = null;">Link</a>
Using Vanilla JS:
const link = document.querySelector('.link');
link.addEventListener('mouseover',
() = window.open('your url'),
{ once : true }
);
ref: How can I add an event for a one time click to a function?
You could set a var that indicates whether it has been triggered or not...
var triggered = false;
$(".link").one('mouseover', function(e) {
// do something
if(!triggered)
{
triggered = true;
// and whatever else you want to do
}
});
Alternatively you can do something like this :
var check = 0;
$(".link").on('mouseover', function(e) {
if(check == 0 ){
// do something
check = 1;
}else {
return false;
}
});

Use Javascript string as selector in jQuery?

I have in Javascript:
for ( i=0; i < parseInt(ids); i++){
var vst = '#'+String(img_arr[i]);
var dst = '#'+String(div_arr[i]);
}
How can I continue in jQuery like:
$(function() {
$(vst).'click': function() {
....
}
}
NO, like this instead
$(function() {
$(vst).click(function() {
....
});
});
There are other ways depending on your version of jquery library
regarding to this, your vst must need to be an object which allow you to click on it, and you assign a class or id to the object in order to trigger the function and runs the for...loop
correct me if I am wrong, cause this is what I get from your question.
$(function() {
$(vst).click(function() {
....
}
})
You can use any string as element selector param for jQuery.
Read the docs for more information.
http://api.jquery.com/click/
http://api.jquery.com/
You can pass a String in a variable to the $() just the way you want to do it.
For example you can do:
var id = 'banner';
var sel = '#'+id;
$(sel).doSomething(); //will select '#banner'
What's wrong is the syntax you are using when binding the click handler. This would usually work like:
$(sel).click(function(){
//here goes what you want to do in the handler
});
See the docs for .click()
Your syntax is wrong, but other than that you will have no problem with that. To specify a click:
$(function() {
for ( i=0; i < parseInt(ids); i++){
var vst = '#'+String(img_arr[i]);
var dst = '#'+String(div_arr[i]);
$(vst).click(function (evt) {
...
});
}
})
Note that since vst is changing in the loop, your event code should also be placed in the loop.
EDIT: Assuming you want the same thing to happen for each image and each div, you could also do something like this:
$(function () {
function imgEventSpec($evt) {
// image clicked.
}
function divEventSpec($evt) {
// div clicked.
}
for (var idx = 0; idx < img_arr.length && idx < div_arr.length; idx ++) {
$("#" + img_arr[idx]).click(imgEventSpec);
$("#" + div_arr[idx]).click(divEventSpec);
}
});

Do something on :target with javascript

I'm using the CSS3 :target pseudo selector to create in-page navigation without reloading the page. This works really well!
But I have a problem, I need to reset the forms in a page when the page targetted, how can I know if an element is targetted with javascript? Like element.ontarget = function();
Or maybe something like element.ondisplaychange -> element.oncsschange?
BETTER UPDATE:
var hashcache = document.location.hash;
window.onhashchange = function() {
if(hashcache != document.location.hash) {
$(hashcache + ' form input').each(function() {
$(this).val('');
});
hashcache = document.location.hash;
}
}
UPDATE:
$('a[href^="#"]').each(function() {
this.onclick = function() {
href = $(this).attr('href');
if(href != document.location.hash) {
$(href + ' form input').each(function() {
$(this).val('');
});
}
}
});
If you're using JavaScript for the navigation, I'd suggest just adding the check to that. But I'm guessing from your question you're not, that you're instead using plain links with just anchors (e.g., <a href='#target1'>, <a href='#target2'>, ...).
A couple of options:
Use a Timer
In that case, basically what you want to do boils down to receiving an event when the anchor changes. As far as I know, and as far as the people answering this other question on StackOverflow in January knew, you can only do that with a timer. (Edit: But see ide's comment below, there's a new hashchange event we'll be able to use soon!) E.g.:
(function() {
var lastHash = window.location.hash;
setTimeout(function() {
var newHash = window.location.hash;
if (newHash !== lastHash) {
lastHash = newHash;
// Trigger your target change stuff
}
}, 250);
})();
That checks for changes every quarter second. That may not be enough for you, you could lower the 250, but beware running too much and slowing everything else down.
But as you say below, this is inefficient.
Hook the Link's click event
Since you're already using JavaScript on the page, I'd recommend using handlers on your links instead. If you add a class name or something to them (I bet they already have one; I'll us "navlink" below), this is easily set up:
var links, index, link;
links = document.getElementsByTagName('a');
for (index = 0; index < links.length; ++index) {
link = links.item(index);
if ((" " + link.className + " ").indexOf(" navlink ") >= 0) {
hookEvent(link, 'click', clickHandler);
}
}
function clickHandler() {
// `this` will reference the element that was clicked
}
// The 'hook' function:
var hookEvent = (function() {
var elm = document.createElement('a');
function hookEventViaAttach(element, event, handler) {
element.attachEvent("on" + event, handler);
}
function hookEventViaAddListener(element, event, handler) {
element.addEventListener(event, handler, false);
}
function hookEventDOM0(element, event, handler) {
element["on" + event.toLowerCase()] = handler;
}
if (elm.attachEvent) {
return hookEventViaAttach;
}
if (elm.addEventListener) {
return hookEventViaAddListener;
}
// I usually throw a failure here saying not supported, but if you want,
// you can use the DOM0-style stuff.
return hookEventDOM0;
})();
A lot of the complication of the above goes away if you use a library like jQuery, Prototype, YUI, Closure, or any of several others.
For instance, the jQuery version:
$("a.navlink").click(clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The Prototype version:
$$("a.navlink").invoke('observe', 'click', clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The onfocus property returns the onFocus event handler code on the current element.
event handling code = element.onfocus
The onblur property returns the onBlur event handler code, if any, that exists on the current element.
element.onblur = function;
Example: http://jsfiddle.net/g105b/cGHF7/
<html>
<head>
<title>onblur event example</title>
<script type="text/javascript">
var elem = null;
function initElement()
{
elem = document.getElementById("foo");
// NOTE: doEvent(); or doEvent(param); will NOT work here.
// Must be a reference to a function name, not a function call.
elem.onblur = doEvent;
};
function doEvent()
{
elem.value = 'Bye-Bye';
alert("onblur Event detected!")
}
</script>
<style type="text/css">
<!--
#foo {
border: solid blue 2px;
}
-->
</style>
</head>
<body onload="initElement()";>
<form>
<input type="text" id="foo" value="Hello!" />
</form>
<p>Click on the above element to give it focus, then click outside the
element.<br /> Reload the page from the NavBar.</p>
</body>
</html>
Maybe youcan just code like this
function hashChangeEvent(){
$(window.location.hash)//do something
}
window.onhashchange = hashChangeEvent;//when hash change
hashChangeEvent();//first load

Categories

Resources