How to wrap a link to all images inside a div? - javascript

I have something like this:
<img class="photo" src="www.example.com" />
<img class="photo" src="www.example2.com" />
<img class="photo" src="www.example3.com" />
And I need to get this:
<a href="www.example.com" class="link">
<img class="photo" src="www.example.com" />
</a>
<a href="www.example2.com" class="link">
<img class="photo" src="www.example.com2" />
</a>
<a href="www.example3.com" class="link">
<img class="photo" src="www.example.com3" />
</a>
I need to add the link, the href with the same code as the SRC of each image, and a class.
I was trying to do it like this:
$('.photo').wrapAll('<a>');
But it doesn't even work.
What am I doing wrong?

Because the hrefs will all be different, you'll need to use each.
$('img.photo').each( function() {
var $img = $(this),
href = $img.attr('src');
$img.wrap('');
});
Note that wrapAll isn't what you want anyway as it will take all the elements and wrap them with a single anchor tag. If you weren't using an anchor that needs a different href for each element, wrap would work by itself and wrap each one individually.

$('img').wrap("<a href='foo'>") will work just fine.

Try this:
$('.photo').before('<a href="www.example3.com" class="link">');
$('.photo').after('</a>');
And if you want
$( '.photo' ).each( function() {
var mySrc = $( this ).attr( "src" );
$( this ).before( '<a href="' + mySrc + '" class="link">' ) );
$( this ).after( '</a>' ) );
});
I hope this works for you...

Related

getting all 2nd level childs of element & for each function

I'm trying to implement a plugin called kort kort plugin , cool thumbs. The problem is that the plugin is coded to work in this way
all img must be direct children of a div , example
<div class="kort">
<img src="my_img.png" />
<img src="my_img.png" />
<img src="my_img.png" />
<img src="my_img.png" />
<img src="my_img.png" />
<.div>
but in my case, I need to add a link to the img so the the will look like
<div class="kort">
<a href="#"><img src="my_img.png" /><a/>
<a href="#"><img src="my_img.png" /><a/>
<a href="#"><img src="my_img.png" /><a/>
<a href="#"><img src="my_img.png" /><a/>
<a href="#"><img src="my_img.png" /><a/>
<.div>
Here the plugins core core i think that line 91 is the source of problem but I'm not sure , I tried to edit and modify several part of code but in vain .
You can change the way you are finding the elements. Instead of looking for the children, you can look for the image tags.
What the code does now:
function updateState() {
elementLeft = element.offsetLeft;
elementWidth = element.offsetWidth;
elementChildren = [].slice.call( element.children );
}
What you can try to do:
function updateState() {
elementLeft = element.offsetLeft;
elementWidth = element.offsetWidth;
elementChildren = [].slice.call( element.getElementsByTagName("img") );
}

How to get each element and assign them an inline style contained inside the child

I've been looking for an elegant solution for a day now and I am pretty new to jQuery.
I would like to get each .figure and assign them an inline style where the value is contained inside the child element via a custom data- attribute :
<div>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-01-thumbnail.png" src="images-01.png" />
</div>
<div class="content">
<h3>Sale</h3>
<h4>Discover our latest styles</h4>
</div>
</a>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-02-thumbnail.png" src="images-02.png" />
</div>
<div class="content">
<h3>Free Shipping</h3>
<h4>When you buy xxxxxx</h4>
</div>
</a>
<a href="#">
<div class="figure">
<img class="thumbnail" data-thumbnail="images-03-thumbnail.png" src="images-03.png" />
</div>
<div class="content">
<h3>Free Shipping</h3>
<h4>When you buy xxxxxx</h4>
</div>
</a>
</div>
In other words, the results would be :
...
<div class="figure" style="background: url(images-01-thumbnail.png);">
...
<div class="figure" style="background: url(images-02-thumbnail.png);">
...
<div class="figure" style="background: url(images-03-thumbnail.png);">
...
Also, I'm always ready something about jQuery so if you have any books about JavaScript or jQuery to suggest, that is always appreciated.
You can iterate over all .picture elements, find the image descendant and read its data attribute:
$('.figure').css('background', function() {
return 'url(' + $(this).children('img').data('thumbnail') + ')';
});
Some methods, like .css even accept functions so that you can iterate over the selected elements implicitly.
Reference: .css, .children, .data
you can iterate over each item with the class thumbnail and set the css property to the closet div.
$('.thumbnail').each(function() {
var $this = $(this),
$background = $this.data('thumbnail');
$this.closest('.figure').css({background : $background} )
});
This should work
$("[data-thumbnail]").each(function ()
{
var $this = $(this), url = $this.data("thumbnail");
$this.parents(".figure").css("background-image", 'url("' + url + '")');
});
How about this (Working code example: http://jsfiddle.net/jpbH2/2/):
var pathToImages = "/";
$(".figure img").each(function(){
$(this).parent().css({"background": "url(" + pathToImages + $(this).data('thumbnail') +")"})
});
Edit
I actually didn't notice the data-thumbnail. Edited my answer above

jquery gallery / carousel oddity

I've got an image viewer that combines a thumbnail/large image block that works great...
looks like this:
<div id="gallery-large" ><img id="largeImage" src="" /></div>
<div id="gallery-scroller" >
<ul class="holder">
<li class="slide first"><img src="galleries/kids/01.jpg" data-large="galleries/kids/06.jpg" alt="1st image description" /></li>
<li class="slide"><img src="galleries/kids/02.jpg" data-large="galleries/kids/07.jpg" alt="2nd image description" /></li>
<li class="slide"><img src="galleries/kids/03.jpg" data-large="galleries/kids/08.jpg" alt="3rd image description" /></li>
<li class="slide"><img src="galleries/kids/04.jpg" data-large="galleries/kids/09.jpg" alt="4th image description" /></li>
<li class="slide"><img src="galleries/kids/05.jpg" data-large="galleries/kids/10.jpg" alt="5th image description" /></li>
</ul>
<div class="clear"></div>
</div>
<script>
$('.holder').delegate('img','click', function(){
$('#largeImage').attr( 'src',$(this).attr('data-large') );
});
</script>
However when I try to combine this with a carousel (the simplest one I found here - http://www.flintstudio.biz/stuff/sliders/1.html )
It stops working...
the code looks like this
<div id="gallery-large" ><img id="largeImage" src="" /></div>
<div id="gallery-scroller" >
<a class="button prev" ><img src="images/arrow_left.png"/></a>
<a class="button next" ><img src="images/arrow_right.png"/></a>
<ul class="holder">
<li class="slide first"></li>
<li class="slide"></li>
<li class="slide"></li>
<li class="slide"></li>
<li class="slide"></li>
</ul>
<div class="clear"></div>
</div>
<script>
$( window ).load(function(){
var images = ['galleries/kids/01.jpg', 'galleries/kids/02.jpg', 'galleries/kids/03.jpg', 'galleries/kids/04.jpg', 'galleries/kids/05.jpg'];
$.preloadImages( images, init );
function init() {
$( '#gallery-scroller' ).imgSlider( images );
}
$('.holder').delegate('img','click', function(){
$('#largeImage').attr( 'src',$(this).attr('data-large') );
});
});
</script>
from a concept standpoint the only difference is that the list is populated after the window loads -
I've tried changing
.delegate('img','click', function(){
to
.on( 'click', 'img', finction(){
but that doesn't help..
OH - one important point - I changed one line in the carousel.js - so it's not doing a background-image css change, but adding an image...
so I changed this (line 37)
$( e ).find( '.holder > li' ).eq( i ).css( 'background', 'url('+images[i]+') no-repeat' );
to
$( e ).find( '.holder > li' ).eq( i ).html( '<img class="thumb" src="' + images[i] + '" />' );
What am I missing...???
jsfiddle of the simple thumbnail viewer... http://jsfiddle.net/cBpvZ/
jsfiddle of the carousel version... http://jsfiddle.net/ZJzLd/
I think you are binding the events on wrong DOM object, so instead of IMG it should be LI. You can inspect the HTML using firebug and can see that there is no IMG tag inside UL.holder. Try the following code.
$('.holder').delegate('li','click', function(){
var imgSrc = $(this).css('background-image').replace('url("','').replace('")','');
$('#largeImage').attr( 'src',imgSrc);
});
Ideally I should have used the RegExp to replace the string, however this works.
thx Mahesh
forest thru the trees... I couldn't see it because I'd fiddled with it so much... the missing reference to data-large was indeed the issue.
the solution was (defined by me) to have TWO arrays - one for thumbs and one for large..(I could take the path of adding some suffix or prefix to the image names and keep them correlated that way - but I choose not to - and therefor want the flexibility to name things whatever... and this needs two arrays)
var images = ['galleries/kids/01.jpg', 'galleries/kids/02.jpg', 'galleries/kids/03.jpg', 'galleries/kids/04.jpg', 'galleries/kids/05.jpg'];
var large = ['galleries/kids/06.jpg', 'galleries/kids/07.jpg', 'galleries/kids/08.jpg', 'galleries/kids/09.jpg', 'galleries/kids/10.jpg'];
$('#gallery-scroller').append('<img src="images/loader.gif" id="gallery-loader" style="position:absolute; top:45%; left:45%;"/>');
$.preloadImages( images, init );
function init() {
$( '#gallery-loader' ).remove();
$( '#gallery-scroller' ).imgSlider( images, large );
}
of course this mean altering the carousel.js to handle the additional passed array - no prob there...
works like a charm. I can now populate this with data, and place the carousel anywhere I need, and the large image viewer where I need it... bravo - thanks for the assist.

Efficent function replaceWith for multiple classes

The second "click" function of this script doesn't work, I think it's simply a syntax issue. I'm quite new to this. But I need to find a simple way call the live "click" function once for an array of vars.
The script works, just not the second part.
I'm looking for an efficient way to replaceWith an array of different vars, each matching a classed link, and without creating a new function every time.
Any suggestions would be great!
Thanks in advance
<script type="text/javascript">
$(window).load(function(){
$('a.pow').live("click",function(e) {
webgl = $('<iframe src="http://s..."> </iframe>');
e.preventDefault();
$('#slider-wrapper').replaceWith(webgl);
});
$('a.biff').live("click",function(e) {
video = $('<iframe src="http://s..."> </iframe>');
e.preventDefault();
$('#slider-wrapper').replaceWith(video);
});
});
</script>
html
<div id="slider-wrapper">
<div>
<a class="pow" href="">
</a>
</div>
<div>
<a class="biff" href="">
</a>
</div>
next one could be..
<div>
<a class="batman" href="">
</a>
</div>
</div><-- close slider wrapper -->
You can give all your anchors that will load iframes a common class, move the description of the anchor from class to a custom attribute, and have the event handler to act on the custom attribute instead.
<div id="slider-wrapper">
<div>
<a class="link" href="" data-desc="pow">
</a>
<div>
<div>
<a class="link" href="" data-desc="biff">
</a>
<div>
<div>
<a class="link" href="" data-desc="batman">
</a>
<div>
</div>
And in your script:
<script type="text/javascript">
var desc_url_map = {
"pow" : "http://s...",
"biff" : "http://s...",
"batman" : "http://s..."
};
$(window).load(function () {
$('a.link').live('click', function(evt) {
item = $('<iframe src="' + desc_url_map[this.dataset.desc] + '"></iframe>');
$('#slider-wrapper').replaceWith(item);
evt.preventDefault();
});
});
</script>
Hope there are no bugs :)

jQuery Newbie, need a little help

Okay, so I am in the process of recreating this feature:
http://www.w3.org/html/logo/#the-technology
I current have it so when you click on a link, it will add a class to the image that relates to that link (href="#one" on the <a> and then id="#one" on the <img>), however it is currently not going through each <a> tag and only one. And also it is not removing the class I requested.
Code follows:
JS
$(document).ready(function() {
var container = '#portfolio #text_container';
var img_container = '#portfolio #image_container';
$(container).children('a').bind('click', function() {
var this_attr = $(this).attr('href');
var this_img = $(img_container).find('img').attr('id');
if(this_attr == this_img) {
//$(img_container).find('img').hasClass('current').removeClass('current');
// ^^^ This line isn't working, any ideas? :/
$(img_container + ' img[id*="' + this_attr + '"]').addClass('current');
}
else {
alert(this_img + ' this img');
alert(this_attr + ' this attr');
}
});
});
And the HTML is as follows
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="current" id="#one" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" id="#two" />
</div>
<div id="text_container">
Item 1
Item 2
<p id="#one" class="current">A bunch of text!</p>
<p id="#two">The second bunch of text!</p>
</div>
</div>
Please let me know if you need any more information :)
rcravens fixed this with the following code..
JS
$(document).ready(function() {
$('#text_container a').click(function(evt) {
evt.preventDefault();
$('.current').removeClass('current');
var href = $(this).attr('href');
$("." + href).addClass('current');
});
And the HTML..
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="one current" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" class="two" />
</div>
<div id="text_container">
Item 1
Item 2
<p class="one current">A bunch of text!</p>
<p class="two">The second bunch of text!</p>
</div>
</div>
My interpretation of what you are trying to do is here:
http://jsfiddle.net/rcravens/wMhEC/
The code is changed a bit. You shouldn't have multiple elements with the same id.
Bob
The reason this isn't working:
if(this_attr == this_img)
is because this_attr is a URL and this_img is an ID attribute value.

Categories

Resources