The issue is because you're only using a single setTimeout()
reference. As soon as you hover over the next word the previous timeout is cleared.
To fix this you need to use multiple timeouts, one per word. You can place them in to the data()
of the element to retain a reference to them:
(function(count) {
'use strict';
(function wrap(el) {
$(el).filter(':not(script)').contents().each(function() {
// Node.* won't work in IE < 9, use `1`
if (this.nodeType === Node.ELEMENT_NODE) {
wrap(this);
// and `3` respectively
} else if (this.nodeType === Node.TEXT_NODE && !this.nodeValue.match(/^s+$/)) {
$(this).replaceWith($.map(this.nodeValue.split(/(S+)/), function(w) {
return w.match(/^s*$/) ? document.createTextNode(w) : $('<span>', {
id: count = count + 1,
text: w
}).get();
}));
}
});
}('body'));
}(0));
$('span').hover(function() {
let $self = $(this).addClass('hovered');
clearTimeout($self.data('timeout'));
}, function() {
var $self = $(this);
$self.data('timeout', setTimeout(function() {
$self.removeClass('hovered');
}, 1000));
});
p {
font-size: 26px;
}
.hovered {
filter: blur(3px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div>
<p>hello my name is rose how are you </p>
</div>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…