Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I animate a strike through effect using JavaScript on a piece of text?

I want to try create an effect where by when I trigger an event an animated line strikes through a piece of text. The effect should be done in Java Script.

Can someone suggest some ways to do this? I have text already on a page and I would like the text to strike through from left to right as if a line is being drawn

like image 529
thiswayup Avatar asked Mar 20 '11 12:03

thiswayup


2 Answers

Using jQuery it's possible with little tweak: http://jsfiddle.net/yahavbr/EbNh7/

JS in use:

var _text = "";
$(document).ready(function() {
    _text = $("#myDiv").text();
    StrikeThrough(0);
});

function StrikeThrough(index) {
    if (index >= _text.length)
        return false;
    var sToStrike = _text.substr(0, index + 1);
    var sAfter = (index < (_text.length - 1)) ? _text.substr(index + 1, _text.length - index) : "";
    $("#myDiv").html("<strike>" + sToStrike + "</strike>" + sAfter);
    window.setTimeout(function() {
        StrikeThrough(index + 1);
    }, 100);
}

This will strike through myDiv text, making the line appear with animation.

As it's not using any heavy jQuery stuff it can be converted to plain JavaScript pretty easily so if you prefer not to use jQuery I'll edit my answer.

like image 134
Shadow Wizard Hates Omicron Avatar answered Sep 29 '22 20:09

Shadow Wizard Hates Omicron


var findText = function(element, pattern, callback) {

    if ( ! element.childNodes) {
      return;   
    }
    for (var childi = element.childNodes.length; childi-- > 0;) {
        var child = element.childNodes[childi];
        if (child.nodeType == 1) {
            findText(child, pattern, callback);
        } else if (child.nodeType == 3) {
            var matches = [];
            var match;
            while (match = pattern.exec(child.data))
            matches.push(match);
            for (var i = matches.length; i-- > 0;)
            callback.call(window, child, matches[i]);
        }
    }
}


findText(document.body, /./g, function(node, match) {
    var element = document.createElement('span');
    node.splitText(match.index + 1);
    element.appendChild(node.splitText(match.index));
    node.parentNode.insertBefore(element, node.nextSibling);
});

var spans = document.getElementsByTagName('span'),
    spansLength = spans.length,
    currentSpan = 0,
    interval = setInterval(function() {
        if (currentSpan == spansLength) {
            clearInterval(interval);
        }
        spans[currentSpan++].style.textDecoration = 'line-through';

    }, 100);

jsFiddle.

  • Go through each character (except \n) using regex and recursively apply function with callback to wrap each individual matched character with a span.
  • Select all these span elements and then use setInterval() to traverse them, adding style="text-decoration: line-through via the style object of the span.
  • Stop when we have iterated through each span.

The disadvantage of using innerHTML is when you serialize the HTML, you lose all events, etc. In the fiddle above, the strong element is still clickable (you will click the span, which will bubble up to the parent).

like image 35
alex Avatar answered Sep 29 '22 20:09

alex