How to load picture images via click on a picture? - javascript

At the moment i load default images for every picture in my app. I want to load the real picture of all images in div 5 if i click on any picture of div 5. At the moment i use the onclick event of the img tag with:
switchImg(this, "LINK_FOR_PICTURE")
my js snippet:
function switchImg(img, url){
$(img).attr("src", url);
}
At the moment it only loads the picture that i clicked on.
here the HTML snippet:
<div id="1">
</div>
<div id="2">
</div>
..
<div id="5">
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_1")" alt="No_picture">
</div>
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_2")" alt="No_picture">
</div>
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_3")" alt="No_picture">
</div>
.....
</div>
How do i need to change my code that following condition is true:
i click on any picture in div id=5 and all this pictures gets the correct picture link (LINK_FOR_PICTURE_1, LINK_FOR_PICTURE_2, etc) as src. The other pictures in the other divs don`t change and still display the default img. (Div id 5 is an example the same procedure should be possible for other divs with pictures).
Please keep in mind that the img link changes for every picture.

using only numbers for id is bad practice
your div id="5" is closed right after first image
you are using double quotes in double quotes in your example - bad idea
by calling switchImg(this, "LINK_FOR_PICTURE_3") using this, "this"
represents only clicked image. You would need something like
function switchImg(img){
$(img).closest('div').find('img').each(function(){
$(this).attr("src", $(this).attr('imglink'));
});
}
using html
<img src="DEFAULT_IMG" onclick="switchImg(this);" imglink="LINK_FOR_PICTURE_3" alt="No_picture">

Take advantage of jQuery and event delegation and observe when the div is clicked to then find all the images within that div and trigger the src change. To explain this better i've quickly thrown together an example on JSFiddle
http://jsfiddle.net/Phunky/EnhUE/
In my example you can either click images individually or the div for them all.

This will do it:
HTML
<div id="5">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
</div>
JS
function switchImg(img){
img.attr("src", img.data('fullImg'));
}
$(function(){
var allImages = $('#5 img');
allImages.click(function(){
allImages.each(function(){
switchImg($(this));
});
});
});
HTML changes
I assume you want all the img tags wrapped in #5, no? Because your current HTML markup is invalid.
Additionally, ids can't technically start with a number. It probably won't cause a problem in most browsers, but it is invalid.
I'm using an HTML5 data-attribute to store the link for the picture. This will work even in non-HTML5 browsers. I'll get to this in a moment.
Finally, inline-JS is generally a bad idea because it is difficult to maintain. Using jQuery, it's very easy to bind code to the onclick event.
JS Changes
allImages.click() binds the code inside to the click event on any of the images.
The .each() function then loops over all those images, passing itself as a jquery object to the switchImg function.
My modified version of the switchImg function doesn't need a second parameter, because it can simply use the jQuery object to access the data-fullImg attribute. If using a version of jQuery prior to 1.6 (or something like that), using the .data() method in the way I did won't work. You'd instead need to use .attr('data-fullImg').
EDIT
In response to the OP's comment on this post:
$(function(){
$('img.showOriginal').click(function(){
$(this).parent().children().each(function(){
switchImg($(this));
});
});
});
This code assumes that you put the class"showOriginal" on every img tag, since I doubt that you truly want to apply this functionality to every single img tag on the page. Beyond that, we have this part: $(this).parent().children(). That simply traverses the DOM up to the parent element (#5, #2, whatever), and then back down to all the children (the images you want to change).

Related

Toggling an html IMG element's class using JS (no Jquery)

I give up... All of your answers were just different ways of targeting the local element.
If you bothered to actually read what I was saying you would realise that it was not a problem with the code I already had, just that the code DID NOT work on IMG tags.
While faffing around trying to demonstrate my problem (and that none of your solutions did anything different to what was already happening) I found that I can achieve exactly what I want by applying a Grayscale filter to a DIV element placed over each image. The mouseover event then triggers an opacity change in the DIV element.
It is a little heavier that I wanted but it answered my ACTUAL question. The answer being:
Yes, there probably is a way to toggle class of IMG tags. But no, I am probably not going to find it here without causing arguments or being told i'm using "bad code". So yes, it IS easier and more efficient to target DIV elements.
By the way, page load times are about how large data packages are. Larger data packages (images, html/css/js documents, etc) take longer to download and so the page takes longer to load. The website I am trying to create proves this thesis, I have an almost complete and (almost) fully functional website with loads of 'clever' little effects all under 20mb, about 15mb of which is images. This website is clean and simple, is hosted on my Samsung Galaxy Tab 4 (using Papaya) and loads almost instantly.
THIS is what I meant by "I want this to be VERY lite". Thank you all for your attempts to help, it's just a shame that I couldn't get anyone to understand what was going on.
If you add onClick to image element you don't need to pass anything, you will receive MouseEvent which contains all information. You need target from event.
I suggest to not use onClick on element as it is not scalable, you have to add it to all elements. Better to add listener to wrapping/container element and then filter target by some attribute e.g data-something Please check fiddle
So you have wrapping element and you images:
<div class="images-container">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray thumb-color" />
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray" />
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray" />
</div>
and you attach listener to you wrapping element. It is best practice as you don't attach listeners to each element and same time you are able easily scale your solution
var imagesContainerEl = document.querySelector('.images-container');
imagesContainerEl.addEventListener('click', function(event) {
var element = event.target;
if (element.hasAttribute('data-toggleable')) {
element.classList.toggle('thumb-color');
}
});
The same code can be extended to support mouseover and mouseout. Check fiddle2. One function to rule them all and in the darkness bind them..
var imagesContainerEl = document.querySelector('.images-container');
imagesContainerEl.addEventListener('mouseover', onToggleImage);
imagesContainerEl.addEventListener('mouseout', onToggleImage);
function onToggleImage(event) {
var element = event.target;
if (element.hasAttribute('data-toggleable')) {
element.classList.toggle('thumb-color');
}
}
Also updated fiddle which shows how to make image grayscale/color
Is what you refer to in your question as
onClick="colorFunction(image1)"
an inline javascript event listener?
If so, try replacing it with:
onClick="colorFunction(this)"
and rewrite colorFunction() as:
function colorFunction(image) {
image.classList.toggle('thumb-color');
}

How to get parentNode ID and use it as a variable

I'm trying to run a script on images within specific blog posts. Each post div is given a unique ID by Blogger that I'm trying to get. Because I only want to run the script on posts containing the function call and not the entire page, I want the function to basically find the ID of the div that's calling it, store that ID as a variable, and then pass that variable in to my function.
<script>
var scriptTag = document.scripts[document.scripts.length - 1];
var parentTag = scriptTag.parentNode;
</script>
This returns the correct element but the second I wrap it in a function(){} it doesn't work anymore. How can I assign these variables from within a function so I don'thave to clutter up every post's html with a bunch of variable declarations?
Secondly, once I have these variables assigned is there a way to use the value stored with the getElementByID method to actually select the element?
var parentDivID = parentTag.id;
var postID = document.getElementByID(parentDivID); //can't figure out how to select using this as the variable
For ease of use I'd like it if I could simply wrap the function call in script tags and stick it at the end of my post's html whenever I need to use it.
Details
The script I want to run finds images within divs with a specified class and resizes them to fit side-by-side so that the outer edges of the images completely fill the width of the div.
Here is the question covering that script:
Force dissimilar images to equal heights so combined widths fill fixed div
I would like to call this script at the end of any post body where I plan to use side-by-side formatting. The reason I want to call it at the end of a post instead of on the entire page is because the page uses "infinite scrolling" and I'm worried that as posts load after the fact the resizing script will have already been run and newly loaded posts will not be resized.
So I want the function to be able to find the unique ID of the div that contains the call, use that as a variable and ask the script to look inside that post for divs of a certain class, then look within those divs for image tags and resize those images. I hope that makes sense.
Here's an example of what I'd like the post's html to look like:
<div style="width:500px; margin:auto;">
<div class="widthVal x2">
<img class="caption" alt="Caption 01" src="sample01.jpg" />
<img class="caption" alt="Caption 02" src="sample02.jpg" />
<img class="caption"alt="Caption 03" src="sample03.jpg" />
</div>
<script> resizeMagic(); </script>
</div>
Thanks for any help!

Is there a way to make images inside display:none not get downloaded by the browser?

I want the browser (mobile webkit especially) to NOT download images that are inside display:none divs. Right now, they get downloaded and not rendered.
Is there a jquery plugin to do this?
you can use data-* attributes. that way, you can have jQuery load them on demand:
<img data-source="image_path">
//this one gets all images and loads them
$('img').each(function(){
//loads the source from data-source
this.src = this.getAttribute('data-source');
});
<img data-source="image_path" class="foo">
<img data-source="image_path" class="foo">
//this one gets all images that have class foo and loads them
$('img.foo').each(function(){
//loads the source from data-source
this.src = this.getAttribute('data-source');
});
ofcourse you need to wrap this in a function so that you can call which images on demand. like:
function loadImg(selector){
$(selector).each(function(){
this.src = this.getAttribute('data-source');
});
}
//load images with class foo:
loadImg('.foo');
I don't think so. To be sure, you would need your original HTML DOM to exclude the hidden images, which you could do with server-side programming based on user agent sniffing (although that is not recommended). Modifying the DOM after document.ready or document.load will mean that the browser has already had a chance to request assets from the server even if they might not be displayed.
It would be unusual but if you still want to use jQuery you could follow #Pointy's advice and make all images placeholders in your markup. Then replace the :visible placeholders with the images you want using an attribute as the data source. No plugin is needed, just use something like replaceWith() or attr() to swap out the placeholder node for the image you want downloaded or change the src attribute.
I would use a 1x1 transparent gif as the placeholder with the correct height and width attributes rather than no source <img> for a placeholder. That way the page flow will be determined correctly when the page renders so it won't jump around as your images lazily load.

How to fade in div's linked to icons?

I want to fade in the divs that pop up when you roll over an icon at my Tumblr theme I'm building, roseannebarr.tumblr.com. I don't know how to :(
P.S: If you get a "We'll be back shortly" try again in a few minutes, thats Tumblr being stupid :(
Here is how Tumblr works; Tumblr uses their own "tags" to create posts entered from a user's dashboard. You can post a link, photo, text, chat, video, or an audio. I only entered a photo post below. Outer is the icon you hover over (it also uses "block") and tooltip is the actual content itself. The reason you view the source on my page but can't see this is because the tags ARE the content.
<div id="outer">
{block:Photo}
<img id="block" src="http://static.tumblr.com/ux4v5bf/vYSlebvt2/photo.png">
<div id="tooltip">
{LinkOpenTag}<center><img id="photo" src="{PhotoURL-500}" alt="{PhotoAlt}" /></center>
{block:Caption}<div class="caption">{Caption}</div>{/block:Caption}
<img id="cover" src="http://static.tumblr.com/ux4v5bf/pMHledd2y/cover.png">
<img id="cover" src="http://static.tumblr.com/ux4v5bf/pMHledd2y/cover.png">
</div>
{/block:Photo}
</div>
I assume you are currently using jQuery's show() and hide() methods to work with the those divs.
Instead jQuery has a fadeIn() and a fadeOut() function which do exactly as they sound, you can find the docs for fadeIn here.
It takes a time in milliseconds as the first argument and an optional function to be called when the animation has finished as the second:
$('div#whatever').fadeIn(200, function() {
console.log('the fade has finished when this function is called');
});
$('#myIconId').mouseover(function() {
$('.mydivsClass').fadeIn(5000);
});
The one problem I see is that you have the same id on multiple elements on the page. W3C states one ID but multiple classes. You may have to do some refactoring to get the above to work. You need some way to match your icons up with an image, and typically that is what the id tags would do.

Unobtrusive Javascript: Removing links if Javascript is enabled

I'm using PopBox for magnifying thumbnails on my page.
But I want my website to work even for users which turned javascript off.
I tried to use the following HTML code:
<a href="image.jpg">
<img src="thumbnail.jpg" pbsrc="image.jpg" onclick="Pop(...);"/>
</a>
Now i need to disable the a-Tag using javascript, otherwise my PopBox won't work.
How do I do that?
Just put the onclick on the a-tag:
<img ...>
Make sure to return false either at the end of the function (here Pop) or inline like in the above example. This prevents the user from being redirected to the link by the <a>'s default behaviour.
Put the onclick event onto the link itself, and return false from the handler if you don't want the default behavior to be executed (the link to be followed)
You could give all your fallback anchor tags a particular classname, like "simple"
Using prototype, you can get an array of all tags using that class using a CSS selector, e.g.
var anchors=$$('a.simple')
Now you can iterate over that array and clear the href attributes, or install an onclick handler to override the normal behaviour, etc...
(Edited to add that the other methods listed above are much simpler, this just came from a background of doing lots of unobtrusive javascript, where your JS kicks in and goes and augments a functioning HTML page with extra stuff!)
May I suggest, in my opinion, the best solution? This is using jQuery 1.4+.
Here you have a container with all your photos. Notice the added classes.
<div id="photo-container">
<a href="image1.jpg">
<img class="popup-image" src="thumbnail1.jpg" pbsrc="image1.jpg" />
</a>
<a href="image2.jpg">
<img class="popup-image" src="thumbnail2.jpg" pbsrc="image2.jpg" />
</a>
<a href="image3.jpg">
<img class="popup-image" src="thumbnail3.jpg" pbsrc="image3.jpg"/>
</a>
</div>
An then you make a single event handler this way:
<script type="text/javascript">
$(document).ready(function(){
var container = $('#photo-container');
// let's bind our event handler
container.bind('click', function(event){
// thus we find (if any) the image the user has clicked on
var target = $(event.target).closest('img.popup-image');
// If the user has not hit any image, we do not handle the click
if (!target.length) return;
event.preventDefault(); // instead of return false;
// And here you can do what you want to your image
// which you can get from target
Pop(target.get(0));
});
});
</script>
The href attribute is not required for anchors (<a> tags), so get rid of it...
<a id="apic001" href="pic001.png"><img src="tn_pic001.png"></a>
<script type="text/javascript">
document.getElementById("apic001").removeAttribute("href");
</script>
This method will avoid library contention for onclick.
Tested in IE6/FF3/Chrome. Side benefit: You can link directly to the portion of the page containing that thumbnail, using the id as a URI fragment: http://whatever/gallery.html#apic001.
For maximum browser compatibility, add a name="apic001" attribute to the anchor tag in your markup ('name' and 'id' values must be identical).
Using jQuery, dojo, Prototype, etc. you should be able to do the removeAttribute on multiple, similar anchors without needing the id.
You should be able to mix and match the return false from Chris's idea with your own code:
<a href="image.jpg" onclick="return false;">
<img src="thumbnail.jpg" pbsrc="image.jpg" onclick="Pop(...);">
</a>
If someone has Javascript disabled, then their browser ignores the onclick statement in both elements and follows the link; if they have Javascript enabled, then their browser follows both OnClick statements -- the first one tells them not to follow the <a> link. ^_^

Categories

Resources