PDA

View Full Version : setTimeout to detect changes in a text field



Rain Lover
11-27-2012, 07:27 PM
I wonder why the following sample code doesn't work properly:


<!DOCTYPE html>
<html>

<head>
<title></title>
<style type="text/css">
textarea, iframe {
display:block;
width:300px;
height:100px;
margin:3px;
padding:3px;
border:1px solid #CCC;
}
</style>
</head>

<body>
<textarea id="field" onfocus="getFocus();" onblur="loseFocus();">This is some text.</textarea>
<iframe name="target"></iframe>
<script>
var textarea = document.getElementById('field');
var iframe = window.target.document;

function displayResult() {
if (textarea.value) {
iframe.open();
iframe.write(textarea.value);
iframe.close();
}
window.setTimeout(displayResult, 10);
}

function getFocus() {
if (textarea.value == textarea.defaultValue) {
textarea.value = '';
}
}

function loseFocus() {
if (textarea.value == '') {
textarea.value = textarea.defaultValue;
}
}
displayResult();
</script>
</body>

</html>

Demo: http://jsfiddle.net/RainLover/4ksMR/

The iframe content is supposed to get updated in real time -- as soon as the textarea content changes by keyboard or mouse. This approach is an alternative to the oninput event. But since oninput isn't well-supported across different browsers I decided to create a timer to compare the current text field value with its value in 10 milliseconds before.

keyboard
11-27-2012, 09:12 PM
When I type, it prints it to the iframe.
When I click away, if the textbox is empty it prints the default to the iframe.

It seems to work fine... What exactly is the problem?

Rain Lover
11-28-2012, 09:05 AM
When I type, it prints it to the iframe.
When I click away, if the textbox is empty it prints the default to the iframe.

It seems to work fine... What exactly is the problem?

Just updated my question for clarification.
Note: It should work as soon as the textarea content changes, not after you make changes and click away.

bernie1227
11-28-2012, 09:10 AM
Note: It should work as soon as the textarea content changes, not after you make changes and click away.

It does change as soon as the content changes. Are you referring to the last letter which doesn't go away until you click?
if so:
add the highlighted part to the code:


function displayResult() {
if (textarea.value) {
iframe.open();
iframe.write(textarea.value);
iframe.close();
}
if (textarea.value == '') {
iframe.open();
iframe.write('');
iframe.close();
}
window.setTimeout(displayResult, 10);
}

Rain Lover
11-28-2012, 09:28 AM
It does change as soon as the content changes. Are you referring to the last letter which doesn't go away until you click?


There's a problem with my approach that I don't know how to resolve: the iframe content gets updated every 10ms while I'd like it to refresh only if the current text field value is different from its value in 10 milliseconds before. Something like this:


function displayResult() {
if (textarea.value != textarea.value.10ms.ago) {
iframe.open();
iframe.write(textarea.value);
iframe.close();
}
window.setTimeout(displayResult, 10);
}

bernie1227
11-28-2012, 09:38 AM
Alright, this does what you want:


<textarea id="field" onfocus="getFocus();" onblur="loseFocus();">This is some text.</textarea>
<iframe name="target"></iframe>
<script>
var beforeText = '';
var textarea = document.getElementById('field');
var iframe = window.target.document;

function displayResult() {
if (textarea.value && textarea.value != beforeText) {
iframe.open();
iframe.write(textarea.value);
iframe.close();
beforeText = textarea.value;
alert(beforeText);
}
window.setTimeout(displayResult, 10);
}

function getFocus() {
if (textarea.value == textarea.defaultValue) {
textarea.value = '';
}
}

function loseFocus() {
if (textarea.value == '') {
textarea.value = textarea.defaultValue;
}
}
displayResult();
</script>​

this jsfiddle (http://jsfiddle.net/) demonstrates it by alerting when the function is called. Rather than changing every 10ms, it runs only if it has been updated.

Rain Lover
11-28-2012, 09:46 AM
Alright, this does what you want:


<textarea id="field" onfocus="getFocus();" onblur="loseFocus();">This is some text.</textarea>
<iframe name="target"></iframe>
<script>
var beforeText = '';
var textarea = document.getElementById('field');
var iframe = window.target.document;

function displayResult() {
if (textarea.value && textarea.value != beforeText) {
iframe.open();
iframe.write(textarea.value);
iframe.close();
beforeText = textarea.value;
alert(beforeText);
}
window.setTimeout(displayResult, 10);
}

function getFocus() {
if (textarea.value == textarea.defaultValue) {
textarea.value = '';
}
}

function loseFocus() {
if (textarea.value == '') {
textarea.value = textarea.defaultValue;
}
}
displayResult();
</script>​

this jsfiddle (http://jsfiddle.net/) demonstrates it by alerting when the function is called. Rather than changing every 10ms, it runs only if it has been updated.

Perfect! Thanks! :)