3

So I got a little codepen. Everything works so far except a little thing. I got a <h1> and an <input>. When I type something in the text input, its value should get passed to the <h1> in realtime.
I tried to do that with a keyup function:

$('input[name=titleInput]').keyup(function(){
  $('#title').text(this.value);
});

Something happens, but not what I want.
When I type something in the text input, then delete it (with backspace) and re-enter something, only the first character gets passed to the title.

Try it out on my codepen. Maybe it's just a stupid mistake of mine, but to me this behaviour is pretty weird.
Thanks for your help in advance!

EDIT:
I am using text-fill-color, which may causes the problem.

EDIT 2:
A friend of mine tested it. It worked for her. She's using Chrome and the same version as me (58.0.3029.110 (official build) (64-Bit)).

Alireza
  • 2,319
  • 2
  • 23
  • 35
Tobias Glaus
  • 3,008
  • 3
  • 18
  • 37

2 Answers2

4

Chrome does not update the content correctly. Such kind of bugs can always happen if you use vendor prefixed css properties, so you should avoid those.

You could hide the container before update, and then show it again with a timeout. This will trigger an update, but would also result in flickering.

$('input[name=titleInput]').keyup(function(){
  $('.clipped').hide()
  $('#title').text(this.value);
  setTimeout(function() {
    $('.clipped').show();
  })
});

EDIT An alternative might be to use background-clip on the text and provide the inverted image yourself, but I right now don't have time to test that.

EDIT2 Based on the test of @TobiasGlaus the following code does solve the problem without flickering:

$('input[name=titleInput]').keyup(function(){
  $('.clipped').hide().show(0)
  $('#title').text(this.value);
});

This seems to be different to $('.clipped').hide().show() most likely it starts an animation with duration 0 and uses requestAnimationFrame which also triggers a redraw. To not relay on this jQuery behaviour, the code should be written as:

$('input[name=titleInput]').keyup(function(){

  if( window.requestAnimationFrame ) {
    $('.clipped').hide();
  }

  $('#title').text(this.value);

  if( window.requestAnimationFrame ) {
    window.requestAnimationFrame(function() {
      $('.clipped').show();
    })
  }
});
t.niese
  • 39,256
  • 9
  • 74
  • 101
  • Nice solution! Works perfectly, but as you said it results in flickering. But I think I can live with that. – Tobias Glaus Jun 15 '17 at 13:52
  • @TobiasGlaus you could try to experiment with some other css properties, like slightly toggling the zoom factor or the position using transformations, with a small factor like `0.1` on different elements, probably one of those would also result in a redraw – t.niese Jun 15 '17 at 13:55
  • I tried out something else now. Instead of using a timeout, I just added this `$('.clipped').hide().show(0);` to my initial code. Not flickering anymore. Can you confirm that? (edited my codepen) – Tobias Glaus Jun 15 '17 at 14:06
  • @TobiasGlaus Yes there is not flickering. I wouldn't have expected that. But maybe thats because jQuery starts an animation with a duration `0` that still uses `requestAnimationFrame` internally. – t.niese Jun 15 '17 at 14:11
  • Yeah. (I have to commend Juank for [this solution](https://stackoverflow.com/a/8840703/5883638) tho.) Thanks for your help! – Tobias Glaus Jun 15 '17 at 14:14
  • @TobiasGlaus I would use `requestAnimationFrame` directly. I update my answer accordingly. Just to be sure that an update of jQuery won't break it. – t.niese Jun 15 '17 at 14:19
  • Thanks alot. That's perfect! – Tobias Glaus Jun 15 '17 at 14:26
0

i'd use the following lines:

$('input[name=titleInput]').bind('keypress paste', function() {
   setTimeout(function() {
     var value = $('input[name=titleInput]').val();
     $('#title').text(value);
   }, 0)
});

This will listen to the paste / keypress events, and will update the value on change.

Bamieh
  • 10,358
  • 4
  • 31
  • 52