Implementation focus: quick spoiler hiding

I’d like to share a very nifty, quick-to-whip-up piece of code I use for the book reviews I will be doing from here on out, in my Reader category: a short JavaScript snippet to hide spoilers (you can see it in action in my Mockingjay review). You see, I suck at making book reviews: I always inevitably talk about things that is best left to be discovered by a reader. So to help myself and anyone who might chance upon my reviews, a spoiler protection feature for my blog sounds just about right.

Why I didn’t go with the “More” tag route

WordPress has a feature that lets you force users to click through to the post’s dedicated page: essentially, hiding anything under the “More” tag when viewing in the blog index/posts list.

Insert More tag WP button

This works as a quick solution: but this didn’t really feel very “bright” to me. That’s an extra click and page load, and it means that I can’t have multiple spoilery sections in a single post. I don’t exactly know why I will need multiple separate spoilery sections, but far be it from me to set limitations on my writing style!

My solution

I went and used JavaScript to hide spoilers in the page. I did so for a couple reasons:

  1. Users won’t need to wait before seeing the hidden content: one click to surface it, and it’s there already.
  2. There is minimal break in the experience and tone of the entry.
  3. I could have as many spoilery sections in my entry, but the entry will still read as expected: you could just skip the spoilery sections easily.
  4. Users get the same experience whether they’re reading the entry on its own page or on the blog index page: spoilers will still be marked.
  5. Presentational text (show/hide spoilers) is not included in the content of the post.

The implementation

My library of choice is YUI3, but the same should also be relatively easy to do in other libraries, or even just plain JavaScript.

The script basically retrieves any and all tags with a class name of “spoiler” and hides everything inside that by lowering the opacity to 10%. This way, the user has a tantalizing, indistinct view of just how much they’re missing out by not reading the book/watching the movie! ;)

The script also adds its own text to the entry via JavaScript, saying that there are spoilers ahead and they can click on the text to toggle visibility. It’s not an actual link, but I wanted to style it slightly like a link–but you really have full freedom as to how you’d like the spoiler toggle warning to look like.

(As always, the best place to put the code below would be at the end of your page.)

<script type="text/javascript" src=""></script>
<script language="javascript">
YUI().use( "anim", function(Y){
    Y.all('.spoiler').each(function(o, i){
        var id = 'spoiler-' + i;
        var spoilerToggle = '<div id="spoiler-toggle-'+i+'" class="spoiler-toggle">Warning! Spoilers ahead! Click here to toggle spoiler visibility.</div>';
        Y.on( 'click', function(e){
            var opacityValue = ( o.getStyle('opacity') >= 0.9 ) ? 0.1 : 1;
            var anim = new Y.Anim({
                node: o,
                duration: 0.25,
                to : { opacity: opacityValue }
        }, '#spoiler-toggle-'+i );
        o.insert( spoilerToggle, o );

Without any HTML tags with the class “spoiler”, the script will not run unnecessarily, so you’re pretty free to use it for any page or post type.

To add styles specific to the spoiler toggle, you can use:

.spoiler-toggle { /* style for whole warning */ }
.spoiler-toggle span { /* style for toggle "link" */ }

Customizing the code

You can use the above code for almost any other similar purpose. You can change the element it hides by changing “.spoiler” at this line:

Y.all('.spoiler').each(function(o, i){

making sure that what you put in is a valid CSS selector (i.e., #some-id .some-class element or similar). It will then apply fading in/out to the whole element.

You can also well as change the wording of your toggle, or completely change it out to a different element (an image, or what-have-you) by changing the HTML at:

var spoilerToggle = '<div id="spoiler-toggle-'+i+'" class="spoiler-toggle">Warning! Spoilers ahead! Click here to toggle spoiler visibility.</div>';

making sure that you leave the outermost div with its ID intact.

Hope it’s useful, or helps you think of other ways to improve your site. Website improvement never needs to be a full-blown affair: a couple low-hanging fruit, small details here and there, makes the work worthwhile. ♥

Comments are closed. :( You can bother me at @angelamaria if you need to tell me something!