文本输入中的打字机效果在Firefox中不起作用

时间:2018-01-10 09:38:05

标签: javascript jquery html settimeout cleartimeout

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



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

});
&#13;
<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>
&#13;
&#13;
&#13;

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

为什么?

2 个答案:

答案 0 :(得分:1)

Looks like changing the placeholder value retriggers mouseover event

a "hack" that works:

$(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>

答案 1 :(得分:0)

In Firefox mouseover and mouseout fire multiple times. In fact a number of things can cause them to refire. Here changing the placeholder property does it, probably because FX is recalculating the layout after it changes something visual. There are likely to be similar issues in other browsers that you haven't found yet.

You can't rely on mouseover and mouseout (or indeed any position events) only firing once to start your effect and once again to stop it.

Instead make this a state of the input and toggle a flag:

$(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>

This works in FX.

However, consider using requestAnimationFrame or using something other than the placeholder property, as this is likely to cause dropped frames, especially on mobile.

You may also cause A11Y issues, as screen readers will have trouble reading a property that you're changing ever 80ms.