I'd like to display the alt text for an image as a paragraph with a class using vanilla JavaScript.
Example:
<img src="image.jpg" alt="These are planets">
Rendered As:
<img src="image.jpg" alt="These are planets">
<p class="photo-caption">These are planets</p>
Try the following. Note that it uses es6 functions
const images = Array.from( document.querySelectorAll('img') );
images.forEach(image => {
let alt = image.getAttribute('alt');
if( alt )
{
image.insertAdjacentHTML('afterEnd', `<p class="caption">${alt}</p>`);
}
});
<img src="https://placeimg.com/240/280/any" alt="These are planets">
<img src="https://placeimg.com/240/280/any" alt="These are something">
<img src="https://placeimg.com/240/280/any" alt="Something else">
<img src="https://placeimg.com/240/280/any" alt="Something">
In case it's useful to anyone here's what I ended up with and it worked perfectly. This is useful if you'd like to selectively add captions to images without adding additional HTML to your Markdown:
Jekyll/Github pages markdown:
![These are planets](path/to/image.jpg){: .add-caption}
On build it will render:
<img class="add-caption" src="image.jpg" alt="These are planets">
Using #SuperDJ's JS
const images = Array.from( document.querySelectorAll('.add-caption') );
images.forEach(image => {
let alt = image.getAttribute('alt');
if( alt )
{image.insertAdjacentHTML('afterEnd', `<p class="photo-caption">${alt}</p>`);}
});
Final Output HTML:
<img class="add-caption" src="image.jpg" alt="These are planets">
<p class="photo-caption">These are planets</p>
Add CSS:
.photo-caption {
color: #999;
font-size: .5rem;
text-align:center;
}
Hope it's helpful to you. I searched the web for an hour and couldn't find a solution.
Related
I have just started with Javascript/HTML and am wondering how I could create a page that has say, 2 images on and when you click on an image text relevant to that image appears?
My images are listed as below:
<img class="thumb" data-ord="1" onclick='changeMainImg(this);' src="full/01.jpg">
My changeMainImg function:
function changeMainImg1(that) {
document.getElementById("fullview").src=that.src;
current=that;}
Can I implement the text in the function so that each of the two different images has its own text?
Thank you
There are several ways to achieve this. If text is short, you can add it as a dataset attribute in the same img tag like this:
<img class="thumb" data-ord="1" data-text="my text" onclick='changeMainImg(this);' src="full/01.jpg">
function changeMainImg1(that) {
document.getElementById("fullview").innerHTML = that.dataset.text;
}
Other way is to define a variable with all texts and call it by index:
<img class="thumb" data-ord="0" onclick='changeMainImg(this);' src="full/01.jpg">
var texts = [
'text 1',
'text 2'
];
function changeMainImg1(that) {
document.getElementById("fullview").innerHTML = texts[that.dataset.ord];
}
I assume displaying the src attribute works for you. Below a possible solution. Prerequisite is to assign the same class name to each image involved.
/* Store image elements in an array */
const images = [... document.getElementsByClassName('thumb')];
/* Assign event listener to each image element */
images.map( (image) => image.addEventListener( "click", function()
{ alert(image.src) }
));
<img class="thumb" data-ord="1" src="full/01.jpg">
<img class="thumb" data-ord="2" src="full/02.jpg">
<img class="thumb" data-ord="2" src="full/03.jpg">
<img class="thumb" data-ord="2" src="full/04.jpg">
<img class="thumb" data-ord="2" src="full/05.jpg">
I was looking for a way to change image A to B and B to A by just
clicking them.
So far, this is what I'm using.
<img id="pixelbutton" src="images/pixelbutton.png" />
<img id="pixelbutton2" src="images/pixelbutton_press.png" style="display: none;" />
<script type="text/javascript">
$(document).ready(function(){
$("#pixelbutton").click(function(){
$("#pixelbutton").css({'display':'none'})
$("#pixelbutton2").css({'display':'block'});
})
$("#pixelbutton2").click(function(){
$("#pixelbutton2").css({'display':'none'})
$("#pixelbutton").css({'display':'block'});
})
})
</script>
The script works well for a pair of image.
Now if I have 100 pair of image.
"A <--> B"
"C <--> D"
"E <--> F"
and so on...
Do I have to copy the body HTML and script 100 times and change their ID+URL or there is another more efficient way?
To create hundreds of them... First, use a class.
Then, use a data attribute to store the "alternate" URL.
<img class="pixelbutton" src="images/pixelbutton.png" data-altsrc="images/pixelbutton_press.png"/>
<script type="text/javascript">
$(document).ready(function(){
$(".pixelbutton").click(function(){
// Get the two values
var src = $(this).attr("src");
var altSrc = $(this).data("altsrc");
// Switch them
$(this).attr("src",altSrc).data("altsrc",src);
});
})
</script>
This will work for thousands of .pixelbutton...
;)
EDIT
As per this other .data() documentation, (I wonder why there's two different documentation pages...) the data-* have to be lowercase... Because when trying to get altSrc, it is interpreted as alt-src.
I just learned that... That is quite a strange new standard, from jQuery 3.
So here is your CodePen updated.
You could probably set a naming pattern and use delegation to make an event handler on the images' container.
You could check if the event's target is an image and retrieve its id. Using that id, you could use the pattern you've set to change the images interchangeably.
There are multiple solutions to this, but this is by far the simplest approach:
Wrap your image pairs in a parent <div>
Use .toggleClass() to toggle a class, say .hide, in the images in the element
This solution assumes that you have images in pairs :) see proof-of-concept example:
$(document).ready(function() {
$('img').click(function() {
console.log($(this).siblings());
$(this).add($(this).siblings()).toggleClass('hide');
});
});
/* For layout only */
div {
display: inline-block;
}
/* Used to hide image */
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
<div>
<img src="http://via.placeholder.com/100x100/999999/ffffff" />
<img src="http://via.placeholder.com/100x100/b13131/ffffff" class="hide" />
</div>
Try this one:
jQuery(document).ready(function($) {
var $imgBlock = $('#images');
var html = '';
var imgArr = [
'http://i0.wallpaperscraft.com/image/surface_shape_metal_116716_200x300.jpg',
'http://i0.wallpaperscraft.com/image/universe_space_face_rocket_116714_200x300.jpg',
'http://i0.wallpaperscraft.com/image/letter_surface_wooden_116674_200x300.jpg',
'http://i0.wallpaperscraft.com/image/mountains_lake_reflection_116663_200x300.jpg',
'http://i1.wallpaperscraft.com/image/leaf_drops_surface_116678_200x300.jpg',
'http://i1.wallpaperscraft.com/image/candle_spruce_christmas_decoration_116684_200x300.jpg'
];
$.each(imgArr, function(index, url) {
html += (index % 2 === 0) ? '<div>' : '';
html += '<img src="' + url + '"/>';
html += (index % 2 === 1 || index === imgArr.length - 1) ? '</div>' : '';
});
$imgBlock.append(html);
$imgBlock.on('click', 'img', function(e) {
$(this).parent('div').find('img').removeClass('red');
$(this).addClass('red');
});
});
img {
border: 2px solid #ccc;
}
.red {
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="images"></div>
I tried everything and couldn't link my Image IDs to a preloaded Generic.js file in the Head section. Here's my HTML below:
<div id="bgimgwrapper">
<noscript>
<div>
<img id='bgNoScript' src='index_files/background1.jpg'
alt='' title='' width='100%' height='100%' />
</div>
</noscript>
<img class="active" id="bg0" src="index_files/background1.jpg"
style="width: 100%; display: none;">
<img id="bg1" src="index_files/background2.jpg"
style="width: 100%; display: block;">
</div>
bg0 and bg1 should be assigned to a function inside the preloaded generic.js, here's the function:
function bgStart() {
setCurrentCycle();
$bg = $('<img style="width:100%">'), bg = $bg[0];
$bg.hide().load(bgLoad);
$bg.addClass("active");
bg.id = "bg" + currentCycle;
bg.src = slideArray[currentCycle];
$bg.appendTo("#bgimgwrapper");
theWindow.resize(resizeBg)
}
bgStart() basically is a background image slider. In firebug though, I can't even see the evaluation "ev" sign next to each ID divs. Appreciate your comments.
don't understand why you are using 2 references for your new bg element... how about:
$bg = $('<img style="width:100%">');
$bg.hide().load(bgLoad)
.addClass("active")
.attr('id', 'bg' + currentCycle)
.attr('src', slideArray[currentCycle])
.appendTo("#bgimgwrapper");
theWindow.resize(resizeBg);
Essentially I have an interactive map which contains 4 div statements each of which contains an image of an island. I would like to create an on hover event which will display a corresponding sailing timetable depending on which image the user hovers. e.g. island 1 should display timetable 1.
I have the following code so far and ideally I am looking for a javascript or css solution:
<div class="Map">
<div id="Island_Morar">
<img src="images/IsleOfMorar.jpg"/>
</div>
<div id="Island_Rum">
<img src="images/IsleOfRum.jpg"/>
</div>
<div id="Island_Eigg">
<img src="images/IsleOfEigg.jpg"/>
</div>
<div id="Island_Muck">
<img src="images/IsleOfMuck.jpg"/>
</div>
</div>
<img id="TimetableEigg" src="images/TimetableEigg.jpg">
any help is appreciated.
You need some different markup if you want a plain css solution. If you want to have different timetables for each hover you should go with something like this:
markup
<div class="tt-container" id="Island_Rum">
<img src="images/IsleOfRum.jpg"/>
<img class="timetable" src="images/TimetableRum.jpg">
</div>
<div class="tt-container" id="Island_Eigg">
<img src="images/IsleOfEigg.jpg"/>
<img class="timetable" src="images/TimetableEigg.jpg">
</div>
<div class="tt-container" id="Island_Muck">
<img src="images/IsleOfMuck.jpg"/>
<img class="timetable" src="images/TimetableMuck.jpg">
</div>
</div>
css
.timetable {
display : none;
}
.tt-container:hover .timetable {
display : block;
}
That should do the trick
If you want to keep your current HTML code, I'd make three image blocks for timetables, and initially set them all to display: none; and add onmouseover event handlers to island elements which would contain Javascript statement which will set disply: block; on appropriate timetable.
Something like this:
<div class="Map">
<div id="Island_Morar" onmouseover="document.getElementById('TimetableEigg1').style.display = 'block';">
<img src="images/IsleOfMorar.jpg"/>
</div>
<div id="Island_Rum" onmouseover="document.getElementById('TimetableEigg2').style.display = 'block';" >
<img src="images/IsleOfRum.jpg"/>
</div>
<div id="Island_Eigg" onmouseover="document.getElementById('TimetableEigg3').style.display = 'block';" >
<img src="images/IsleOfEigg.jpg"/>
</div>
<div id="Island_Muck" onmouseover="document.getElementById('TimetableEigg4').style.display = 'block';" >
<img src="images/IsleOfMuck.jpg"/>
</div>
</div>
<img id="TimetableEigg1" src="images/TimetableEigg1.jpg">
<img id="TimetableEigg2" src="images/TimetableEigg2.jpg">
<img id="TimetableEigg3" src="images/TimetableEigg3.jpg">
<img id="TimetableEigg4" src="images/TimetableEigg4.jpg">
Seems you barely know the basics of HTML and already trying to jump too deep. External libraries will help you and speed up your progress. I see people gave you CSS solutions so here is a JS solution.
First thing is download the well known JS library called jQuery.
then load this file to your page and add a script at the bottom of your body tag:
$("div.map").on("mouseover", "#Island_Morar", function(e) {
$(this).show(); // option one
//$(this).addClass("class-name"); // option two
}).on("mouseout", "#Island_Morar", function(e) {
$(this).hide(); // option one
//$(this).removeClass("class-name"); // option two
});
With this script you can do whatever you want, for example - use the second option of adding and removing classes in order to animate your Timetables (see Example).
Possible CSS / JQuery solution:
$(".Map a").hover(
function() {
$('#' + $(this).attr('class')).show();
}, function() {
$('#' + $(this).attr('class')).hide();
}
);
.timetables img { display:none; }
<div class="Map">
<a href="#" class="islandmorar">
<img src="images/IsleOfMorar.jpg"/>
</a>
<a class="islandrum">
<img src="images/IsleOfRum.jpg"/>
</a>
<a class="islandeigg">
<img src="images/IsleOfEigg.jpg"/>
</a>
<a class="islandmuck">
<img src="images/IsleOfMuck.jpg"/>
</a>
</div>
<div class="timetables">
<img id="islandmorar" src="images/TimetableEigg.jpg"/>
<img id="islandrum" src="images/TimetableEigg.jpg"/>
<img id="islandeigg" src="images/TimetableEigg.jpg"/>
<img id="islandmuck" src="images/TimetableEigg.jpg"/>
</div>
Pure CSS solution but you need to place the large image in .main div
the first image will be displayed first and will change on hover on other images and when you leave move out of the main div it will show the first image
Note: used random images
.Map > div {
display: inline-block;
}
img.two,
img.three,
img.four,
#Island_Rum:hover ~ img.one,
#Island_Muck:hover ~ img.one,
#Island_Eigg:hover ~ img.one {
display: none;
}
img.one {
display: block;
}
#Island_Morar:hover ~ img.one {
display: block;
}
#Island_Rum:hover ~ img.two {
display: block;
}
#Island_Eigg:hover ~ img.three {
display: block;
}
#Island_Muck:hover ~ img.four {
display: block;
}
<div class="Map">
<div id="Island_Morar">
<img src="http://placeimg.com/100/100/any/animals" />
</div>
<div id="Island_Rum">
<img src="http://placeimg.com/100/100/any/arch" />
</div>
<div id="Island_Eigg">
<img src="http://placeimg.com/100/100/any/nature" />
</div>
<div id="Island_Muck">
<img src="http://placeimg.com/100/100/any/tech" />
</div>
<img class="one" src="http://placeimg.com/400/400/any/animals" />
<img class="two" src="http://placeimg.com/400/400/any/arch" />
<img class="three" src="http://placeimg.com/400/400/any/nature" />
<img class="four" src="http://placeimg.com/400/400/any/tech" />
</div>
Don't put class="map" to the wrapper div, give it to every div with id beginning with "Island_...".
Do the same with your timeTable images, give them a class "timeTable".
Put this before your "head" end tag :
<script>
"use strict";
//wait for every element to be loaded
window.onload = function(){initialization();}
</script>
Then, put this before your "body" end tag :
<script>
"use strict";
//first create a function that hides elements with class 'timeTable'
function hide(elements){
var htmlClass = document.getElementsByClassName(elements);
//hide every element with class
for (var i = 0 ; i < htmlClass.length ; i++){
htmlClass[i].style.display = "none";
htmlClass[i].style.visibility = "hidden";
}
}
//create a function that show only the timeTable you want
function show(element){
document.getElementById(element).style.display = "block";
document.getElementById(element).style.visibility = "visible";
}
function initialization(){
//replace 'someMapId' with the id of the image you are hovering
//replace 'someTimeTableId' with the id of the image you want to show
//replace 'timeTable' with the name of a class you want to hide
document.getElementById("someMapId").onmouseover = function(){
hide("timeTable");
show("someTimeTableId");
}
//repeat these 3 lines for every image the user will hover
}
</script>
Don't forget the quotes when using the functions.
You should use css for styling and javascript for interactions.
You don't need jQuery for basic scripts like that, it only slows page loading and keeps you away from learning basic javascript.
(Ok, I edited mistakes, now it works ;)
jsFiddle
Ive made a basic "gallery" which uses the function below to show a larger picture when clicking on thumbnails. I want to make an animation to transition the thumbnail in to the bigger image. for example the thumbnail could slide to the place of the bigger image and spread to it or something along those lines.
function Kuvansuurennus(pic)
{
document.getElementById("peukalokuva").style.visibility="visible"
document.getElementById("peukalokuva").src=pic
}
Some style definitions I use
.thumb
{
height:150px;
width:200px;
}
#peukalokuva
{
float:right;
margin-right:4%;
width:70%;
visibility:hidden;
}
And the images I use and the target image for the bigger images
<img id="peukalokuva">
<div>
<img class="thumb" src="kuva1.jpg" onclick="Kuvansuurennus(this.src)"/>
<br>
<img class="thumb" src="kuva2.jpg" onclick="Kuvansuurennus(this.src)"/>
<br>
<img class="thumb" src="kuva3.jpg" onclick="Kuvansuurennus(this.src)"/>
<br>
<img class="thumb" src="kuva4.jpg" onclick="Kuvansuurennus(this.src)"/>
<br>
<img class="thumb" src="kuva5.jpg" onclick="Kuvansuurennus(this.src)"/>
<br>
<img class="thumb" src="kuva6.jpg" onclick="Kuvansuurennus(this.src)"/>
</div>
Thats the code, so how should I modify the funktion to get an animated transition from thumbnail to larger image?
You could do something with the format of...
$('img.thumb').click(function(){
var source = $(this).attr('src');
$('#peukalokuva').show().attr('src', source);
});
This would mean you wouldn't need click handlers in your html. You would want to reference a larger image though. Possibly in a different folder. source = 'large/' + $(this).attr('src')