【问题标题】:Scrolling link text on hover - endless marquee effect悬停时滚动链接文本 - 无尽的选框效果
【发布时间】:2020-03-22 18:58:05
【问题描述】:

我正在寻找一种高性能且流畅的解决方案,用于在其内联块框内滚动文本的链接,就像选取框效果一样。

 $(document).ready(function() {
    
    function scroll(ele){
    	var s = $(ele).text().substr(1)+$(ele).text().substr(0,1);
	    $(ele).text(s);
    }

    scrollInterval = null;
    function startScrolling(e) {
        if (!scrollInterval) {
            scrollInterval = setInterval(function(){
                scroll(e)
            },100);
        }
    }

    function stopScrolling(e) {
        clearInterval(scrollInterval);
        scrollInterval = null;
    }

    $(".mali").hover(function(){
        startScrolling($(this));
    });

    $(".mali").mouseout(function(){
        stopScrolling($(this));
    });

    $(".mali").mousedown(function(){
        stopScrolling($(this));
    });

  });
.mali {
        display: inline-block;
        background: black;
        color: white;
        padding: 10px;  
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.

到目前为止,我的解决方案实际上是我在另一个线程的 stackoverlow 上找到的,并尝试使用它。

不过有两个问题。

1.) 由于这基本上是使用间隔来循环单个字母,因此效果不是很平滑。效果是口吃。

有没有人知道如何使这更顺畅?也许在那种情况下根本不使用这种方法,也许使用 CSS 过渡来为文本设置动画?

2.) 有没有人有一个聪明的解决方案来解决我悬停后如何返回到初始状态?我想要悬停效果,但是当将鼠标从链接上移开时,它应该动画回到初始文本状态。

谢谢, 马特

【问题讨论】:

    标签: javascript jquery animation scroll marquee


    【解决方案1】:

    2) 你可以保存初始状态,然后恢复它:

    $(document).ready(function() {
        
        function scroll(ele){
        	var s = $(ele).text().substr(1)+$(ele).text().substr(0,1);
    	    $(ele).text(s);
        }
    
        scrollInterval = null;
        function startScrolling(e) {
            if (!scrollInterval) {
                $(e).data("text", $(e).text());
                scrollInterval = setInterval(function(){
                    scroll(e)
                },100);
            }
        }
    
        function stopScrolling(e) {
            clearInterval(scrollInterval);
            scrollInterval = null;
            $(e).text($(e).data("text"));
        }
    
        $(".mali").hover(function(){
            startScrolling($(this));
        });
    
        $(".mali").mouseout(function(){
            stopScrolling($(this));
        });
    
        $(".mali").mousedown(function(){
            stopScrolling($(this));
        });
    
      });
    .mali {
            display: inline-block;
            background: black;
            color: white;
            padding: 10px;  
            transition: all .2s;
          }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.

    1) 作为一个流畅的动画,我认为这是一个 PoC。也许它会帮助你进一步的想法。

    $(document).ready(function() {
        // Those global data could be stored in element's data.
        var indent = 0,
            width = 0,
            padding = 10;
        function scroll(ele){
          // Every iteration decrease indent by value
          indent -= 1;
          
          // If is indent greater than or equal than real width
          // (width with padding) reset indent.
          if(-indent >= width+padding)
            indent = 0;
           
           // Aplly property
          $(ele).css("text-indent", indent);
        }
    
        var scrollInterval = null;
        function startScrolling(e) {
            if (!scrollInterval) {
                // Get text and real width
                let text = $(e).text();
                width = $(e).width()
              
                $(e)
                  // Set real width & height, so that container stays
                  .width($(e).width())
                  .height($(e).height())
                  
                  // Save text to data for reset
                  .data("text", text)
                  
                  // Add 2 spans with text:
                  // <span>text</span><span>text</span>
                  // Where second span has defined padding on the left
                  .html($("<span>").text(text))
                  .append($("<span>").text(text).css("padding-left", padding+"px"));
                 
               resumeScrolling(e);
            }
        }
    
        function stopScrolling(e) {
            pauseScrolling(e);
            
            // Reset
            $(e)
              // Revert real text and reset indent
              .text($(e).data("text"))
              .css("text-indent", indent = 0);
        }
    
        function pauseScrolling(e) {
            clearInterval(scrollInterval);
            scrollInterval = null;
        }
    
        function resumeScrolling(e) {
            if (!scrollInterval) {
              // Every 30ms repeat animation. It must be at least 25x per second
              // so it runs smoothly. (So 1 - 40).
              scrollInterval = setInterval(function(){
                scroll(e)
              },30);
           }
        }
    
        $(".mali").hover(function(){
            startScrolling($(this));
        });
    
        $(".mali").mouseout(function(){
            stopScrolling($(this));
        });
    
        $(".mali").mousedown(function(){
            stopScrolling($(this));
        });
    
        $("#start").click(function(){
          startScrolling($(".mali"));
        });
        $("#stop").click(function(){
          stopScrolling($(".mali"));
        });
        $("#pause").click(function(){
          pauseScrolling($(".mali"));
        });
        $("#resume").click(function(){
          resumeScrolling($(".mali"));
        });
    
      });
    .mali {
      display: inline-block;
      background: black;
      color: white;
      padding: 10px;
      /*
      This could help, but you can't reset text-indent without animation.
      transition: all .1s;
      */
      overflow: hidden;
      vertical-align: middle;
    }
    
    /* When you hover element, new span elements
    can't take pointer events, so your elements
    stays hovered. */
    .mali span {
      pointer-events: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.
    
    <br><br>
    <button id="start">Start</button>
    <button id="stop">Stop</button>
    <button id="pause">Pause</button>
    <button id="resume">Resume</button>

    这背后的想法是:

    • 制作元素overflow:hidden;,这样不会有文字溢出
    • 设置固定尺寸
    • 里面有重复的文字
    • 每 x 毫秒更改一次文本缩进(x
    • 当它溢出时,重置它,使它可以无限循环

    【讨论】:

    • ……非常感谢。你能给我一些关于你在选项2中所做的事情的简单描述吗?如果我用鼠标在链接上停留的时间更长,它很快就会自行重置。
    • 我解释并添加了平滑重置,包括填充。
    • 感谢您的大力支持!惊人的。关于“设置修复尺寸”......你在这里是什么意思?我希望它在具有特定类的所有链接上“开箱即用”,我不必设置固定宽度。另外,还有一件事。我将如何重置它?最后一个问题,如果我希望它与其他文本一致,我会简单地使用填充或边距(或相对位置)将它再次移动到行中吗?由于溢出隐藏当然会破坏基线。
    • 因为有重复的文本,并且会溢出,您需要使用绝对尺寸修复容器。但是会有真实物体的尺寸,所以它不是硬编码的。但是,是的,填充尚未修复,必须对其进行重构。重置,只需调用stopScrolling 即可重置它。所以恢复文本(来自数据)并最终删除固定尺寸(将宽度和高度设置为自动)。 vertical-align: middle; 将帮助您再次居中。
    • @M1KO 我无法自己进行 stopScrolling 重置。你能帮我最后一次吗?提前致谢。垂直对齐效果很好,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    相关资源
    最近更新 更多