I have three clickable images. One image on the first row, two images on the second row. The image on the first row is a reflection of whichever image on the second row was last clicked. I can make the image on the second row modify the src of the image on the first row, but am having difficulty modifying the onclick parameter of the anchor tag. I can't just change the href of the first image, it has to actually mimic the clicking of the second row image. Here's my code, along with by a jsfiddle of it:
https://jsfiddle.net/2hgzmnmb/
<a onclick="document.getElementById('image1').click();" id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" onclick="document.getElementById('previewImage').src='http://i.imgur.com/UevhwuA.png';alert('1')"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" onclick="document.getElementById('previewImage').src='http://i.imgur.com/121fy0E.png';alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
I want to add the following: document.getElementById('previewLink').onclick='document.getElementById('image1').click();' to the onclick parameter for the first image on the bottom row, and: document.getElementById('previewLink').onclick='document.getElementById('image2').click();'
to the second image on the bottom row, so the image on the first row will not only look like whichever image was last clicked on the second row, but will also mimic the actual click. Right now, obviously from the code, it will only mimic clicking the first image on the second row, no matter what image was last clicked, and I'm thinking it's because my syntax isnt correct when I try to modify the onclick property of the anchor tag for the image on the first row.
I also tried doing this with variables but got a bit tied in knots.
Any ideas on how I could go about doing this? I'm close, just not there yet.
Thanks!
Fiddle: https://jsfiddle.net/2hgzmnmb/1/
this: document.getElementById('previewLink').onclick='document.getElementById('image1').click();'
should be:
document.getElementById('previewLink').onclick=this.onclick
because onclick attribute is actually running a JS code, so if you pass a string there, it will interpret it as just a string.
onclick='document.getElementById('image1').click();' is the same as the string "document.getElementById('image1').click();", it does nothing.
add the line below to each anchor tag in the second row
document.getElementById('previewLink').related_id=this.id
<a onclick="if(document.getElementById(this.related_id)!=null){document.getElementById(this.related_id).click()};" id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" onclick="this.related_id=this.id;document.getElementById('previewImage').src='http://i.imgur.com/UevhwuA.png';alert('1');document.getElementById('previewLink').related_id=this.id"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" onclick="this.related_id=this.id;document.getElementById('previewImage').src='http://i.imgur.com/121fy0E.png';document.getElementById('previewLink').related_id=this.id;alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
I'd remove the inline handlers and use addEventListener() instead - except for demo purposes I've left your alert() messages in the inline onclick attributes to simulate the click behaviour that you want clicks on the preview image to mimic.
By putting the logic into JS in a <script> element you'll find it much easier to maintain because you can format the code in a readable manner.
Then simply use a variable to keep track of what the currently selected image is:
// the following JS should be in a script element at the end of the body
// and/or wrapped in a window onload handler
function imageClick(e) {
currentImage = e.currentTarget;
document.getElementById("previewImage").src = currentImage.querySelector("img").src;
}
var images = document.querySelectorAll(".image");
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", imageClick);
}
var currentImage = images[0]; // default to first image
document.getElementById('previewLink').addEventListener("click", function() {
currentImage.click();
});
<a id="previewLink"><img id="previewImage" src="http://i.imgur.com/UevhwuA.png"></a>
<br><br>
<a id="image1" class="image" onclick="alert('1')"><img src="http://i.imgur.com/UevhwuA.png"></a>
<a id="image2" class="image" onclick="alert('2')"><img src="http://i.imgur.com/121fy0E.png"></a>
Note also that I added a class to your lower images in order to make it easy to process them in a loop to add their click handler. This is optional, you could select by id instead with .querySelectorAll("#image1,#image2").
Related
I generate procedurally a div containing an image and an input file in an HTML file.
The ID of all the element change by 1 each time. Here is the sample of the div that is repeated with K as the number that is incremented each time I generate this div, so every item has a different ID.
<div>
<img id="frame-add-K" src="" class="img-fluid" />
</div>
<label style="border: 2px solid black" for="img-input-K" class="btn">Select Image</label>
<input type="file" name="image_content_K" id="img-input-K" style="display:none; visibility:hidden;" accept="image/*" />
The div containing the image is supposed to work as a preview. So when the user input his image, I want to change the img source to the newly updated image.
I have tried something like this using jquery:
$(document).ready(function() {
$("input[id^=img-input-]").on("input", function() {
var id_input = $(this).attr('id').substring('img-input-'.length); //get me only the number at the end
$("#frame-add-" + id_input).attr("src", event.target.files[0]);
});
});
But id_input is always egual 1, so the change only affect my first div and change always the first image source. Moreover "event.target.files[0]" doesn't work there.
I ideally would like to make a generic function using jquery that would get the K of the element changed et update the image src associated with this K but I am open to any suggestion solving my issue.
Rather than use any ids, you can select the image which is the child of the div element two before the input.
const theImg = $(this).prev().prev().find("img");
I have a page that show lots of photos which can be opened with lightgallery.js
I've already made some custom HTML caption which works fine. But now I want to add a label to the image itself. How can I do that?
I will show an example of what my photos page looks like:
When you open an image this is what it looks like:
The left part is a custom HTML caption which I linked with this attribute: data-sub-html.
Example code of my looped code:
$photomasonry .= '
<div class="tile scale-anm noselect">
<a href="https://studio.website.nl/'.$getphotos['preview'].'" data-sub-html="#caption'.$imgcount.'" class="item masonrytile" data-src="https://studio.website.nl/'.$getphotos['preview'].'">
<img src="https://studio.website.nl/'.$getphotos['preview'].'"/>
<span class="idlabel">'.$getphotos['id'].'</span>
<span class="sizelabel">'.$size.'</span>
</a>
</div>';
$photomasonry .= '
<div id="caption'.$imgcount.'" style="display:none">
<img src="https://studio.website.nl/images/logo.png">
<h4 class="subhtmlh4">Maak iets moois met deze foto</h4>
<div class="gallerypopupbtns">
<button class="btnstyle purplebtn" type="button" name="button">Maak iets moois</button>
</div>
</div>';
$imgcount++;
But now I want this purple size icon (L, XL, XX) as a label on the image when lightgallery is opened. How can I do this? The html of the lightgallery is only generated after the page is loaded.
I want to add an element inside this part:
<div class="lg-img-wrap">
<img class="lg-object lg-image" src="https://studio.website.nl/images/photos/previews/preview-bb58317c8d05e29b32963e7a295a5b9f.jpg">
</div>
But not just that, the content is dynamic, so display the correct size for the correct image. I already created this for the photo overview page but not when clicking a photo.
According to the lightgallery docs, you can use the event lgAfterOpen to execute code once the gallery is opened. However, lightgallery makes this slightly difficult as you can't access the image clicked on from this event, but you can access it from the event lgBeforeOpen. With this in mind, I'd accomplish this by doing two things.
Firstly, add the size as a data attribute of each image:
<img src="https://studio.website.nl/'.$getphotos['preview'].'" data-size="'.$size.'"/>
Secondly, add the following functions when initialising lightgallery:
// example gallery definition
const lg = document.getElementById('custom-events-demo');
// add the following functions
lg.addEventListener('lgBeforeOpen', (event) => {
//add datasize property to target so it can be accessed in the afterOpen function
event.target.dataset.size = event.explicitOriginalTarget.dataset.size;
});
lg.addEventListener('lgAfterOpen', (event) => {
// get size from data attribute
var size = event.target.dataset.size;
// get the .lg-img-wrap div to append size to
var imgWrap = document.querySelector(".lg-container.lg-show .lg-img-wrap");
// create and append span
var sizeSpan = document.createElement("span");
sizeSpan.classList.add("sizelabel");
sizeSpan.innerHTML = size;
imgWrap.appendChild(sizeSpan);
});
//initialise lightgallery
lightGallery(lg);
You may be using a different version of lightgallery, but when I tested this the .lg-img-wrap element was a picture element not a div, so I replaced the last line of the event listener function with the following to get the size to show:
imgWrap.parentElement.appendChild(sizeSpan);
You might need a bit of extra CSS to position the size span as you wish, but just to get it to show all you need is:
.sizelabel {
position: relative;
}
Note: I don't think this will work if you navigate to a different image from within lightgallery as it won't update the size, and in fact the size might just get removed. To fix this you'd probably need to do something using the lgAfterSlide event and the index of the image, but from your screenshot it looks like you don't expect the user to scroll through images within lightgallery anyway so this may not be an issue.
How to show clicked image in modal
In view:
<a ng-click="openModal($event)" ng-style="{'background-image': 'url(assets/img/img-01.jpg)'}"><img src="assets/alpha-4x3.png"></a>
<a ng-click="openModal($event)" ng-style="{'background-image': 'url(assets/img/img-02.jpg)'}"><img src="assets/alpha-4x3.png"></a>
In controller:
$scope.openModal = function($event) {
$scope.modal.show();
$scope.poppedUpImg = $event.target.style.backgroundImage;
};
In Modal Template:
<ion-content class="p20">
<img ng-src="{{poppedUpImg}}" src="" alt="">
</ion-content>
Image not able to make the above code work. Or please suggest the better way to do it. The alpha image is taking my clicks.
Edit/Update
#Sphinxxx answer worked if the anchor is holding text content, if there is image inside the anchor then his answer does not work. Here is what I did to make things work.
$event.srcElement.parentElement.style.backgroundImage.split('("')[1].split('")')[0]
Not tested, but I'm guessing $event.target.style.backgroundImage is "url(assets/img/...)". To make a proper image src, you need to extract the url between the parentheses:
$scope.poppedUpImg = $event.target.style.backgroundImage
.split('("')[1]
.split('")')[0];
Edit:
If the clicked <a> contains child elements, $event.target will be the clicked child element. To always access the <a> element, use $event.currentTarget instead (Angular ng-click $event passes child element as target).
Example (click either the small "contained" thumbs or the larger backgrounds):
http://jsfiddle.net/U3pVM/26551/
In my function I would like to take an image add a dynamically created caption then wrap it all neatly in a div.
Before:
<img src="whatever" />
After:
<div class="imageBlock">
<img src="whatever" />
<span class="caption">The Caption</span>
</div>
This is what I currently have:
var imageCaption = '<span class="caption">'+array[1]+'</span>'
$(this).after(imageCaption).wrap('<div class="imageBlock '+array[0]+'" />');
This is working BUT is placing the span outside of the closing div tag.
You have to pay attention to what this actually refers to.
To get what you want just reverse the order,
var imageCaption = '<span class="caption">'+array[1]+'</span>'
$(this).wrap('<div class="imageBlock '+array[0]+'" />').after(imageCaption);
This is because your object that is being passed is the original image tag. Originally you call after on your tag so it does that correctly, but what gets returned from that call is still just the original image element, not both. So when you call wrap, you are only calling it on the original image tag. By wrapping first, the image tag becomes the child of the wrapped element, then after will insert it in the correct location.
This might be clearer,
var myImage = $(this);
myImage.after(imageCaption);
myImage.wrap('<div class="imageBlock '+array[0]+'" />');
See the problem?
try
$(document).ready(function() {
$('#x').wrap('<div class="imageBlock">');
$('<span class="caption">The Caption</span>').insertAfter($('#x'));
});
'x' is the ID attribute value of <img src="whatever"> element
Here is a fiddle to start you off:
http://jsfiddle.net/c3nxe/
I'm new at javascript and while there are many more complex solutions, I don't understand them and hope I don't have to at this point.
I have a main picture...
<img src="main-picture.jpg" name="Mainpic" id="image">
...and I want to be able to change this picture when I click on one of two thumbnails.
<img src="replacement1.jpg" name="pic1">
<img src="replacement2.jpg" name="pic2">
My javascript code I thought would be super easy. I'm currently using...
function FirstPic(){
document.Mainpic.src = document.pic1.src
return
}
function SecPic(){
document.Mainpic.src = document.pic2.src
return
}
Now the variable is changing however it's not staying changed. When the thumbnail is clicked on, the replacement picture flashes on the screen and then it returns to the original main-picture.jpg.
How do I make the change permanent until a different thumbnail is clicked?
Thanks!
I think it's flipping back because your page is reloading.
You need to return false from your onclick= if you don't want the href= value to activate after your onclick.
Also, you can set href="#" just in case. # goes nowhere (doesn't ever reload the page)
I think your page is refreshing by your click, change your links as :
<img src="replacement1.jpg" name="pic1">
<img src="replacement2.jpg" name="pic2">
Why not do something like this (haven't checked the syntax completly, so it could be faulty.
function FirstPic()
{
var pic1 = document.getElementById("pic1");
if (pic1 == typeof('undefined')) return;
pic1.src = "newpicname.jpg";
}
Make sure you give the tags an ID attribute called pic1 and pic2 (instead of a name attribute) and give the image itself an 'onclick' attribute...
<img onclick='FirstPic()' id='pic1' src='image1.jpg' />