1

Back to my framework again. I have a method which gets the element's value, clears the element's value in dom, and then puts it back in letter by letter. Tested it in Chome, FF and IE (10). Everything is working fine. But there's a small problem with IE. It won't clear the element's value if I refresh the page while the script is executing. Or after it, doesn't really make a difference.

<textarea cols="60" id="textarea">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas suscipit lacus non hendrerit cursus.
</textarea>

<script>
(function(){
    (this[arguments[0]] = function selector(id){
        if(!(this instanceof selector)) {
            return new selector(id);
        }
        this.elm = document.getElementById(id);
    }).prototype = {
        type:       function(delay) {
                        var elm = this.elm;
                        var status;
                        if ('value' in elm) {
                                var text = elm.value;
                                elm.value = "";
                                status = 0;
                            } else if ('innerHTML' in elm)  {
                                var text = elm.innerHTML;
                                elm.innerHTML = "";
                                status = 1;
                            }
                        var letters = text.split("");
                        var counter = 0;
                        function write() {
                            if (counter < letters.length) {
                                switch (status) {
                                    case 0: elm.value += letters[counter];      break;
                                    case 1: elm.innerHTML += letters[counter];  break;
                                }
                            }
                            counter += 1;
                        }
                        setInterval(write, delay);
                    },
   };
})('$');

$('textarea').type("100");

FIDDLE

Is this IE related problem or am I missing something in the code? I feel like it's probably IE >.>

akinuri
  • 10,690
  • 10
  • 65
  • 102

1 Answers1

0

I'm pretty sure this is an IE related problem. IE 10 tries to be user-friendly and keeps changed input text in textareas even after a page refresh.

Now here's the problem: Your script already tries to clear the textarea before IE restores the text from the previous page load. Hence your script then adds the new text to the old text.

So a simple workaround would be giving IE a little time to restore the text before starting your typefunction and clearing the textarea. However, you will have to get the textarea's original content before IE overwrites it.

And just something I noticed while looking at your code: Using setInterval for this effect is a bad idea since the function will keep running (and counting) forever even after the complete text has been written to the textarea; you'll have to use clearInterval.

Here's the corrected code (changes are commented). This works for me in FF, IE 10 and Chrome.

(function(){
    (this[arguments[0]] = function selector(id){
        if(!(this instanceof selector)) {
            return new selector(id);
        }
        this.elm = document.getElementById(id);
        this.elm.setAttribute("autocomplete", "off");
    }).prototype = {
        type: function(delay) {
            var elm = this.elm;
            var status;
            // Don't clear textarea here, won't have any effect; but get original textarea content
            if ('value' in elm) {
                var text = elm.value;
                status = 0;
            }
            else if ('innerHTML' in elm)  {
                var text = elm.innerHTML;
                status = 1;
            }
            var letters = text.split("");
            var counter = 0;
            var interval;
            function write() {
                if (counter < letters.length) {
                    switch (status) {
                        case 0: elm.value += letters[counter];      break;
                        case 1: elm.innerHTML += letters[counter];  break;
                    }
                }
                else {
                    // Clear timer
                    clearInterval(interval);
                }
                counter += 1;
            }
            setTimeout(function(){
                // Clear textarea after waiting a little; using 0 as timeout value should be perfect, no need for higher values
                if (status == 0) {
                    elm.value = "";
                }
                else {
                    elm.innerHTML = "";
                }
                interval = setInterval(write, delay);
            }, 0);
        },
    };
})('$');

$('textarea').type("100");
Aletheios
  • 3,960
  • 2
  • 33
  • 46
  • 1
    This code seems like it solves the problem but also creates another one. If I reload the page before it prints the text -say in the middle- after page loads, it won't print the whole text. It stops priting at the point where I loaded the page. This happens in IE and FF. In Chrome it works fine. – akinuri Oct 06 '13 at 14:10
  • 1
    Hmm I didn't test that. ^^ Here's a workaround for FF: Add `this.elm.setAttribute("autocomplete", "off");` at the end of your `selector` class (see [this question](http://stackoverflow.com/questions/4263536/firefox-cache-textarea-value)). However I'm still looking for a solution that also works in IE... – Aletheios Oct 06 '13 at 14:39
  • I've edited my answer to provide a more general solution; it now should work in FF, IE 10 and Chrome. – Aletheios Oct 06 '13 at 15:00