1

当用户将鼠标悬停在输入上时,此代码会在输入中产生打字机动画效果,它会为占位符文本设置动画。当用户离开时,我希望动画停止并且输入恢复到原始状态。

$(function() {

    var sppInput,
        sppInputName = $('#spp-input-name'),
        sppInputNamePlace = sppInputName.attr('placeholder');

    // Typewriter Effect
    function sppInputStart(elm, n, text) {
        if (n < (text.length)) {
            $(elm).attr('placeholder', text.substring(0, n + 1));
            n++;
            sppInput = setTimeout(function () {
                sppInputStart(elm, n, text);
            }, 80);
        }
    }
    function sppInputStop(elm, place) {
        clearTimeout(sppInput);
        $(elm).attr('placeholder', place);
    }

    // Typewriter Effect for Name
    sppInputName.mouseover(function () {
        sppInputStart(this, 0, sppInputName.data('typewriter'));
    });
    sppInputName.mouseout(function () {
        sppInputStop(this, sppInputNamePlace);
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder="Name" data-typewriter="Insert the Name" type="text" id="spp-input-name" name="name" required>

此代码适用于所有浏览器(包括 IE),但不适用于 firefox。

为什么?

4

2 回答 2

1

看起来像更改placeholder值重新触发mouseover事件

一个有效的“黑客”:

$(document).ready(function() {

    var sppInput,
        sppInputName = $('#spp-input-name'),
        sppInputNamePlace = sppInputName.attr('placeholder');

    // Typewriter Effect
    function sppInputStart(elm, n, text) {
        if (n < (text.length)) {
            $(elm).attr('placeholder', text.substring(0, n + 1));
            n++;
            sppInput = setTimeout(function() {
                sppInputStart(elm, n, text);
            }, 80);
        }
    }

    function sppInputStop(elm, place) {
        clearTimeout(sppInput);
        $(elm).attr('placeholder', place);
    }

    // Typewriter Effect for Name
    sppInputName.mouseover(function() {
        // hack
        if ($(this).data('flag') != '1') {
            $(this).data('flag', '1');
            sppInputStart(this, 0, sppInputName.data('typewriter'));
        }
    });
    sppInputName.mouseout(function() {
        // hack
        $(this).data('flag', '0');
        sppInputStop(this, sppInputNamePlace);
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder="Name" data-typewriter="Insert the Name" type="text" id="spp-input-name" name="name" required>

于 2018-01-11T08:45:54.977 回答
0

在 Firefox 中mouseovermouseout多次触发。事实上,很多事情都可能导致他们重新开火。在这里更改占位符属性可以做到这一点,可能是因为 FX 在更改视觉内容后重新计算布局。您尚未发现的其他浏览器中可能存在类似问题。

您不能依赖mouseover并且mouseout(或实际上任何位置事件)只触发一次来启动效果并再次停止它。

而是将其设为输入状态并切换标志:

$(function() {

    var sppInput,
        sppInputName = $('#spp-input-name'),
        sppInputNamePlace = sppInputName.attr('placeholder'),
        inputAnimating = false;

    // Typewriter Effect
    function sppInputStart(elm, n, text) {
        if(!inputAnimating) {
            setTimeout(function () {
                sppInputStart(elm, n, text);
            }, 500);
            return;
        }
        
        if (n < (text.length)) {
            $(elm).attr('placeholder', text.substring(0, n + 1));
            n++;
            sppInput = setTimeout(function () {
                sppInputStart(elm, n, text);
            }, 80);
        }
    }
    function sppInputStop(elm, place) {
        clearTimeout(sppInput);
        $(elm).attr('placeholder', place);
    }

    // Typewriter Effect for Name
    sppInputName.mouseover(function () {
        inputAnimating = true;
    });
    sppInputName.mouseout(function () {
        inputAnimating = false;
    });
    
    sppInputStart(sppInputName, 0, sppInputName.data('typewriter'));

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder="Name" data-typewriter="Insert the Name" type="text" id="spp-input-name" name="name" required>

这适用于 FX。

但是,请考虑使用requestAnimationFrame或使用属性以外的其他东西placeholder,因为这可能会导致丢帧,尤其是在移动设备上。

您也可能会导致 A11Y 问题,因为屏幕阅读器将无法读取您每 80 毫秒更改的属性。

于 2018-01-11T08:43:49.530 回答