Changing image with onclick for 100's of different image links - javascript

I am fairly new to javascript and just trying to figure out how to get 100's of image links to change to a specific image once they've been clicked.
I know you can add ID's, but having to make 100's or 1000's of ID's will be a pain. Maybe someone will be able to help me with this issue, or direct me in the correct direction. Thank you!
<a id="click"><img id="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://yahoo.com','_blank');"></a>
<a id="click"><img id="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://google.com','_blank');"></a>
<a id="click"><img id="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://monster.com','_blank');"></a>
document.getElementById('click').onclick = function(){
document.getElementById('change').src = "http://i.imgur.com/0eaWvgw.jpg";
}

Using jQuery,
$('a').on('click', function() {
$('img').each(function() {
$(this).attr('src', 'http://i.imgur.com/0eaWvgw.jpg')
});
});

First of all, There must not be multiple elements in a document that have the same id value.
Use common-class over all the elements on which click event is to be bound
Use jQuery .on method to register events over all the elements having specified common-class
Also note that you have attached inline-click event over img elements, which action is suppose to take place once click is dispatched ?
$('.click').on('click', function(e) {
e.preventDefault(); //To prevent behavior of `a` elements
$(this).find('img.change').prop('src', 'http://i.imgur.com/0eaWvgw.jpg');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<a class="click">
<img class="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://yahoo.com','_blank');">
</a>
<a class="click">
<img class="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://google.com','_blank');">
</a>
<a class="click">
<img class="change" src="http://i.imgur.com/zS0lOud.jpg" onClick="window.open('http://monster.com','_blank');">
</a>

As others stated, an id is something that must be unique. A class is what you want to use. The class attribute is a space-separated list of words. In this case, we only need one class on all links. Now you put some JS on all these links, but you should instead write it like this:
<a class="change" href="http://www.example.com" target="_blank">
<img src="image.png" />
</a>
The links will open the sites in a new window or tab even on browsers with JavaScript disabled in that way.
Then we need to retrieve a list of all elements with the "change" class, and add an event listener for the click event on all of them.
var changeLinks = document.querySelectorAll('.change');
var clickListener = function(e) {
var imgElement = e.currentTarget.querySelector('img');
imgElement.src = 'newimage.png';
// technically, the image is only changed once so we can remove the
// event listener once it has run on a link
e.target.removeEventListener('click', clickListener);
};
for(var i=0, element; element = changeLinks[i]; ++i) {
element.addEventListener('click', clickListener);
}

Related

Event delegation does not capture all inner elements

I am using event delegation on my project but for some reason it does not works as expected.
It may seem like a duplicated question but searching for days I have not found the solution so it is not as clear, even in a course I am taking at UDEMY this is not addressed.
The html structure is like this:
<div class="users-list">
<a class="useruid" id='. $row['unique_id'] .'>
<div class="content">
<img src="php/images/'. $row['img'] .'" alt="">
<div class="details">
<span>'. $row['fname']. " " . $row['lname'] .'</span>
<p>'. $you . $msg .'</p> </div>
</div>
<div class="status-dot '. $offline .'"><i class="fas fa-circle"></i>
</div>
</a>
</div>
The vars with the dollar sign are php variables and everything inside "users-list" <div> is added dynamically to the DOM (that part works well).
The problem comes when handling the event listener in javascript as follows:
const ulist = document.querySelector(".users-list");
ulist.addEventListener("click", (e) => {
e.preventDefault();
console.log(e.target);
if (e.target.classList.contains("useruid")) {
console.log(e.target.id);
}
});
I need to get the id number inside the element to use it in another part of the program but it will only be captured if I click on the outer boundaries of the box and most of the time only the <span> and the <p> elements are the ones that will capture the click.
What do I'm missing here, isn't the click suppose to bubble up all the way up passing through the <a> element not matter where I click in that box?
I've searched on other questions here and everywhere online for days but can't find a clear solution. Maybe my approach is incorrect, I don't know really.
Adding additional clarification
using this has the same problem:
if (e.target.matches("a.useruid")) {
console.log(e.target.id);
}
What do I'm missing here, isn't the click suppose to bubble up all the way to the <a> element not matter where I click in that box?
No. It bubbles up to <div class="users-list"> because that is where the event listener is bound.
The target is the element that triggered the event.
You need to change your logic from does the clicked element have the class to does the clicked element or one of its ancestors have the class.
You can do that with closest.
const ulist = document.querySelector(".users-list");
ulist.addEventListener("click", (e) => {
e.preventDefault();
const anchor = e.target.closest(".useruid");
console.log(e.target);
console.log(anchor)
if (anchor) {
console.log(anchor.id);
}
});
<div class="users-list">
<a class="useruid" id='one'>
<div class="content">
<img src="//placekitten.com/100/100" alt="">
<div class="details">
<span>foo</span>
<p>bar</p>
</div>
</div>
</a>
</div>
The target will be the most nested element that has been clicked, So, it maybe a child element to .useruid element.
I think you need to use closest
const ulist = document.querySelector(".users-list");
ulist.addEventListener("click", (e) => {
e.preventDefault();
console.log(e.target);
if (e.target.closest(".useruid")) {
console.log(e.target.id);
}
});
e.target represents the element event was called upon. If you click on span, your e.target is that span.
To solve the problem, you first have to check if the event was called on anchor tag.
const myTarget = e.target.matches("a")? e.target : e.target.closest("a")

JavaScript: get href value of multiple <a> tags

Without using jQuery or any other library, the objective is to inform the user which URL will visit with an alert event. In the markup, there are multiple <a> tags with different href values for each, when the user clicks the <a> tag, an alert event displays mentioning where the user is going before actually leaving the website.
Workflow:
The document loads
The user clicks an <a> tag
An alert event displays with the href value of the clicked <a> tag
Once the user closes the alert event, the browser starts loading the href website
Code sample:
document.querySelector('a').onclick = function(e) {
e.preventDefault();
var href = document.querySelector('a').href;
alert('You are going to: ' + href);
window.location = href;
}
<div id="container">
<a class="link" href="https://www.microsoft.com/">Link A</a>
<a class="link" href="https://www.google.com/">Link B</a>
<a class="link" href="https://www.apple.com/">Link C</a>
</div>
Objective:
Set up the JavaScript dynamically for all the <a> tags to achieve the workflow output for each one of them (and for any further <a> tags with the same class that might be included in the document). Please note that only Link A works as desired so far.
Your coding to solve this is appreciated!
querySelector will only match the first element that matches the selector. You can either use querySelectorAll to match all of those elements, add listeners to all of them...
OR
Attach one listener to the container (event delegation allows it to capture events from its children as they "bubble up" the DOM). When a child element is clicked the handler function checks that its an anchor with a .link class, and then executes the rest of the code.
const container = document.querySelector('#container');
container.addEventListener('click', handleClick);
function handleClick(e) {
if (e.target.matches('.link')) {
e.preventDefault();
const { href } = e.target;
alert(`You are going to: ${href}`);
window.location = href;
}
}
<div id="container">
<a class="link" href="https://www.microsoft.com/">Link A</a>
<a class="link" href="https://www.google.com/">Link B</a>
<a class="link" href="https://www.apple.com/">Link C</a>
</div>
Use querySelectorAll() to get all the anchor tags, then loop through them and addEventListener() instead of onclick, because onclick can only be assigned to one element at a time. Also, you can grab the href with e.target.href. e.target is the element that was acted upon to start the event.
document.querySelectorAll('a').forEach(function(el) {
el.addEventListener("click", function(e) {
if (e.target.matches('.link')) {
e.preventDefault();
var href = e.target.href;
alert('You are going to: ' + href);
//window.location = href;
}
})
})
<div id="container">
<a class="link" href="https://www.microsoft.com/">Link A</a>
<a class="link" href="https://www.google.com/">Link B</a>
<a class="link" href="https://www.apple.com/">Link C</a>
</div>

Use jQuery to target a class within a div and perform additional changes within the same div

I have the following HTML code:
<div class="pack1">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
<div class="pack2">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
<div class="pack3">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
[...]
<div class="pack10">
<a class="optionButton">First option</a>
<a class="optionButton">Second option</a>
<a class="optionButton">Third option</a>
</div>
Using jQuery I would like to trigger an event on clicking the a tag with the optionButton class but I don't know how to limit the event to the div that the a tag resides in.
For example right now I have something like:
$(document).ready(function(){
$('.optionButton').click(function() {
$(".optionButton").removeClass('checked');
$(this).addClass('checked');
});
});
It works fine for the first selection, lets say when I click the First option in the pack1 div, but if I make another selection, lets say Third option in the pack3 div, the first one will disapear.
Also, there must be only one selected option for each pach.
You need to narrow down the selection of your removeClass, as right now it's selecting every occurrence of optionButton.
$(document).ready(function(){
$('.optionButton').click(function() {
$(this).siblings('.optionButton').removeClass('checked');
$(this).addClass('checked');
});
});
This will narrow it down by selecting siblings of the clicked element that have the class optionButton.
JSFiddle
EDIT: Woops, put the wrong class in there. Should be patched up now.
Because exact DOM structure is highly subject to change, your best bet is to almost always go to the parent and search your way down like so:
1) $(this).parent().find(".optionButton").removeClass("checked");
or you can simplify the selector results set (and make your code slightly more efficient) by saying:
2) $(this).parent().find(".checked").removeClass("checked");
You can also use the selector context parameter like so:
3) $(".checked", $(this).parent()).removeClass("checked");
The difference between 2 and 3 is purely syntactic. jQuery will convert 3 into 2 behind the scenes
I think this could work
$(document).ready(function(){
$('.optionButton').click(function() {
var parent = $(this).closest("div");//getting the parent content
parent.find(".optionButton").removeClass('checked');//remove the checked
$(this).addClass('checked');
});
});

href link not working while using jquery trigger

i have a javascript like this one
var funct = function(){
return {
init : function(data) {
this.sendRequest({
action : 'login'
});
},
login : function()
{
var parentDIV = $("#dnn_ctr450_HtmlModule_lblContent");
parentDIV.attr('href', 'https://webcenter.elendersolutions.com/webcenter/').trigger('click');
}
}
}
HTML CODE of this one.
<div id="dnn_ctr450_ModuleContent" class="DNN_HTMLContent">
<div id="dnn_ctr450_HtmlModule_lblContent" class="Normal">
<p></p>
<h2></h2>
<h2>
<a href="https://webcenter.elendersolutions.com/webcenter/" target="_self"> <-- how can i trigger this one?
<img width="188" height="40" border="0" src="/Portals/0/WebcenterSignin.gif" alt="Webcenter Login"></img>
</a>
</h2>
<h2>
<a href="https://rates.lsi-lps.com/">
<img width="188" height="40" border="0" src="/Portals/0/RateCalculatorSignin.gif" alt=""></img>
</a>
</h2>
<h2></h2>
<p></p>
</div>
what i'm trying to do is to trigger the link so it would function like i just click it manually.
For one thing, you aren't actually selecting the link correctly. Rather, you are selecting its parent div, and setting an href on the div. The target element of your function is what is in your jQuery object, in this case the div: $("#dnn_ctr450_HtmlModule_lblContent").
Instead, select the anchor link directly (it may be worth reviewing the jQuery docs for the attribute-equals selector and find:
var parentDIV = $("#dnn_ctr450_HtmlModule_lblContent");
var aLink = parentDIV.find("a[href='https://webcenter.elendersolutions.com/webcenter/']");
The second problem is that jQuery's click functionality won't allow you to follow links; you'll have to take advantage of the native html element's click method, as detailed in this SO post.
aLink[0].click();
Note that by doing [0] we are accessing the underlying DOM element, and so the method we're calling is not a jQuery method.
we can't do anything with it with JQuery. the only we can do is to progmatically do the redirection.
var href = parentDIV.attr('href');
window.location.href = href;
but with native javascript yes we can.
parentDIV.[0].click(); //where the index 0 returns the native DOM object.
but please be advised that for some reasons browsers doesn't want to trigger redirection from href link when triggered progmatically by javascript.

onClick does not function inside a dynamically generated div

I have a jquery code which generate a div dynamically
the problem is that the onclick function for the a tag does not calls the required function
Here is the code
$("#new").append('
<ul class="#...#">
<li>
<a href="./d.html?n1='+item[0]+'&n2='+item[2]+'&n3='+item[3]+'">
<input type="hidden" value='+item[0]+'>
<img style="height: 64px; width: 64px;" class="#...#"
src="image.png" width="40" height="40" />
<span class="#...#">
<b>'+item[0]+'</b>
'+item[1]+'......
</span>
</a>
<br />
<div>
<a onClick="insert();" href="#">
<i class="icon1"></i>
</a>
<a href="2.php?q='+q+'&n='+item[0]+'" id="icon2" name="icon2">
<i class="icon2"></i>
</a>
</div>
</li>
</ul>
');
I am using the above code as an ajax success function
the a tag is not calling the insert() function
I searched for the error but could not find the
What am doing it wrong?
Thsnks in advance
Add a custom class, such as "catchClick" to the element that you need to catch the click event of.
var linkToAdd = '<a class="catchClick" href="#">My link</a>';
var $linkToAdd = $(linkToAdd);
$('#new').append($linkToAdd);
Then the following code will setup handlers for clicks on that element.
It works because the click event is bubbled up the dom hierarchy to the document element. So you can attach a listener to the document element instead.
$(document).on('click', '.catchClick', function(e) {
// do your stuff here
// you probably need to get a jquery reference to the element that was clicked:
var $this = $(this);
// you probably want to stop the event's default actions so we'll add this:
e.stopPropagation();
e.preventDefault();
});
When you work with dynamic content I suggest you use DOM event delegation. The ideea is to add the listener on a parent of your dynamically added content
This explains how to do it and how it works
http://davidwalsh.name/event-delegate
Use JavaScript event delegation to separate concerns:
$(function() {
$(document.body).on('click', 'ul.someClass div a', function() {
// insert() method logic goes here
});
});
Second argument specifies the event target. This event is bind to the document's body so it's always present. Target DOM objects can be generated per AJAX at some point later or removed from the document. The actual target check happens when a user actually clicks something.
Also adding a class attribute to <div> or <a> in your code might help with readability. E.g.:
<div class="buttons">
<a class="btn-insert" onClick="insert();" href="#">
<i class="icon1"></i>
</a>
<a href="2.php?q='+q+'&n='+item[0]+'" id="icon2" name="icon2">
<i class="icon2"></i>
</a>
</div>
Target attribute for jQuery on() method could then be simplified to just '.btn-insert'
Set the click event handler AFTER having appended new clickable items to the document, and subsequently after each time you append new clickable items to the document.

Categories