Using vanilla JS to set image src from data-attribute - javascript

I'm looking for a way to set the src of an image - in a modal - using the data attribute of a clickable element.
The markup for the element looks like this (there could be multiple of these on a page):
<span class="tooltip" data-imageToSet="someimage.jpg">Click me</span>
<div id="modal">
<img id="image" src="placeholder.jpg" />
</div>
<script>
var modal = document.getElementById('modal'),
modalImage = document.getElementById('image');
document.addEventListener('click', function(event) {
if (event.target.classList.contains('tooltip')) {
modal.classList.toggle('shown');
modalImage.src = event.currentTarget.dataset.imageToSet;
}
});
</script>
From what I've been reading up, this should work? But I keep getting a console error:
Uncaught TypeError: Cannot read property 'imageToSet' of undefined at HTMLDocument.<anonymous> ((index):1)

You have two issues. currentTarget will be the element you bound the click to so it will be document. The second issue is camel case does work with dataset, you need to use dash.
var modal = document.getElementById('modal'),
modalImage = document.getElementById('image');
document.addEventListener('click', function(event) {
if (event.target.classList.contains('tooltip')) {
modal.classList.toggle('shown');
console.log(event.target)
modalImage.src = event.target.dataset.imageToSet;
}
})
<span class="tooltip" data-image-to-set="http://placekitten.com/300/300">Click me</span>
<div id="modal">
<img id="image" src="http://placekitten.com/g/200/300" />
</div>

First you check if the target (i.e. the element that is clicked) has the tooltip class
event.target.classList.contains('tooltip')
But then you use the currentTarget (i.e. the element to which the event handler is bound: document) to read the dataset.
modalImage.src = event.currentTarget.dataset.imageToSet
You need to continue to use the target throughout.

Related

How get src value when click on one of the mulitple images in javascript?

I have 3 images in my web page. I want to get src value every time when I clicked on any image. I tried following code but its not working with multiple images.
<div class="test">
</div>
</div>
</div>
</div>
<script type="text/javascript">
function filename(){
//var fullPath = document.getElementsByClassName('dImage').src;
var fullpath = document.getElementsByClassName('dImg').src
console.log(fullPath);
var filename = fullPath.replace(/^.*[\\\/]/, '');
var fileid = filename.split("\deckel.")[0];
//window.location.href = "web-rocketcreator.html?="+fileid;
console.log(fileid);
}
</script>
As the other answers have mentioned the specific problem area, here's an alternative solution.
Instead of attaching a click event to each image you can attach one to the container and listen for events as they bubble up the DOM (known as event delegation.)
// Grab the container, and add an event listener to it
const imageContainer = document.querySelector('.test');
imageContainer.addEventListener('click', filename, false);
function filename(event) {
// Pick out the src attribute from target element
// (the image that was clicked on)
const { target: { src } } = event;
// Use the src as the basis for the rest of
// your calculations
var filename = src.replace(/^.*[\\\/]/, '');
var fileid = filename.split("\deckel.")[0];
console.log(`web-rocketcreator.html?=${fileid}`);
}
.test a {
display: block;
}
<div class="test">
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-1.png" alt="">
</a>
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-2.png" alt="">
</a>
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-3.png" alt="">
</a>
</div>
To get a reference to the object which triggered the click event you need to pass the keyword this as a parameter.
In your case this object is the <a> element. To get it's nested children - the <img> element you need to call the .children method which returns an array. Since there's just the image element you can directly reference it using children[0] and ultimately add the .src property to retrieve the source.
function filename(element){
console.log(element.children[0].src);
}
<div class="test">
</div>
Get src value from image when clicking on it
When you call a function from onClick() you can pass 'this' to the function. This way you will directly have a reference to the clicked element inside the functon
<img src="xxxx.jpg" onclick="myFunction(this)" />
function myFunction(element) {
const src = element.src;
}
Get src value from image when clicking on parent container
<a onclick="myFunction(this)"><img src="xxxx.jpg" /></a>
function myFunction(link) {
const src = link.children[0].src
}

Can't add attributes to element with jQuery

I've CMS, which renders a markup in such a way where I can't add any additional id, class or events to elements.
In such a way I have to add them programmatically. The task is simple:
1). Find element by class name and add to its successor,(img) id name
2). add onClick attribute to it
3). execute script onClick (should swap the image and href's name (max 3 images))
JSFiddle
Here is a piece of markup:
<div class="single-image text-center to_change_inner">
<div class="content">
<div class="single-image-container">
<img class="img-responsive" src="https://picsum.photos/200/300">
</div>
</div>
</div>
<div>
<a id="btn-1559300726188">Click</a>
</div>
And here is a JQuery:
jQuery(function($) {
element1 = $('.to_change_inner').children('img'); //find() also doesn't work
element1.id="imgClickAndChange";
if (element1.addEventListener) {
element1.addEventListener("click", changeImage, false);
} else {
if (element1.attachEvent) {
element1.attachEvent("click", changeImage);
}
}
});
function changeImage() {
if (document.getElementById("imgClickAndChange").src == "https://picsum.photos/200/300")
{
document.getElementById("imgClickAndChange").src = "https://picsum.photos/20/30";
}
else
{
document.getElementById("imgClickAndChange").src = "https://picsum.photos/200/300";
}
}
window.addEventListener('load', function(){
document.getElementById('btn-1559300726188').setAttribute("onclick", "imgClickAndChange(); return true;");
});
jQuery objects are not DOM elements, they're sets of DOM elements.
To set an attribute on all elements in the set, use attr: element1.attr("id", "imgClickAndChange")
To set a property, use prop: element1.prop("id", "imgClickAndChange") (id happens to be the property reflecting the id attribute; src is also both an attribute and a reflected property).
To add an event handler, use on: element1.on("click", changeImage).
In general, setter methods in jQuery set them on all elements in the set, and getter methods get from the first element in the set (but there are exceptions).
If for any reason you need to directly access the DOM element(s) in the set, you can do that with brackets notation like with an array.
More in the API docs and the learning center.
According to your HTML, you have an error here:
element1 = $('.to_change_inner').children('img'); //find() also doesn't work
The comment is incorrect, find would be what you want there, not children:
var element1 = $('.to_change_inner').children('img'); // Doesn't work
console.log(element1.length); // 0, no matching elements
var element1 = $('.to_change_inner').find('img'); // Works
console.log(element1.length); // 1, there was a matching element
<div class="single-image text-center to_change_inner">
<div class="content">
<div class="single-image-container">
<img class="img-responsive" src="https://picsum.photos/200/300">
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
That code also seems to be falling prey to what I call The Horror of Implicit Globals, you need to declare element1.
Use this:
jQuery(function($) {
element1 = $('.to_change_inner img');
element1.attr('id',"imgClickAndChange");
element1.on('click',function(){changeImage();})
});
function changeImage() {
if (document.getElementById("imgClickAndChange").src == "https://picsum.photos/200/300")
{
document.getElementById("imgClickAndChange").src = "https://picsum.photos/20/30";
}
else
{
document.getElementById("imgClickAndChange").src = "https://picsum.photos/200/300";
}
}
window.addEventListener('load', function(){
document.getElementById('btn-1559300726188').setAttribute("onclick", "imgClickAndChange(); return true;");
});

How can I properly use '$(this)' to call a DOM element that triggered the event?

I wrote the following script that resets the the Iframe Source, removes a class (.play) and adds an image placeholder when .b-close is clicked. I got it to work but the problem is that I have multiple modals and I would like only like to affect the modal that's clicked. I figured that I should use the '$(this)' DOM element in order to achieve this.
<script>
(function($){
var ivid = $('.pretty-embed iframe').attr('src');
$(document).ready(function() {
$(".b-close").click(function(e){
e.preventDefault();
var vidID = $(this).parent().find('.pretty-embed').attr('data-pe-videoid');
var vidImg = "//img.youtube.com/vi/"+vidID+"/maxresdefault.jpg";
var vidImgUrl = '<img src="'+vidImg+'" width="100%" alt="YouTube Video Preview">';
$('.pretty-embed').removeClass('play').empty();
$('.pretty-embed').html(vidImgUrl);
$('.b-modal').click(); /// Just trying to close modal..... $.modal.close();
});
});
})(jQuery);
</script>
Here's is the the Modal that I will be calling. Keep in mind that there will be multiple modals, so I would only like to affect the modal that's clicked
<div id="element_to_pop_up" display: block;">
<a class="b-close">x</a>
<h3 class="pop-hd">Header</h3>
<p>Test Video</p>
<div class="pretty-embed play" data-pe-allow-fullscreen="false">
<iframe width="330" height="186" style="border:none;" src="//www.youtube.com/embed/nGSfaMxCu-U?autoplay=1&rel=1"></iframe>
</div>
</div>
The problem is in your $('.pretty-embed') selector which selects all the embed elements in all modals If I understood your problem correctly. To fix that take the id of the modal and prepend it to the selectors like below:
(function($){
var ivid = $('.pretty-embed iframe').attr('src');
$(document).ready(function() {
$(".b-close").click(function(e){
e.preventDefault();
var vidID = $(this).parent().find('.pretty-embed').attr('data-pe-videoid');
var vidImg = "//img.youtube.com/vi/"+vidID+"/maxresdefault.jpg";
var vidImgUrl = '<img src="'+vidImg+'" width="100%" alt="YouTube Video Preview">';
var parent_id = $(this).parent().attr(id);
// Prepend the parent id before the .pretty-embed selector
$('#'+parent_id+' .pretty-embed').removeClass('play').empty();
$('#'+parent_id+' .pretty-embed').html(vidImgUrl);
$('#'+parent_id+' .b-modal').click(); /// Just trying to close modal... $.modal.close();
});
});
Also you can use the same way you did it in the previous lines:
$(this).parent().find('.pretty-embed').removeClass('play').empty();
You can get the current modal with
var current_modal = $(this).parent().find('.pretty-embed');
Then remove the class play, and add your image like this:
current_modal.removeClass('play').empty();
current_modal.html(vidImgUrl);
See your complete code in this jsfiddle

Passing innerHTML to an element and attaching event

I have to pass innerHTML to a div using my JavaScript function.The innerHTML that I am passing also has a div for which I have to attach a click event so that on click of it, the element responds to the click event.
I have a fiddle here to explain the problem:
http://jsfiddle.net/K2aQT/2/
HTML
<body>
<div id="containerFrame">
</div>
</body>
JavaScript
window.onload = function(){usersFunction();};
function usersFunction(){
var someHtml = '<div> <div class ="btnSettings"> </div> <span></span> </div>';
changeSource(someHtml);
}
function changeSource(newSource){
document.getElementById("containerFrame").innerHTML = newSource;
}
While passing the source, how do I tell JavaScript function that this HTML being passed also has some element which has to be bound to a click event?
If you have to do it this way, you could consider adding the click handler inside the HTML string itself:
var someHtml = '<div> <div class ="btnSettings" onclick="return myFunction()"> </div> <span></span> </div>';
Alternatively, after modifying the .innerHTML, find the right <div>:
var frame = document.getElementById('containerFrame');
frame.innerHTML = newSource;
var settings = frame.getElementsByClassName('btnSettings')[0];
// depends on the browser, some IE versions use attachEvent()
settings.addEventListener('click', function(event) {
}, false);
i think you need something like that:
document.getElementById("containerFrame").onclick = function() {
// put your function here
};

find the img id and src and adding to the array

Heres my html code:
<div id="cmdt_1_29d" class="dt_state2" onclick="sel_test(this.id)">
<img id="cmdt_1_29i" onclick="dropit('cmdt_1_29');"
src="http://hitechpackaging.zes.zeald.com/interchange-5/en_US/ico_minus.png">
<span class="dt_link">
CARTON & BOARD
</span>
</div>
<div id="cmdt_2_31d" class="dt_istate1" onclick="sel_test(this.id)">
<img src="/site/hitechpackaging/images/items/test.jpb ">
CORRUGATED & CORNER BOARD
</div>
The dropit function modifies my img src which I dont want to, unfortunately I cant modify,
Can I somehow read the data into array before it is being modified and that I can add the data back to the image.
To remove the click handler:
var i = document.getElementById('cmd1_1_29i');
i.onclick = null;
Or, if you want to still call the original click handler:
var i = document.getElementById('cmd1_1_29i');
_onclick = i.onclick;
i.onclick = function(e) {
// do what you want here
_onclick && _onclick.apply(this, [e]);
}
​

Categories