I was wondering if you guys would be able to tell me what these last 2 lines mean in some code which will change images according to where they are in the sequence. It will change whenever I hit a button
var image = document.getElementById('light');
image.src=list[light];
Hope you are able to help me.
Thanks
PS: That code is found near to the end of my whole code
var image = document.getElementById('light');
This line sets the variable image to an element in the page with the id 'light'.
image.src=list[light];
This sets the src of the image to the value of list[light].
If list is an array then light will be a number to refer to the element of the array.
Alternatively if list is an object light could be a string.
That code gets an element by it's ID value and updates the source of the image, presumably to a different image.
Here you just get a reference to the image object.
var image = document.getElementById('light');
On the second line you change src property of image object to some different value, what is automatically triggers the reloading of image.
image.src=list[light];
Related
I'm after insight into how to avoid unwanted behaviour in loading images using promises. My real-world use is quite complex (a large threejs application) so I've boiled down my issue below to an easier to explain example.
I have a gallery div which shows an image. There are a group of thumbnails which the user can click which loads the image associated with that thumbnail and once loaded shows it in the gallery div (in the real application a promise is used here as we must load the image, then once loaded create a texture from it before passing that texture back to apply to a plane).
The issue I'm having is that if the user clicks multiple thumbnails quickly they are applied to the gallery div in the order they load which could mean that a user could click a large image to load, then a small image resulting in the small image being shown but then being overwritten by the larger image (even though it wasn't the last selected due to it being larger and therefore taking longer to load).
I'm at a loss on how to solve this issue elegantly and am hoping someone might be able to offer a suggestion on how other software/programs deal with this issue. Is it as simple as having a redundancy system to see if an image is still selected once it loads and if it isn't then abort?
There are a number of different algorithms for dealing with this issue and part of the selection process depends upon exactly what behavior you want. Based on your description it sounds like you want an image to be shown as soon as it is loaded, but to never overwrite an image that came after it and has already been displayed. That means that if images are requested in the order 1,2,3, but arrive in the order 2,1,3, then you will show image 2, then 3 and never show 1.
Assuming that is the desired algorithm, then a fairly simple way of doing things is to just assign each request a sequence number and just keep track of the last sequence number that you showed. Whenever any image finishes loading, you check if it's sequence number of above the last sequence displayed. If not, you don't show it because it's an old image that was surpassed by a newer image. If so, then you show it and update the lastShownSequence number to the sequence number of this image. This type of algorithm requires two lasting variables to keep track of the lastShownSequence number and the nextSequenceNumber to be assigned.
Here's a sample code implementation:
var lastShownImage = 0;
var nextSequenceNumber = 1;
// url is image url
// elem is image element in the page to replace with newly loaded image element
function loadImage(url, elem) {
let imageSequenceNumber = nextSequenceNumber++;
let img = new Image();
img.onload = function() {
// image loaded now
// see if we should display it or not
if (imageSequenceNumber > lastShownImage) {
// hide current image so there's never any flashing of two images
elem.style.display = "none";
// record the sequence number we are showing
lastShownImage = imageSequenceNumber;
// insert new image
let parent = elem.parentNode;
parent.insertBefore(img, elem);
// remove previous image
parent.removeChild(elem);
}
};
img.src = url;
}
If you don't want lastShownImage or sequenceNumber to be open scoped like this, then they can be encapsulated either in an IIFE or in an instance of a class that you create, but since I don't see how exactly you would use this from your code or see if you needed a more generalized multi-instance implementation, I didn't add any extra complication for that.
Currently I have thumbnails, when I click the them a large version of the pic appears in the div directly to the right of the thumbnails. What I now want to be able to do is click the larger pic in the div and then trigger a lightbox that shows an even larger version of the pic.
I'm not quite sure how to do what I'm thinking is the solution so I'm gonna try and explain. I'm thinking that when i click the div to trigger the lightbox I want to take the src of the pic being click and then somehow redirect it to another src in my images folder.
Example:
When I click image in div I get the src of pic lets say that the source is:
src="redpic.jpg"
Then lets say in my images folder I have a larger version of the pic selected with the source:
src="redpic_large.jpg"
Would it be possible to manipulate the the src of an first image img src="redpic.jpg" by adding _large to the end and then appending this to my
lightbox???
Everytime I try to do things with my images I always seem to be running into problems.
say the src="redpic.jpg" when I check in the console the src goes to something like //139.0.0.1:56328/img/dotted.jpg and it seems to cause me a lot of problems
Sure, you can get the source of the image like this :
$("img").on("click", function(){
var source = $(this).attr("src");
});
This will give you the complete path (redpic.jpg).
You can use split() to get an array of both parts (the name and the extension)
var parts = source.split(".");
Now, all that you have to do is append the "_large" to the first part of the source, combine them back together and set your other image's source as the newly assembled one.
parts[0] += "_large";
var newSource = parts.join(".");
You pass the period . to the join function so that it puts a period in betwen your elements, instead of the default comma , .
All that's left to do is to use newSource as the source attribute of your other image.
$(".other-image").attr("src", newSource);
Situation: I have a tiny http server that can only handle 4 connections at any given time. When opening a web page, my web browser sends a get request for every image resource asynchronously (tries to open more than 4 connections at the same time). This causes some bad behaviour.
Initial solution: I wrote a JS function that loads the images sequentially and stores them in a dictionary
var loadedImages = {};
like so:
var img = new Image();
img.src = <img_location>;
loadedImages[<img_name>] = img;
After all the images are loaded i try to place them in various places in the DOM. The important part is that i need to place the same picture in multiple places. I do it like this:
//For all the elements that need to have the same image DO:
var img = loadedImages["<img_name>"];
$(this).html(img);
Problem: What happens is that as soon as the code puts the image in the SECOND element, the image gets removed from the FIRST element. When the image gets put in the THIRD element, it gets removed from the SECOND element. So what happens is that basically only the last element contains the image, while all the others are empty.
Question: How can I place the same image from my javascript dictionary (or any other javascript object) on multiple DOM elements?
Edit:When using something like
//For all the elements that need to have the same image DO:
var img = loadedImages["<img_name>"];
$(this).html($(img).clone());
as proposed by Tamil Vendhan and Atif Mohammed Ameenuddin, the image gets placed on all the elements and that is ok, but the browser requests the image from the server every time it comes to that line of code. So it is not really a good solution. Same goes when i use "cloneNode()"
Try using the clone method in jQuery
$(this).html($(img).clone());
Use jQuery.clone:
$(this).html($(img).clone());
Update:
Yes, browser will make the request. But it will use the cached image if it is already loaded.
Check your debugger's net panel to confirm this. You will see (from cache) under Size column.
This is my case: I have a page with a banner that will be frequently updated, this means the image path of the banner will be different each time the page is updated (can't be overwritten). Anyway, it will be inside a div or container with a constant name.
What I need to do is retrieve that image path and print it in a different page, so if the banner changes in the first page, it will automatically change in the second one.
I thought maybe some javascript could do the work, but I am not really sure how to get the image path from inside the div.
Any help will be appreciated, greetings from Argentina
solution using html5 and javascript is this
you can get the image tag through javascript(as u say it is in div
and whose id you know)
something like
src = document.getElementById("id").childnodes[0].src
should work for u
then you can store this src in the localStorage
localStorage["src"] = src;
as soon as you store something in localstorage it will fire a
"storage" event in all the other pages except the page in which
you have actually stored the src
so handle "storage" event in the other pages like this
window.addEventListener("storage",func,false);
function func(event)
{
src = localStorage[event.key];
//now src has the updated src :)
}
I'm trying to detect if a class is present and, if so, set the background attribute of another element. This is what I have but it's not working.
if(jQuery("#slider-banner").hasClass('living-nutrients'))
{
jQuery("#home-middle-first").css("background-image","[path to new background image]");
}
BTW - My next step is for this to detect it whenever the ID "slider-banner" changes, but so far I can't even get it to work once on page load. Any help would be greatly appreciated... Thanks!
EDIT: I changed from .attr to .css as instructed. Makes sense... but still not working. I've tried adding console.log message within the IF statement and got nothing also. Does that give anyone any more ideas?
Example HTML where class changes:
<img id="slider-banner" class="living-nutrients" src="[image path]">
Example HTML where I want to change background image:
<div class="home-middle-one-third" id="home-middle-first">
</div>
UPDATE:
For everyone who said it "should work"... you are right! Turns out that, as written, it doesn't like being in the footer of the page, but when I moved it to the head, presto!
The final piece of this puzzle is to have it detect and evaluate based on the #slider-banner changing, (or more accurately, which class is present for the ID'd area), not just the page loading, as is currently.
The ID is for one element of a slide within a slider. There are three possible classes I could assign to the ID depending on which slide is visible. So I need the script to evaluate every time a slide changes.
Any ideas? Thank you all!
background-image is a element's style property, not its own one.
So .css("background-image","[path to new background image]");
Almost!
if(jQuery("#slider-banner").hasClass('living-nutrients'))
{
jQuery("#home-middle-first").css("background-image","[path to new background image]");
}
css is the correct function to set a CSS attribute.
The attr will set an HTML attribute. <div attr='attr value'>
Edit
I'm kind of guessing about the functionality of your script here in the following example.
When you set the background-image of a HTML node, that's all it does is set the background image. You must also set the width and height accordingly, to all the node to be large enough to even see the background of the node. Background images will not automatically resize the node.
var slider = jQuery("#slider-banner"); // jQuery("#slider-banner") is slow, so we save it to a var if we use it more than once
console.log(slider); // should be this in Chrome: [<img id="slider-banner" class="living-nutrients" src="[image path]">]
if(slider.hasClass('living-nutrients'))
{
jQuery("#home-middle-first").css({
"background-image":"url("+slider.attr('src')+")", // url() for good meassures
//"background-image":slider.css('background-image'), //try this if that doesn't work
"height":slider.height(),
"width":slider.width()
});
}
Here is a working example.
Try this
jQuery("#home-middle-first").css("background-image","url([path])");