Question

Basically, I can not get the More... link to animate the height of the next span when the link that has a class "dropdown" is clicked on. It just doesn't animate at all. It animates only when it is changed to a Less... link and the Less... link gets clicked to collapse the extra content in the paragraph. How can I get the More... link to animate when the content becomes shown? I am currently toggling the height, should I be doing something else instead?

Using the following jQuery code in $(document).ready(function() { });

$(".listitem").on("click", ".dropdown", function(event) {
    event.preventDefault();
    var $this = $(this);
    var type = $this.next("span").length > 0 && !$this.next("span").is(":visible") ? 'expand' : 'collapse';
    var theSpan = type == 'expand' ? $this.next("span") : $this.prev("span");
    if (type == 'expand') {
        $this.insertAfter(theSpan);
    }
    else
        $this.insertBefore(theSpan);

    theSpan.animate({height: 'toggle'}, 250, function(){
        $this.text(type == 'expand' ? ' [ Less... ]' : '[ More... ]');
    });
});

I have the following structured HTML within a ul tag (All li tags are the same structure):

<li>
   <div class="listitem">
      <span style="font-weight: bold;">Headline</span> Here is some body copy for the headline that should expand with an animation when clicking on the More... link right here. <a href="#" class="dropdown red">[ More... ]</a><span class="hidden">Here is more text to be shown and it should animate when the More... link is clicked, but it currently does not!</span>
   </div>
</li>

CSS:

ul
{
    list-style: none outside none;
    list-style-type: none;
}
ul li
{
    padding: .4em;
    margin-left: -20px;
}
.listitem
{
    display: table;
}
.hidden
{
    display: none;
}

EDIT

You can see the problem here: http://opportunityfinance.net/Test/conference-2013/highlights.html

I need the text to stay on the same line when it is expanded, it should not be pushed to the next line down. Is there some sort of white-space css way of doing this? or perhaps display: inline??

Was it helpful?

Solution

This is the only thing I can think of then. Just shows / hides each letter one at a time.

It will only become html once the text is fully loaded.

$(".expander").each(function(e) {
    var expanded = false, 
        isExpanding = false, 
        $this = $(this).text("[More...]");
    $this.click(function() {
        if(!isExpanding) {            
            isExpanding = true;
            if(!expanded) {
                var i = 0, 
                    interval = setInterval(function() {
                    if(i < $this.prev().text().length) {
                        $this.prev().prev().text($this.prev().text().substring(0, i));
                        i++;
                    } else {
                        $this.prev().prev().html($this.prev().html());
                        clearInterval(interval);
                        isExpanding = false;
                    }
               }, 1000 / 60);                
            } else {
                var i = $this.prev().text().length - 1, 
                    interval = setInterval(function() {
                    if(i >= 0) {
                        $this.prev().prev().text($this.prev().text().substring(0, i));
                        i--;
                    } else {
                        clearInterval(interval);
                        isExpanding = false;
                    }
                }, 1000 / 60);

            }
            expanded = !expanded;
        }
    });
}).prev().before("<span></span>").hide();

Demo

http://jsfiddle.net/CxX8n/9/

OTHER TIPS

<span> is an inline element so the height property doesn't apply. But you are trying to toggle height which is why animate() keeps forcing display: inline-block, and why it doesn't work the first time. So instead, try toggling opacity.

$(".listitem").on("click", ".dropdown", function(event) {
    event.preventDefault();
    var $this = $(this);
    var type = $this.next("span").length > 0 && !$this.next("span").is(":visible") ? 'expand' : 'collapse';
    var theSpan = type == 'expand' ? $this.next("span") : $this.prev("span");
    if (type == 'expand') {
        $this.insertAfter(theSpan);
    }
    else
        $this.insertBefore(theSpan);

    theSpan.animate({opacity: 'toggle'}, 250, function(){
        $this.text(type == 'expand' ? ' [ Less... ]' : '[ More... ]');
    });
});

Here's the JSFiddle

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top