【问题标题】:How do I animate a strike through effect using JavaScript on a piece of text?如何在一段文本上使用 JavaScript 制作删除线效果?
【发布时间】:2023-03-07 12:25:01
【问题描述】:

我想尝试创建一种效果,当我触发一个事件时,一条动画线穿过一段文本。效果应该用Java Script来完成。

有人可以建议一些方法吗?我的页面上已经有文字,我希望文字从左到右贯穿,就像正在画一条线一样

【问题讨论】:

  • 您使用什么标记? Vanilla JavaScript,或者您正在使用库(jQuery、MooTools、Glow、Scriptaculous..)?
  • 目前未提交任何框架。虽然可以让它与 dojo 一起使用会很好。

标签: javascript animation


【解决方案1】:

使用 jQuery 只需稍作调整即可:http://jsfiddle.net/yahavbr/EbNh7/

正在使用的JS:

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);
}

这将删除myDiv 文本,使线条出现动画。

由于它没有使用任何繁重的 jQuery 东西,它可以很容易地转换为纯 JavaScript,所以如果你不想使用 jQuery,我会编辑我的答案。

【讨论】:

  • 这很酷,但最好不要使用html() 序列化 HTML,这将删除所有其他附加事件。
  • @alex 我假设没有这样的事件,只是举个简单的例子.. 什么可能是更好的替代 IYO?
  • 我自己添加了an answer
【解决方案2】:
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.

  • 使用正则表达式遍历每个字符(\n 除外)并递归地应用带有回调的函数以将每个匹配的字符包装为 span
  • 选择所有这些span元素,然后使用setInterval()遍历它们,通过stylestyle对象添加style="text-decoration: line-through
  • 当我们遍历每个 span 时停止。

使用innerHTML的缺点是当你序列化HTML时,你会丢失所有事件等。在上面的小提琴中,strong元素仍然是可点击的(你会点击span,它会冒泡给父母)。

【讨论】:

  • +1 当然,但是我怀疑 OP 希望文档中的 all 文本被删除? :)
  • @Shadow OP 可以简单地将document.body 更改为他们想要的任何元素,非常感谢。
  • 当然,知道.. :) 另外,您使用的是document.getElementsByTagName('span'),所以这也需要更改以支持特定元素。
  • @alex 这不是有点矫枉过正吗?请告诉我您对此有何看法: 1. 在带有删除线的文本节点之前创建一个跨度。 2. 循环遍历文本,并按间隔将每个 char 移动到新的 span。 3. 如果原始元素是一个跨度,给它加上删除线并将所有文本移回其中(以维护事件)并删除新的跨度。否则就是这样!
【解决方案3】:

您可以使用 jQuery 为看起来像删除线的背景图像设置动画。也许是这样的:

$(".someclass").animate({backgroundPosition: '0px 0px'})

这可能看起来比尝试做一些涉及&lt;s&gt; 标签的事情要顺利一些。您的 HTML 标记将如下所示:

<span class="someclass">Lorem ipsum</span>

并且您需要确保.someclass 具有使用背景位置隐藏背景图像的默认 CSS,即:

.someclass { background-position: -1000px 0px; }

【讨论】:

  • 好主意。不过,我认为这不适用于换行符。
【解决方案4】:

我会在带有删除线样式的文本之前创建一个空白跨度。然后,我会编写一个函数,将文本前面的第一个字符弹出并将其附加到您的跨度中。然后,使用 setTimeout() 重复调用该函数,直到该段文本为空。

您要求提供建议 - 代码需要更长的时间 :)

【讨论】:

  • 我会这样做,但使用setInterval,而不是setTimeout
【解决方案5】:

刚从谷歌来到这里,最后写了我自己的简单小函数。我就是这样做的:

function drawLineOnClick() {

    //add or prepend div to the top of the div holding your text
    $("#IdOfElementHoldingTheText").prepend('<div id="lineThrough"></div>');
    var WidthStrikeThrEl = $("#IdOfElementHoldingTheText").width();

    $("#lineThrough").animate({width: WidthStrikeThrEl},1000, function() {

        //when line has been drawn, apply CSS line-through and remove line
        $("#IdOfElementHoldingTheText").attr('class', 'lineThrCssClass');
        $("#lineThrough").remove();
    });
}


#lineThrough {
  position:absolute;
  top:23px; //centering line over text to simulate actual line through
  width:0px;
  height:1px;
  background:#444; //color of line through
}

.lineThrCssClass {
    color:#444;
    text-decoration:line-through;
}

【讨论】:

    【解决方案6】:

    您可以在字符串的开头添加一个&lt;s&gt; 标记,然后将结束的&lt;/s&gt; 标记反复移动到字符串的末尾一个字符,最好使用setTimeout()

    类似的东西(未测试):

    STRIKE_POS = 1;
    ORIG_STR = '';
    
    function startStrike(str) {
        STRIKE_POS = 1;
        ORIG_STR = str;
        strike();
    }
    
    function strike() {
        var str = '<s>' + ORIG_STR.substr(0, STRIKE_POS) + '</s>'
                  + ORIG_STR.substr(STRIKE_POS);
    
        // DO SOMETHING WITH THE STRING, LIKE DISPLAY SOMEWHERE
    
        STRIKE_POS++;
        if (STRIKE_POS < ORIG_STR.length) {
            window.setTimeout("strike()", 200);    // adjust the timeout
        }
    }
    

    【讨论】:

      【解决方案7】:

      这是一个适用于当前版本的 IE、Firefox 和 Chrome 的基本实现:

      <html>
          <head>
              <script type="text/javascript">
                  window.gradualStrike = function(spanId, timeMillis) {
                      var stepDuration;
                      var strikeElem = document.getElementById(spanId);
                      var strikeText = strikeElem.innerHTML.replace("<S>", "<s>").replace("</S>", "</s>");  //IE uppercases the tag
                      var currentStrikePos = strikeText.indexOf("</s>");
                      if (currentStrikePos < 0) {
                          currentStrikePos = 0;
                          stepDuration = timeMillis / strikeText.length;
                      }
                      else {
                          if (currentStrikePos + 3 == strikeText.length) {
                              //the '</s>' is at the end, we are done
                              return;
                          }
                          currentStrikePos -= 3; //account for the '<s>' tag
                          stepDuration = timeMillis / (strikeText.length - 7);  //account for '<s>' and '</s>'
                          strikeText = strikeText.replace("<s>", "").replace("</s>", ""); //strikeText.replace(/\<s\>/, "").replace(/\<\/s\>/, "");
      
                      }
                      currentStrikePos++;
                      strikeText = "<s>" + strikeText.substring(0, currentStrikePos) + "</s>" + strikeText.substring(currentStrikePos);
                      strikeElem.innerHTML = strikeText;
                      setTimeout("gradualStrike('" + spanId + "', " + timeMillis + ");", stepDuration);
                  };
              </script>
          </head>
          <body>
              <span id="someText" onclick="gradualStrike('someText', 1000); this.onclick=function(){return;};">Click to strike...</span>
          </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-23
        • 2013-08-21
        • 1970-01-01
        • 2011-07-05
        • 2022-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多