【问题标题】:jQuery News Ticker: .remove() dom effectjQuery News Ticker: .remove() dom 效果
【发布时间】:2015-07-15 08:07:01
【问题描述】:

我正在尝试制作一个新闻自动收报机(没有任何插件)。 我使用 jQuery UI 的 animate 方法让新闻从右向左移动。

我正在删除第一个新闻 (li) 并将其附加到列表的末尾 (ul) 并重新调整左边距。 这不是为了在每个循环之后都得到一个长的空白。

问题是......当我 .remove() 第一条新闻时,它会导致不良的 UI 故障(至少对我而言)。 这部分:

leftMargin = leftMargin + $('.news-ticker-display li:first').width() - 2;
$('.news-ticker-display li:first').remove();

这是我的jsFiddle 链接:

任何帮助/建议/评论/替代方法将不胜感激。 抱歉,我想不出一个建设性的标题。哈哈

【问题讨论】:

  • 欢迎来到 SO。 +1 为工作 JSFiddle 示例提供了一个措辞清晰的问题。如果只有所有新手都这样做:)

标签: jquery news-ticker


【解决方案1】:

您的代码正在等待下一个动画循环来更新左边距,这会在几帧之后发生。您需要立即设置它(与remove() 在同一帧上)以避免视觉故障。

var leftMargin, scrollSpeed;
var playScroll = true;

scrollSpeed = 5;
leftMargin = 0;

function autoPlay() {
    if (playScroll) {
        $('.news-ticker-display').animate({ marginLeft: --leftMargin }, scrollSpeed, "linear", function () {
            var $first = $('.news-ticker-display li:first');
            var width = $first.outerWidth();
            if (leftMargin < -width) {
                $first.clone().appendTo('.news-ticker-display ul');
                leftMargin = leftMargin + width;
                $first.remove();
                $(this).css({marginLeft: --leftMargin});
            }
            autoPlay();
        });
    }
}

autoPlay();

JSFiddle: https://jsfiddle.net/TrueBlueAussie/8djw6qen/8/

注意事项:

  • 您会看到我使用临时变量简化了代码。最好不要重复 jQuery 选择器。
  • 您还需要使用outerWidth(),而不是尝试补偿边框。
  • 我加快了测试动画的速度(否则会花很长时间才能看到故障):) 只需将其设置回您自己的值即可。
  • 您可以使用上下文减少第一个选择器。例如var $first = $('li:first', this);
  • .first() 传统上比在选择器中使用 :first 更快,但这并不重要:)

【讨论】:

  • 我知道我有偏见,但我认为我的解决方案更好。因为使用--leftMargin 将导致动画回调运行每个像素,因为您基本上是一次为一个像素设置动画。
  • @alan0xd7:我不同意您的具体解决方案在技术上可能更好。我只是解释了所提出的问题并修复了代码原样并详细解释了任何改进/更改。这通常会使 OP 更容易消费。也许如果你改进了你的答案(不是代码,我相信这很好)?
  • @TrueBlueAussie 谢谢,我已经更新了我的答案并解释了为什么我改变了动画的工作方式。
  • 您好 alan0xd7,感谢您的指点。 ^_^ 但我实际上需要动画在每个像素中发生。理由是,因为它是一个新闻自动收报机,我有一个播放/暂停按钮,我的 sn-ps 中没有包含它... + 悬停时停止动画等(lol 用户)。每次运行动画都可以在我希望的时候轻松打破它(playScroll = false)。如果动画不是每次都在运行,则停止/重新启动动画会更困难。
【解决方案2】:

我重新实现了动画的工作原理。现在它一次动画一个宽度的股票项目。

我相信这是一种更好的方法,因为通过使用--leftMargin,您的动画回调每个像素都会运行,而使用这种方法,它只会在一个项目滚动后运行。也无需检查项目是否已超过起点。

通过将动画持续时间设置为width*scrollSpeed,每个像素都以相同的速率滚动。

注意outerWidth 被使用,因为它将包括项目的任何边框和填充。

function autoPlay() {
    if(!playScroll) return;

    var width = $('.news-ticker-display li:first').outerWidth();
    var animateTime = width*scrollSpeed;

    $('.news-ticker-display').animate({ marginLeft: -width }, animateTime, "linear", function(){
        $('.news-ticker-display li:first').clone().appendTo('.news-ticker-display ul');
        $('.news-ticker-display li:first').remove();
        $('.news-ticker-display').css("marginLeft", 0);
        autoPlay();
    });
}

演示:https://jsfiddle.net/alan0xd7/8djw6qen/6/

【讨论】:

    猜你喜欢
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2021-11-02
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多