I know how to do this in jquery but i am trying to do the below in pure old school javascript. Can someone help:
$(".thumbnail").click(function() {
$("#mainImage").attr("src", $(this).attr("src"));
});
My ultimate goal is to click on a thumbnail and have the main image change but I need to do it in javascript (no jquery). I know this sounds pretty simple but I cannot figure it out. thank you.
There are so many things that jQuery gives you automatically that it's difficult to give you an answer that will do everything that your jQuery code does. Here is a simple example that will find every image with a class of thumbnail and set its onclick property to an event handler that performs an image swap.
onload = function () {
var bigImg = document.getElementById("mainImage");
for (var i = 0; i < document.images.length; i++) {
var img = document.images[i];
if (/\bthumbnail\b/.test(img.className) {
img.onclick = thumbnailHandler;
}
}
function thumbnailHandler(e) {
bigImg.src = this.src;
}
};
If you don't have to support IE7, you can simplify it slightly by using document.querySelectorAll():
onload = function () {
var bigImg = document.getElementById("mainImage");
var thumbs = document.querySelectorAll(".thumbnail");
for (var i = 0; i < thumbs.length; i++) {
thumbs[i].onclick = thumbnailHandler;
}
function thumbnailHandler(e) {
bigImg.src = this.src;
}
};
As an aside, I don't understand why you are setting the source of the main image to be the source of the thumbnail. Are you loading the full image into the thumbnail? That can be a lot to download and can quickly increase the memory footprint of your page.
Event delegation is probably the easiest way:
function expandThumbnail(e) {
if(~(' ' + e.target.className + ' ').indexOf(' thumbnail ')) {
document.getElementById('mainImage').src = e.target.src;
}
}
if(document.addEventListener) {
document.addEventListener('click', expandThumbnail, false);
} else {
document.attachEvent('onclick', function() {
expandThumbnail({
target: event.srcElement
});
});
}
If I understand right, you have a thumbnail image displayed, let's say '1thumb.png', of an associated image, let's say '1.png', and when you click this thumbnail image you want to change the src attribute of a main image, let's say with id='mainimg', to show the '1.png' image associated to the thumbnail instead of whatever it's showing. I tried this and it works:
Inside your <header>:
<script type='text/javascript'>
function myHandler(source){
document.getElementById('mainimg').src=source;
}
</script>
...
Your thumbnail code:
<img src='1thumb.png' onclick="myHandler('1.png')"/>
or, for rollover triggering:
<img src='1thumb.png' onmouseover="myHandler('1.png')"/>
Check it out: http://jsfiddle.net/d7Q27/7/
Related
I am using THIS script to display my galleries in lightbox. I was using some plugins but all of them does not display the alt=""(alt added in media in wordpress).
How can I modify the code from the link below to display the alt attributes ?
I found something in the code, but I dont know how to put the dynamic alt there(commented by uppercase text in the code). Dynamic I mean that as user will add the img in wordpress dashboard, he will put the alt then.
{
key: '_preloadImage',
value: function _preloadImage(src, $containerForImage) {
var _this4 = this;
$containerForImage = $containerForImage || false;
var img = new Image();
if ($containerForImage) {
(function () {
// if loading takes > 200ms show a loader
var loadingTimeout = setTimeout(function () {
$containerForImage.append(_this4._config.loadingMessage);
}, 200);
img.onload = function () {
if (loadingTimeout) clearTimeout(loadingTimeout);
loadingTimeout = null;
var image = $('<img />');
image.attr('src', img.src);
image.addClass('img-fluid');
image.attr('alt',"Temp TEXT"); // HERE I WOULD LIKE TO DISPLAY THE ALT AUTOMATICALLY - NOT STATIC AS IT IS NOW
// backward compatibility for bootstrap v3
image.css('width', '100%');
$containerForImage.html(image);
if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
_this4._resize(img.width, img.height);
_this4._toggleLoading(false);
return _this4._config.onContentLoaded.call(_this4);
};
img.onerror = function () {
_this4._toggleLoading(false);
return _this4._error(_this4._config.strings.fail + (' ' + src));
};
})();
}
img.src = src;
return img;
}
},
I am using wordpress on my page and my skills in JS are rather poor, so I am asking you :).
We don't really know what is the type of your img variable. If you want to set the alt tag of image to the one of img, simply do:
image.attr('alt', img.attr('alt'));
…if it's a jQuery object. Otherwise, if img is pure JavaScript, you can do:
image.attr('alt', img.alt);
if the img object holds the existing alt and image is the new jQuery object, then set it with jQuery
image.attr('alt', img.getAttribute('alt'))
I want to load all images before displaying them in a slideshow. I have been searching a lot but nothing seems to work. This is what i have so far and it doesn't work. I am loading images from the <a> tag from another div.
$('.slideshow').load(function(){
if (loaded<length){
first = $(settings.thumb).eq(loaded).find('a').attr("href");
$('<img src="'+first1+'"/>').appendTo('.slideshow');
}
else{ $('.slideshow').show(); }
loaded++;
});
Add an event listener to each image to respond to when the browser has finished loading the image, then append it to your slideshow.
var $images = $("#div_containing_images img");
var numImages = $images.length;
var numLoaded = 0;
var $slideshow = $(".slideshow");
$images.each(function() {
var $thisImg = $(this);
$thisImg.on("load", function() {
$thisImg.detach().appendTo($slideshow);
numLoaded++;
if (numLoaded == numImages) {
$slideshow.show();
}
});
});
It's a good idea to also listen for the error event as well, in case the image fails to load. That way you can increase numLoaded to account for broken image. Otherwise, your slideshow will never be shown in the event the image is broken.
Also note, that by calling detach() followed by appendTo() I am am moving the image in the DOM. If instead, you want to copy the image, use clone() instead of detach().
* EDIT TO MODIFY USER'S EXACT USE CASE *
var $images = $("li.one_photo a");
var numImages = $images.length;
var numLoaded = 0;
$images.each(function() {
$('<img />',
{ src: $(this).attr("href") })
.appendTo('.slideshow')
.on("load error", function() {
numLoaded++;
if(numLoaded == numImages) {
$('.slideshow').show();
}
});
});
* EDIT #2 *
Just realized you were putting everything in the $(".slideshow").load() function. Since $(".slideshow") represents a DIV, it will never raise a load event, and the corresponding function will never execute. Edited above accordingly.
This javascript code is supposed to switch when clicked an image to images from a folder within the html file folder.
After it gets to the last image, if you click again it resets to the first image.
Also there's a fade in and out effect on the appearing images.
It doesn't work and I suspect I wrote the path files to the images wrong somehow and the .attr doesn't change the src of the first image to the others.
Things to keep in mind = an extremely beginner programmer, just picked up html and css in about 2 days, I would appreciate any kind of help!
This is the code:
$(document).ready(function() {
var imageName = ["head.jpg", "head3.jpg", "head4.jpg"];
var indexNum = 0;
$("#head1").click(function() {
$("#head1").fadeOut(300, function() {
$("#head1").attr("src", imageName[indexNum])";
//$(indexNum).css("height=600px,width=1000px")
indexNum++;
if (indexNum > 2) {
indexNum = 0;
}
$("#head1").fadeIn(500);
)};
)};
)};
You got a couple of errors in your code,
You swapped the closing ")" and "}" in the last two lines and you have a random " in the code.
Here's a working example:
$(document).ready(function() {
var imageName = ["http://placehold.it/200x200", "http://placehold.it/300x300", "http://placehold.it/400x400"];
var indexNum = 0;
$("#head1").click(function() {
indexNum = (indexNum + 1) % imageName.length; // this will count 0,1,2,0,1,2,0,1,2... always looping through your images
$(this).fadeOut(function() { //in this context, this refers to the #head, reading it from the DOM over and over again isn't efficient
$(this).attr("src", imageName[indexNum]);
}).fadeIn();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="head1" src="http://placehold.it/200x200" alt="">
Just a small note: Your script (and mine) don't take into account loading times, this means that it will probably work fine on your computer, locally, but once you put it on a server, you will see the image fadeout, then fadein and still be the same image and then swap to the new image all of a sudden. This happens because it has some loading time. If you want to fix this you'll need some other events. Or you could load all images into the page and then just swap the one that is currently shown.
Even thought this has been answered, here is a fiddle with your original code corrected. http://jsfiddle.net/goqz3coj/
Its better to see how your code should work instead of been giving a different code
$(document).ready(function() {
var imageName = ["head.jpg", "head3.jpg", "head4.jpg"];
var indexNum = 0;
$("#head1").click(function() {
$("#head1").fadeOut(300, function() {
$("#head1").attr("src", imageName[indexNum]);
indexNum++;
if (indexNum > 2) {
indexNum = 0;
}
$("#head1").fadeIn(500);
});
});
});
SECOND VERSION Waits for image load before showing again...
http://jsfiddle.net/goqz3coj/2/
By simply using .load you can wait for the image to load and then show.
$(document).ready(function() {
var imageName = ["http://placehold.it/200x200", "http://placehold.it/300x300", "http://placehold.it/400x400"];
var indexNum = 0;
$("#head1").click(function() {
$("#head1").fadeOut(300, function() {
$( "#head1" ).load(function() {
$("#head1").fadeIn(500);
// Handler for .load() called.
});
$("#head1").attr("src", imageName[indexNum]);
indexNum++;
if (indexNum > 2) {
indexNum = 0;
}
});
});
});
Jonas Grumann took your image urls as easier to show with actual images.
Can images be preemptively loaded into the page with javascript so that they can be used at any time as a CSS background image without any request/upload delay?
If so, how?
You don't even need to use JS for this (with the downside of delaying the page load event). Include something like this:
<img src="/path/to/image.jpg.png.gif.bmp" style="display: none" />
This will trigger a request for the image, and add it to the local cache. When you set the CSS background-image property, the image will already be in the local cache, eliminating the delay of another request.
Alternatively, you can accomplish the same thing without delaying the page load by creating the images in JavaScript (this solution allows for multiple images):
function preload(list, callback, imageCallback) {
var at, len;
at = len = list.length;
for (var i = 0; i < len; i++ ) {
var img = new Image();
img.onload = function() {
if( imageCallback ) {
imageCallback.call(this, this, len-at, len);
}
if( !--at ) {
callback(list);
}
};
img.src = list[i];
list[i] = img;
}
}
You'd call this with:
var list = preload(["1.png","2.png","3.png" ... ], function complete(list) {
console.log('images all loaded!');
}, function loaded(image, index, listCount) {
console.log('image ' + index + ' of + 'listCount + 'is loaded');
});
(Thanks to #rlemon for the preload code)
I don't think that using an hidden img tag is the correct way, i'd rather use an "new Img(url)" and attaching to it an onload event where you can set the image as background-image to the element you want.
img = new Image();
img.onload = function(){
// set background-image
};
img.src = image_url;
be sure to put img.src after attaching onload, or you risk that the image is loaded before the event is attached.
Maybe a more complete base to build on:
function preload(list, callback, imageCallback, errorCallback) {
if (typeof(list) === "undefined"
|| list.length === 0) {
return;
}
var len = list.length;
var timers = {};
var checkLen0 = function() {
if (len === 0) {
if (typeof(callback) === "function") {
callback();
}
delete(timers)
}
}
var onload = function() {
clearTimeout(timers[img]);
if (typeof(imageCallback) === "function") {
imageCallback.call(img);
}
len--;
checkLen0();
}
var onerror = function() {
clearTimeout(timers[img]);
if (typeof(errorCallback) === "function") {
errorCallback.call(img);
}
len--;
checkLen0();
}
for (var i = 0; i < list.length; i++ ) {
var img = new Image();
img.onload = onload;
timers[img] = window.setTimeout(5000, onerror);
img.src = list[i];
}
}
While SomeKittens answer is valid, it'll delay the page load as commented by Jimmy. If you are using jquery, I'd go with something like this instead to keep your style, structure and logic separated:
<style>
.preload-img { display: none; }
</style>
...
<div class = "preload-img">/path/to/image.jpg.png.gif.bmp</div>
...
<script>
$(document).ready(function(){
$(".preload-img").each(function(){
preloadImage = new Image();
preloadImage.src = $(this).html();
});
});
</script>
Of course, from there on you can optimize/change it. The advantadge of this is that you can create the <div> dynamically with PHP and you can have all your javascript cached properly as a separated file.
There is an excellent framework for this job called Emerge.js
http://ilyabirman.net/projects/emerge/
Quote from project page:
Emerge.js is a framework for coordinated page loading. Normally, when a complex web page is loading, images appear in random order, causing unpleasant flashing. To replace it with nice and coordinated animations, programming is required. Emerge.js simplifies the task by removing the need to write any Javascript code. The framework uses a declarative approach, where you specify a desired behavior for each element and do not think about the implementation. Emerge.js uses jQuery.
Just as a caveat to SomeKittens' answer above, a particularly large background image should probably be added as a hidden background / via JavaScript after page load, as content images delay the firing of window.onload and may therefore create the perception of a slow loading page.
Given that it sounds like you're using dynamic content anyway, this may be an acceptable solution. It also allows you to do preloading programmatically as required, which may be better for maintenance.
I am trying to change the HTML image src using Javascript. I have two images Plus.gif and Minus.gif.I have inserted HTML img tag and have written a Javascript function to change the image src when clicked.
Problem is that I want to change it back again when user clicks on the image.
For example when the page is loaded the Plus.gif shows and when user clicks on it the image it changes to Minus.gif.
I want it so, when the image is Minus.gif and user clicks on it this should be changed to Plus.gif.
Here is my Javascript function:
<script language="javascript" type="text/javascript">
function chngimg() {
var img = document.getElementById('imgplus').src; //= 'Images/Minus.gif';
if (img) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
} else if (!img) {
document.getElementById('imgplus').src = 'Images/Plus.gif';
alert(img);
}
}
</script>
Image tag:
<img id="imgplus" alt="" src="Images/Plus.gif" onmouseover="this.style.cursor='pointer'" onclick="chngimg()" />
See the changes I made to make it working
<script language="javascript" type="text/javascript">
function chngimg() {
var img = document.getElementById('imgplus').src;
if (img.indexOf('Plus.gif')!=-1) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
}
else {
document.getElementById('imgplus').src = 'Images/Plus.gif';
}
}
</script>
<img id="imgplus" alt="" src="Images/Plus.gif" onmouseover="this.style.cursor='pointer'" onclick="chngimg()" />
Hope that resolves your question.
One way would be to add a toggle variable in your function:
var toggle = false;
function chngimg() {
if (toggle === true) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
} else {
document.getElementById('imgplus').src = 'Images/Plus.gif';
alert(img);
}
toggle = !toggle;
}
Note that it's a better practice to use a sprite for this kind of thing. If you're using two images, the user experience is going to be clunky, because the first time they click the image, there will be a slight delay while the second image loads.
Ideally you would have the two images as a sprite sheet, and be using JQuery. Then you could just do it like this.
HTML
<img id="imgplus" src="Images/Sprite.gif" onclick="chngimg()" />
CSS
#imgplus .clicked { background-position: 0 -30px; }
Javascript
function chngimg() {
$("#imgplus").toggleClass("clicked");
}
I have successfully used this general solution in pure JS for the problem of toggling an img url:
function toggleImg() {
let initialImg = document.getElementById("img-toggle").src;
let srcTest = initialImg.includes('initial/img/url');
let newImg = {
'true':'second/img/url',
'false':'initial/img/url'}[srcTest];
return newImg;
}
Then call toggleImg() inside whatever event handler you use....
someButton.addEventListener("click", function() {
document.getElementById("img-toggle").src = toggleImg();
}