Reputation: 93
This code produces a typewriter animation effect in the input when a user hovers over it, it animates the placeholder text. When a user moves away, I want the animation to stop and the input to go back to its original state.
$(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>
This code works with all browsers (including IE), but NOT firefox.
Why?
Upvotes: 1
Views: 726
Reputation: 155692
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.
Upvotes: 0
Reputation: 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>
Upvotes: 1