Set image width to span tag - javascript

I have this html code
<ul>
<li><img src="path_to_image1"><span>some text</span></li>
<li><img src="path_to_image2"><span>some text</span></li>
<li><img src="path_to_image3"><span>some text</span></li>
</ul>
Images are of different width.
I need to set width of SPAN element to be equal as IMG width.
Here is the code that I wrote by looking over the StackOverflow board.
$(document).ready(function() {
$("ul li a").each(function() {
var theWidth = $(this).find("img").width();
$("ul li a span").width(theWidth);
});
});
Now this code returns only width of the last image.
What to change so I can have width of span element same as img?
Thanks

$('ul li img').each(function() {
var imgWidth = $(this).width();
$(this).next('span').css({'width': imgWidth});
});

You just need to correct one line:
$("ul li a span").width(theWidth);
Replace with:
$(this).find('span').width(theWidth);

the answer is in your own code, almost..
$(this).find("span").width(theWidth);

Replace this line
$("ul li a span").width(theWidth);
with
$(this).find('span').width(theWidth);
Explanation: the line $("ul li a span").width(theWidth); sets the width for all three span elements.
The 'each' loop runs 3 times.
The first time it sets all three spans to the width of the first image.
The second time it sets all three spans to the width of the second image.
...

Can you just set the widths of the <li>'s to the same width as the image and set the <span> as display: block;
The spans will then be as wide as their contain (the <li>) and it saves you a little extra jquery trying to dig down to span level.
Also, to help speed up your jquery selector simply add an id to the list and target that instead of trying to match ul li a...; now all you have to do is match #widths.
Example
<ul id="widths">
<li><img src="path_to_image1"><span>some text</span></li>
<li><img src="path_to_image2"><span>some text</span></li>
<li><img src="path_to_image3"><span>some text</span></li>
</ul>
$(document).ready(function() {
$('#widths img').each(function() {
var imgWidth = $(this).width();
$(this).next('span').css({'width': imgWidth});
});
});

There are many ways around this, this worked for me though.
$(document).ready(function () {
$("ul li a img").each(function (index) {
$(this).next().width($(this).width()).css("display", "block");
});
});

Related

Selecting an element in the same parent as target

Assuming I have a set up of:
<ul id="cal">
<li><span>test</span><img /></li>
<li><span>test</span><img /></li>
<li><span>test</span><img /></li>
</ul>
and in the jQuery:
$('#cal li span').hover(function(){
$("#cal li img").trigger('mouseover');
});
I need to trigger mouseover on the #cal li img, but on only the image of the span rather than all of the images
You can refer to closest <img> using $(this).next() or with:
$("#cal li span").hover(function() {
$(this).siblings("img").trigger("mouseover");
});
Specify it is linked to your context with:
$('#cal li span').hover(function(){
$(this).parent().find("img").trigger('mouseover');
});
$('#cal li span').hover(function(){
$(this).next("img").trigger('mouseover');
});

Show absolutely pos. div on hover in list

I have a simple question yet it's not working out. See this html:
<div id="viewer">
<ul class="tj_gallery">
<li><img src="images/projecten/main/chicane.png" alt="" width="280" height="178" />01</li>
</ul>
</div>
The a.abhover is absolutely positioned inside the relative li. The a.abhover has display:none; in CSS. If I hover one li (it's a long list!) the a.abhover should fadeIn # 1000ms. Right now this is working, but only for every single one of those li's. See my jQuery code:
$(".tj_gallery li").hover(function(){
$(".tj_gallery li a.abhover").stop(true,true).fadeIn("fast");
}, function(){
$(".tj_gallery li a.abhover").stop(true,true).fadeOut("fast");
});
Adding $(this, ".tj_gallery li a.abhover") or $(".tj_gallery li a.abhover", this) doesn't help (it breaks it).
$(".tj_gallery li").hover(function(){
$("a.abhover", this).stop(true,true).fadeIn("fast");
}, function(){
$("a.abhover", this).stop(true,true).fadeOut("fast");
});

Using javascript function parameters to show jquery tabs

Actually I am trying to do jquery tabs. I have written a code that needs rework and probably better ways to implement. I think I could use function arguments to achieve this, but I am not sure. Can somebody tell me how to achieve this in a better way. Though my code works but I think it is rudimentary. I would also like only one tab to display a background color if this is active.
http://jsfiddle.net/5nB4P/
HTML:
<div id="nav">
<ul>
<li>First Tab</li>
<li>Second Tab</li>
<li>Third Tab</li>
</ul>
</div>
<div id="content">
<div class="tabs first">First Div content</div>
<div class="tabs">Second Div content</div>
<div class="tabs">Third Div content</div>
</div>
Script:
$(function() {
$("li :eq(0)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(".tabs:gt(0)").hide();
$(".tabs:eq(0)").show();
})
$("li :eq(1)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(this).css("background","red")
$(".tabs:gt(1), .tabs:lt(1)").hide();
$(".tabs:eq(1)").show();
})
$("li :eq(2)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(".tabs:lt(2)").hide();
$(".tabs:eq(2)").show();
})
})
There is a much better way to achieve this. Here you go
$(function() {
$("li").click(function() {
$(this).css("background","red").siblings().css("background","none");
$(".tabs").hide().eq($(this).index()).show();
return false;
});
})
Working Demo
As #Niels mentioned for setting the background style you can have a dedicated class(active) and add/remove this class instead of setting the inline sytle.
FYI..In the above code $(this).index() gives the position of the first element within the jQuery object relative to its sibling elements
CSS:
.active {
background-color:red;
}
JQuery:
$('li').click(function(){
$this = $(this);
$this.addClass('active').siblings().removeClass('active');
$('.tabs:eq(' + $this.index() + ')').show().siblings().hide();
});
Here is a demo: http://jsfiddle.net/5nB4P/6/
Here is the way that I updated this to make it smaller and I believe to be more effective and easier to use:
http://jsfiddle.net/5nB4P/7/
Code:
$("#nav ul li").click(function(){
var id = $(this).attr("rel");
$("#nav ul li").each(function(){
$(this).removeClass("active");
});
$(this).addClass("active");
$("#content div").each(function(){
$(this).hide();
});
$("#"+id).show();
});
Do you mean this? http://jsfiddle.net/tsukasa1989/5nB4P/1/
$(function() {
$("#nav li").click(function(){
// Handle active status
$(this).addClass("active").siblings().removeClass("active");
// Show the tab at the index of the LI
$(".tabs").hide().eq($(this).index()).show();
})
// Don't forget to set first tab as active one at start
.eq(0).addClass("active");
})
If you want to style the active tab use
#nav li.active{}
My approach doesn't use arguments, but HTML class and id references to shorten things: http://jsfiddle.net/ZScGF/1/

Conflict between some JavaScript and jQuery on same page

I am using a JavaScript function and some jQuery to perform two actions on a page. The first is a simple JS function to hide/show divs and change the active state of a tab:
This is the JS that show/hides divs and changes the active state on some tabs:
var ids=new Array('section1','section2','section3');
function switchid(id, el){
hideallids();
showdiv(id);
var li = el.parentNode.parentNode.childNodes[0];
while (li) {
if (!li.tagName || li.tagName.toLowerCase() != "li")
li = li.nextSibling; // skip the text node
if (li) {
li.className = "";
li = li.nextSibling;
}
}
el.parentNode.className = "active";
}
function hideallids(){
//loop through the array and hide each element by id
for (var i=0;i<ids.length;i++){
hidediv(ids[i]);
}
}
function hidediv(id) {
//safe function to hide an element with a specified id
document.getElementById(id).style.display = 'none';
}
function showdiv(id) {
//safe function to show an element with a specified id
document.getElementById(id).style.display = 'block';
}
The html:
<ul>
<li class="active"><a onclick="switchid('section1', this);return false;">ONE</a></li>
<li><a onclick="switchid('section2', this);return false;">TWO</a></li>
<li><a onclick="switchid('section3', this);return false;">THREE</a></li>
</ul>
<div id="section1" style="display:block;">TEST</div>
<div id="section2" style="display:none;">TEST 2</div>
<div id="section3" style="display:none;">TEST 3</div>
Now the problem....
I've added the jQuery image gallery called galleria to one of the tabs. The gallery works great when it resides in the div that is intially set to display:block. However, when it is in one of the divs that is set to display: none; part of the gallery doesn't work when the div is toggled to be visible. Specifically, the following css ceases to be written (this is created by galleria jQuery):
element.style {
display:block;
height:50px;
margin-left:-17px;
width:auto;
}
For the life of me, I can't figure out why the gallery fails when it's div is set to display: none. Since this declaration is overwritten when a tab is clicked (via the Javascript functions above), why would this cause a problem? As I mentioned, it works perfectly when it lives the in display: block; div.
Any ideas? I don't expect anybody to be familiar with the jQuery galleria image gallery... but perhaps an idea of how one might repair this problem?
Thanks!
If you are including jQuery then you can shorten your javascript to this:
$(function() {
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would also remove the inline styles that set display:none. Then you can in your javascript you can initialize galleria then hide your sections.
Something like:
$(function() {
$('#section2, #section3').hide();
$('#section2 .images').galleria();
var sections = $('#section1, #section2, #section3');
function switchid(id, el){
sections.hide();
$('#'+id).show();
$(this).addClass('active').closest('ul').find('li').removeClass('active');
}
});
I would even go further and change your html to be something like this:
<ul class="sectionlinks">
<li class="active">ONE</li>
<li>TWO</li>
<li>THREE</li>
</ul>
<div id="section1" class="section">TEST</div>
<div id="section2" class="section">TEST 2</div>
<div id="section3" class="section">TEST 3</div>
Then you javascript could just be:
$(function() {
$('#section2 .images').galleria();
$('#section2, #section3').hide();
var sections = $('.section');
$('.sectionlinks a').click(function(e){
e.preventDefault();
sections.hide();
$($(this).attr('href')).show();
$(this).closest('ul').find('li').removeClass('active');
$(this).closest('li').addClass('active');
});
});
Working example: http://jsfiddle.net/cdaRu/2/
Set them all to 'block' by default, initialize the galleria image gallery, and afterwards hide the divs you want hidden and see if that fixes it. Or try initializing the gallery again after every switchid.
My first recommendation would be to re-write your original Javascript function to use jQuery. It already has built-in visibility toggle functions ... using the same system will minimize conflicts and make for smoother code.
This is just "off the cuff" but perhaps the box model is incomplete: "The element will generate no box at all" with display: none;
Perhaps change that back to "block" and set visibility: hidden; would be better?

jQuery .hover() is driving me crazy

I have a project that uses drop-down menus that are nested ul's, like so:
<ul id="nav">
<li id="thome" class="navtab">
HOME
<ul id="subnav_home" class="submenu">
<li>Dashboard</li>
<li>SMS</li>
<li>Email</li>
<li>Twitter</li>
</ul>
</li>
</ul>
Using jQuery, I've added a .hover() to the .navtab li that .show()s the .submenu ul. The problem is that when the cursor moves into the new ul, the .hover()-out for the .navtab fires, .hide()ing the sub-menu, despite the fact that I have the height of the li so that it entirely wraps the .submenu ul.
I've tried adding a delay to the .hide(), but if you pass your cursor over the navtab bar quickly, you get all of the sub-menus at once.
Any solutions for me? Here's the relevant JavaScript. The hide() function is identical to .show() except that it shrinks the height and hides the ul (obviously).
$('.navtab').hover(
function(){
tabShowSubnav($(this).attr('id'));
},
function(){
tabHideSubnav($(this).attr('id'));
});
function tabShowSubnav(menu){
var sb = '#' + menu + ' > .submenu';
var tb = '#' + menu;
$('.navtab').each(function(){
if (!$(this).hasClass('current_page')){
$(tb).addClass('nav_hover');
}
});
$(tb).css('height','239px');
$(sb).show();
}
$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('current_page').addClass("nav_hover");
},
function() {
});
$(".submenu").mouseout(function(){
$(this).hide();
});
$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('.current_page').addClass("nav_hover");
},
function() {
$(this).children(".submenu").hide();
});
This worked for me.
I finally had to go with the jQuery plugin hoverIntent, that ignores children for the purpose of mouseout.

Categories