4

Since .toggle() was deprecated from jQuery, I am looking for a new simple solution which will enable me to create a "Read more" button which slides down a paragraph whilst changing the button text to "Read less".

I have put together this working code:

var moreText = "Read more";
var lessText = "Read less";

$(document).ready(function () {
    $("a.readmorebtn").text(moreText);
    $("a.readmorebtn").toggle(function () {
        $("a.readmorebtn").text(lessText);
        $("p.more").slideToggle(0);
    },

    function () {
        $("a.readmorebtn").text(moreText);
        $("p.more").slideToggle(0);
    });
});

http://jsfiddle.net/approach/gDvyR/

You'll see in the fiddle that 'Migrate 1.1.0' is checked on the options on the left, which is the only way to make .toggle() work in this way with this (newest) version of jQuery.

My question is, can you think of another way of performing the same function but without using .toggle() and Migrate?

Apologies if you feel this question has been answered elsewhere, but I keep finding hints at the workarounds being "relatively straightforward", without really seeing any definitive approaches. Unfortunately being new to jQuery it doesn't seem so straight forward to me!

Many, many thanks.

slava
  • 1,901
  • 6
  • 28
  • 32
Sam Baldwin
  • 413
  • 1
  • 6
  • 20

2 Answers2

5

I personally think all the answers here are too elaborate for what you need. This should do the trick just fine and it works with multiple occurences. http://jsfiddle.net/BramVanroy/gDvyR/5/

var moreText = "Read more",
    lessText = "Read less",
    moreButton = $("a.readmorebtn");

moreButton.click(function () {
    var $this = $(this);
    $this.text($this.text() == moreText ? lessText : moreText);
    $this.next("p.more").slideToggle("fast");
});
Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239
  • This is totally unnecessary change, but since in the 7th line, the `.text()` is always applied, you might as well just determine which text is applied inside `.text()`: `$this.text( $this.text() == moreText ? lessText : moreText );` -- http://jsfiddle.net/lollero/gDvyR/4/ – Joonas Feb 26 '13 at 09:49
  • @Joonas Good call. Edited. :) – Bram Vanroy Feb 26 '13 at 10:17
  • This works great! Now I'll have to make sure I understand what's going on that is making it work. Thank you @BramVanroy and Joonas. – Sam Baldwin Feb 26 '13 at 10:26
  • 2
    @Sam, I didn't want to clutter the answer, so I added some explanatory comments to explain what is going on with the code: http://jsfiddle.net/lollero/gDvyR/6/ – Joonas Feb 26 '13 at 11:18
1

Here's a generic replacement :

$.fn.toggleFuncs = function() {
    var functions = Array.prototype.slice.call(arguments),
    _this = this.click(function(){
        var i = _this.data('func_count') || 0;
        functions[i%functions.length]();
        _this.data('func_count', i+1);
    });
}

You use it as you would use toggle :

$('something').toggleFuncs(f1, f2, f3);

Demonstration

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Thanks @dystroy. For some reason though, in your demonstration I get the "Read less" text appear after the second paragraph is closed. I'm not sure why this could be happening, the code seems to make sense to me. – Sam Baldwin Feb 26 '13 at 10:24
  • @Sam I just inverted the two last lines to ensure the first function passed is the first one to be called. – Denys Séguret Feb 26 '13 at 11:23