I've searched the forums already but I couldn't find anything like this specifically.
I have a page set up with a bunch of images (gallery type thing) and when they user clicks on an image it will change size from the 200x200 thumbnail to the full sized 600x600.
My issue is that one can continue to click these images and the previous one will remain the enlarged. I would like to limit the amount of expanded images to one.
This is the javascript:
function toggleSize(image) {
if (image.style.width != "600px") {
image.style.width = "600px";
image.style.height = "600px";
} else {
image.style.width = "200px";
image.style.height = "200px";
}
and the html for each image is as follows:
<img class="galleryImage" src="../m/54.jpg" onclick="toggleSize(this)" />
the galleryImage class looks like this:
.galleryImage {
margin: -2px -2px -3px -2px;
width: 200px;
height: 200px;
}
So essentially, in theory, I would want every element of the class galleryImage to reset to its original width and height of 200x200.
Any help would be greatly appreciated.
You can search all your images with a given class (and discard the current) using getElementsByClassName and by looping the result resume them to the starting state.
Returns an array of all child elements which have any of the given
class names. When called on the document object, the complete document
is searched, including the root node. You may also call
getElementsByClassName() on any element; it will return only elements
which are descendants of the specified root element with the given
class names.
After this, you can call your toggle function.
Code:
function resetImages(classToFind, image) {
var elems = document.getElementsByClassName(classToFind);
if (!elems) return;
for (var i = elems.length - 1; i >= 0; i--) {
var elem = elems[i];
if (elem === image) continue
elem.style.width = "200px";
elem.style.height = "200px";
}
}
function toggleSize(image) {
resetImages('galleryImage',image);
if (image.style.width != "600px") {
image.style.width = "600px";
image.style.height = "600px";
} else {
image.style.width = "200px";
image.style.height = "200px";
}
}
Demo: http://jsfiddle.net/IrvinDominin/DfSbT/
This is a jquery solution, code not tested. But image resize will work as you expected.
function toggleSize(image) {
// Get the current image size
var currentImageHeight = $(image).height();
// If it is 600, that means user clicked on a enlarged thumbnail
// Just resize it
if(currentImageHeight == 600){
$(image).width(200);
$(image).height(200);
}
// User clicked on other thumbnail. Resize previously enlarged thumbs
else{
$('.galleryImage').width(200);
$(image).width(600);
$(image).height(600);
}
}
Related
I'm creating a lazy load function and I want to append the image to the DOM after it has successfully loaded to create a smooth transition.
I have a function which loops through a list of elements with a specific class, which gradually gets smaller every time you scroll.
Once an image in that list is considered "visible" I add a class and it no longer get's evaluated by the function.
I get the SRC by a data attribute, and create a new Image();
I do some css prop manipulation and add the src after I add the onload function.
This works around 1/3 of the time, most images never fire the onload callback and aren't added to the DOM.
My script is as follows:
var lazyClass = 'js-lazyload';
function lazyLoader() {
//Sets an elements var that checks how many non-visible elements still exist
// This variable is reset every time lazyLoader() is called
var elements = document.querySelectorAll('.' + lazyClass + ':not(.js-lazyload--visible)');
//If there are no hidden elements left, end the function we don't need to proceed.
if (elements.length === 0) return;
//Loop through the elements array
//Only untoggled elements can be in this array because of the previous check
for(var i = elements.length; i--;) {
var lazyLoadElement = elements[i];
if (
lazyLoadElement.getBoundingClientRect().bottom <= window.innerHeight &&
lazyLoadElement.getBoundingClientRect().bottom > 0 ||
lazyLoadElement.getBoundingClientRect().top <= window.innerHeight &&
lazyLoadElement.getBoundingClientRect().top > 0)
{
//The element was considered visible, let's go!
lazyLoadElement.classList.add('js-lazyload--visible');
var imgData = lazyLoadElement.getAttribute('data-image'),
image = new Image(),
lazyStyle = window.getComputedStyle(lazyLoadElement);
if(lazyStyle.position !== 'relative'){
if(lazyStyle.position !== 'absolute'){
lazyLoadElement.style.position = 'relative';
}
}
image.onload = () => {
lazyLoadElement.classList.add('js-lazyload--loaded');
lazyLoadElement.insertBefore(image, lazyLoadElement.firstChild);
}
image.classList.add('js-lazyload__image')
image.style.position = 'absolute';
image.style.top = 0;
image.style.left = 0;
image.style.width = '100%';
image.style.height = '100%';
image.style.zIndex = '-1';
image.style.objectFit = 'cover';
image.src = imgData;
}
}
}
Here is a fiddle which shows the issue:
Elements red - not visible
Elements blue - visible, but no image
Elements green - visible with loaded image
https://jsfiddle.net/dalecarslaw/yumv6rft/
No jQuery Please.
The onload callback that you added is in fact getting fired properly.
The issue in this particular case is the fact that the variables declared using var are function scoped. This means that as your for loop finishes it's iteration, the lazyLoadElement variable is pointing to the same element for all the handlers that get fired with an onload handler.
Changing the declarations for lazyloadElement, imgData, image and lazyStyle from var to let will make the code work as intended.
I am using videojs to build a website to play videos and insert some images to the page at certain time point of the video being played. I used the code below to get the current time and insert an image in "imageContext" div.
<script type="text/javascript">
var myPlayer = document.getElementById("example_video_1");
var added = false;
var ShowAds=function(){
var time = myPlayer.currentTime;
var img = document.createElement('IMG');
div = document.getElementById("imageContext");
div.style.width = '100px';
div.style.height = '100px';
div.style.display = 'inline-block';
if(time > 30 && time <= 40 && !added){
//img.onload = function(){
div.appendChild(img);
added = true;
img.setAttribute("src",'/Applications/MAMP/htdocs/shqc.jpg');
img.style.width = '100%';
img.style.height = 'auto';
}else if(time > 70){
//change to another image in the same position
}
}
myPlayer.addEventListener('timeupdate',ShowAds,false);
</script>
What if I want to show another image on the page when the time changes to, say, the 90th second? Or is there any way to delete the image on the page using javascript? Thanks!
To be clear, I have tried to put
img.setAttribute("src",'/Applications/MAMP/htdocs/yy.jpeg');
under else, it doesn't work
You can set an id to the img element when you create it, (In case if you have multiple img tags inside the document)
img.setAttribute('id', 'myImg');
Then, check whether time equals 90 the same way you check whether it is between 30 and 40 and change the src of it like below.
if(time == 90 ){
document.getElementById("myImg").src="/Applications/MAMP/htdocs/your_image.jpg";
}
In case if you want to delete the img element, since it has a parent
(imageContext), you can do this,
var el = document.getElementById('myImg');
el.parentNode.removeChild(el);
You can use this code:
document.getElementById("image").src="/PATH/To/Image/file.jpg";
I think all you need is this:
document.getElementById("myImg").src = //whatever
You could try creating and array of images locations.
var imageArray = new Array();
imageArray[0]= {
image01: new Image(),
image01.src: "my-image-01.png",
imageCaption: "An image caption"
};
Then at the next interval just set the image attribute to the src of a picture in the array or just append the whole image.
if(time > 90 && time <= 100 && !added){
div.appendChild(img);
added = true;
img.setAttribute("src",imageArray[0].src);
img.style.width = '100%';
img.style.height = 'auto';
Hope that helps.
I used a little help from this other stack overflow question and answer:
Creating an array of image objects
I'd like to use plain javascript to apply either the class name portrait or landscape to all <img> elements with a certain class name based on whether the image file itself is taller than it is wide (portrait orientation) or wider than it is tall (landscape orientation).
I know I can get all of the elements by class name like so:
var portalPics = document.getElementsByClassName("portal-pic");
And I think I can tell the orientation of each image file by comparing the naturalHeight and naturalWidth properties of the HTMLImageElement, but I'm not sure how.
Can anyone help me write the script that I would insert before the closing </body> tag in my HTML document that would automatically add the desired class names to the desired images?
You can just loop, check, and assign:
var portalPics = document.getElementsByClassName("portal-pic");
for (var i = 0; i < portalPics.length; i++) {
if (portalPics[i].naturalWidth > portalPics[i].naturalHeight) {
portalPics[i].className += " landscape";
} else {
portalPics[i].className += " portrait";
}
}
if you compare image width with height, then you know which class to add:
var nodes = document.getElementsByTagName("IMG");
var images = Array.prototype.slice.call(nodes);
images.forEach(function(img) {
if (img.width > img.height) {
img.className += img.className ? ' landscape' : 'landscape';
}
else {
img.className += img.className ? ' portrait' : 'portrait';
}
});
function show()
{
var elem = document.getElementById("pop").querySelector('li:nth-child(3)');
elem.style.width = "500px";
}
</script>
I have this code attached to an onclick
<li onclick="show()">
The element is originally 200px and then turns into 500px when clicked. How do I make it work so that when I click it again it goes back to 200??
The best thing to do would be to use a CSS class to set the width. This has the advantage that:
You don't have to specify the width in multiple places (CSS and JS) (-> easier to maintain)
You don't have to know the default width of the element (-> more flexible)
Example:
CSS:
.wide {
width: 500px;
}
HTML:
<li onclick="show(this)">...</li>
JS:
function show(elem) {
elem.classList.toggle('wide');
}
DEMO
Have a look at the MDN documentation regarding classList for information about browser support. You can also find alternatives in this excellent question/answer about handling CSS classes on elements: Change an element's class with JavaScript
To learn more about event handling (ways to bind event handlers, information available inside event handlers, etc), have a look at the excellent articles at quirksmode.org.
function show() {
var elem = document.getElementById("pop").querySelector('li:nth-child(3)'),
width = parseInt(elem.style.width, 10);
if (width === 500) {
elem.style.width = "200px";
}
else {
elem.style.width = "500px";
}
}
Although, I'd probably name the function toggle or something similar and not inline the click handler.
Use a control variable
var clickControl = false;
function show()
{
if(clickControl)
{
var elem = document.getElementById("pop").querySelector('li:nth-child(3)');
elem.style.width = "500px";
clickControl = !clickControl;
}
else
{
var elem = document.getElementById("pop").querySelector('li:nth-child(3)');
elem.style.width = "200px";
clickControl = !clickControl;
}
}
I want to fade in multiple images at the same time as the page loads. Just like this website does it: http://www.struckaxiom.com/work. I have the script to do it only on one image, but I want to have more images included.
This is the single photo script. Please help.
document.write("<style type='text/css'>#thephoto {visibility:hidden;}</style>");
function initImage() {
imageId = 'thephoto'
image = document.getElementById(imageId);
setOpacity(image, 0);
image.style.visibility = "visible";
fadeIn(imageId,ImageId2,0);
}
function fadeIn(objId, opacity) {
if (document.getElementById) {
obj = document.getElementById(objId);
if (opacity <= 100) {
setOpacity(obj, opacity);
opacity += 10;
window.setTimeout("fadeIn('"+objId+"',"+opacity+")", 100);
}
}
}
function setOpacity(obj, opacity) {
opacity = (opacity == 100)?99.999:opacity;
// IE/Win
obj.style.filter = "alpha(opacity:"+opacity+")";
// Safari<1.2, Konqueror
obj.style.KHTMLOpacity = opacity/100;
// Older Mozilla and Firefox
obj.style.MozOpacity = opacity/100;
// Safari 1.2, newer Firefox and Mozilla, CSS3
obj.style.opacity = opacity/100;
}
window.onload = function() {initImage()}
// -->
</script>
Thanks!
Simple array and loop are all you need.
First, add such array on top of the code:
var images = [ "thephoto1", "thephoto2", "thephoto3" ];
(With the ID of all desired images)
Next change the function name to initImages to reflect the fact it will initialize more than one image and finally add that loop:
function initImages() {
for (var i = 0; i < images.length; i++) {
imageId = images[i];
image = document.getElementById(imageId);
setOpacity(image, 0);
image.style.visibility = "visible";
fadeIn(imageId, 0);
}
}
That's it, no need to touch the other functions.
Live test case with cute cats: http://jsfiddle.net/yahavbr/e863X/ :-)
You could just wrap all of your images in a single container like this:
<div id="imageContainer">
<img src="img1.jpg">
<img src="img2.jpg">
<img src="img2.jpg">
</div>
Change your CSS to this:
<style type='text/css'>#imageContainer {visibility:hidden;}</style>
Change your first function to this:
function initImage() {
containerId = 'imageContainer'
container = document.getElementById(containerId);
setOpacity(container, 0);
container.style.visibility = "visible";
fadeIn(containerId,0);
}
By running the fading effect on the container you can then add as much content to the container and it will all fade in together and you never have to update your code.
The way they are doing is using jQuery (an excellent implementation). All of the images are in the same container and are selected using the jQuery class selector. Then they fade in all elements that fit within the viewable area. Their js file is not minimized so you could reverse engineer most of that functionality. The important thing to note is not that it is showing each row at a time but every element that fits in the viewing area. Their key function looks like this:
var elTop = $(el).offset().top - $(window).scrollTop();
var elHeight = $(el).height();
// if between top of footer and top of window
if (elTop + elHeight > 40 && elTop < $(window).height()) {
if ($.inArray($(el).attr("data-unique-id"), elementsInView) < 0) {
addToView(el);
}
} else {
if ($.inArray($(el).attr("data-unique-id"), elementsInView) >= 0) {
removeFromView(el);
}
}
addToView and removeFromView add and remove the element from an array, then fade is executed on the array.