Doidgey Doidgey - 7 months ago 29
Javascript Question

jQuery calculate widths and change siblings on hover

The Goal



I want all my list items running horizontally across the page width the total width of all the li equaling 100%. I then want there to be one active li which is equal to 45% and for the script to calculate what the other li's width would compute once the active is triggered in order to keep the total to within the 100% limit to keep them all running horizontal.

I have some code that I'm trying to work it out with.

So far...



My code — as you will see — will change the width of the hovered element and adjust the children. However it only adjusts the children on
hoverout
. I can't quite work out how to make this work cleanly. I feel my approach is messy...

Help appreciated. See below for code and working example.

HTML:

<div class="tours">
<ul class="tours-List">
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
<li>
<h2>Tour Item</h2>
<a href="#">View more</a>
</li>
</ul>
</div>


jQuery:

var
$li = $('.tours li'),
$is_active = false;

function checkActive() {
if (!$li.hasClass("is-Active")) {
$li.css({
"width": 100 / $li.length + "%"
});
} else{
$li.css('width', 58 / ($li.length -1) + "%");
}
}

$li.css({
"float": "left",
"width": 100 / $li.length + "%"
});

$li.hover(function(e){
$is_active = true;
$(this).addClass("is-Active");
$(this).css('width', '42%');

}, function(){
$is_active = false;
$(this).removeClass("is-Active");
checkActive();
});


Live example


Answer

As I said in the comments, here is the js, simplified.

var $li = $('.tours li');
var widthPercentLeftWhenOneIsActive = 100-40; // you should use constant of course...

init();

function init(){
    $li.css({
        "float": "left",
        "width": 100 / $li.length + "%"
    });
};

$li.hover(function(e){
        $(this).css("width","");//remove inline style
        $(this).addClass("is-Active");
        //$(this).css('width', '42%'); move it to the css
        shrinkNonActiveItems();
}, function(){
        $(this).removeClass("is-Active");
        unShrinkAll();
});

function shrinkNonActiveItems(){
    $li.each(function(index, item){
        if(! $(item).hasClass("is-Active")){
            $(item).css("width", (widthPercentLeftWhenOneIsActive /     ($li.length-1))+"%" );
        }
    });
};

function unShrinkAll(){
    $li.each(function(index, item){
        $(item).css("width",100 / $li.length + "%");
    });    };

And a little bit of css

li.is-Active{
        width:40%;
    };