1

Consider this Example.

The essential bit is the JavaScript:

function encodeInput(editor) {
    theText = editor.val();
    theText = theText.replace(/\*\*\*(.*?)\*\*\*/, '<strong><i>$1</i></strong>', 'g');
    theText = theText.replace(/\*\*(.*?)\*\*/, '<strong>$1</strong>', 'g');
    theText = theText.replace(/\*(.*?)\*/, '<i>$1</i>', 'g');
    console.log(theText);
    $('#preview').html(theText);
}

$(function() {
    $editor = $('#editor');
    $editor.keyup(function() {
        encodeInput($(this));
    });
});

Tested and works great (I do need the \*\*\* part or it doesn't work).
Anyways, on to the main course

The Problem

Because I'm using keyup, the script is not very responsive (eg. it only "runs" once the user had let go of the key). I want it to behave more like the editor here on StackOverflow, where the key is pressed and response occurs immidiately.

I tried using keydown and keypress but it seems as if the val() attribute is not updated when it runs, so I can't really know the updated value.

In Short

How can I make it more responsive, so that when the user pressed a key, the preview is automatically updated??

Community
  • 1
  • 1
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • Two suggestions: Use `` instead of `` and if you want to add proper markdown support, consider porting markdown-python to JavaScript instead of using regexes. Its approach with plugins, a parse tree, etc is really nice and much cleaner IMO. – ThiefMaster Oct 20 '11 at 13:56
  • @downvoter can you please explain the -1? – Madara's Ghost Oct 20 '11 at 20:55

3 Answers3

2

You can use the HTML5 input event in most browsers and the propertychange event in IE < 9. These events fire immediately after the textarea's value is updated.

Here's an updated demo using these events:

http://jsfiddle.net/muWm2/1/

I've written about this in a few places on SO. Here are two of them:

I would recommend against updating the preview on every single change to the textarea's value because it could quickly get unresponsive, which is a big no-no for user experience. I'd suggest "debouncing" the event, in this case waiting for a period of user inactivity (say half a second) before updating the preview. Here's an answer and a link that may help:

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
0

You can bind() both the keyup and keydown events:

$editor.bind('keyup keydown', function() {
    encodeInput($(this));
});

I noticed that only the first occurrence was working, adding the g flag to the regex seemed to help, and for the purpose of the jsfiddle demo only, unchecking "normalize css" made the bold text appear.

http://jsfiddle.net/tuUym/3/

Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
  • Still the same problem. Does not work until the key is released. – Madara's Ghost Oct 16 '11 at 10:04
  • Works fine for me in Chrome, whereas it did not before. Unfortunately I can't test any other browser at the moment, my laptop crashed and I'm on the gf's computer. BTW might want to add `word-wrap:break-word;` to the preview pane. – Wesley Murch Oct 16 '11 at 10:09
  • I'm using chrome as well, and it doesn't work as intended for me. – Madara's Ghost Oct 16 '11 at 10:11
  • I'd be surprised if we're not seeing the same thing, maybe testing it differently or I misunderstood the question. What exactly isn't working? How can I reproduce it? I'm not seeing "Does not work until the key is released", it works on my end (for example, if I hold `s` I see `sssssssss` in both panes, and it updates as I type including the formatting). I'm off to bed, best of luck. – Wesley Murch Oct 16 '11 at 10:14
  • Hmm, I do notice a little lag now (especially on the first character, not very noticeable when actually typing) - but this still seems to be an improvement. Hope you get a better answer. – Wesley Murch Oct 16 '11 at 10:27
  • Try holding the key down for about a second, you'll see the larger lag I'm talking about. – Madara's Ghost Oct 16 '11 at 10:28
0

Keypress fires when the key is pressed continously, so you have to bind it to keypress in order to see the result. And thats it.

http://jsfiddle.net/tuUym/4/

UPDATE: I see what you mean. Maybe you need an input poller? Check out the de obfuscated wmd code. That will help you achieve the lagless editor you aim for:

WMD Download

Jauzsika
  • 3,171
  • 3
  • 23
  • 32
  • Try pressing backspace, it does not seem to update deleted characters. – Wesley Murch Oct 16 '11 at 10:12
  • Read the question and test your own code, binding keypress causes the `val()` not to be updated (meaning I write L-o-r-e-m and see L-o-r-e). I only see the last character if I press on another key (like shift or ctrl). – Madara's Ghost Oct 16 '11 at 10:13