打印

HF3006: Chrome Safari Opera 中 INPUT、TEXTAREA 元素的 disabled 属性值为 true 时其前景颜色会发生变化,但在 Chrome Safari 中某些情况下 disabled 属性值由 true 转为 false 后,其前景颜色不会更新至最初的设定色

作者:陆远

标准参考

W3C HTML4.01 规范关于失效的控件(Disabled controls)的描述中对 disabled 属性进行了详细介绍:被设置 disabled 属性的表单控件将不再允许用户输入。而 disabled 属性使一个元素出现如下特征:

被设置了 disabled 后的渲染由用户端决定,如将元素 "置灰" 。

关于 disabled 属性 的详细信息,请参考 HTML4 规范 17.12.1 中的内容。

问题描述

各浏览器对于 INPUT、TEXTAREA 元素设置了 disabled 之后的效果处理不尽相同。IE 中会为文字设置一个阴影;Firefox 则保持文字前景色不变;Chrome Safari 会根据元素的背景色自动调整一个前景色;Opera 会将前景色变为 '#6D6D6D'。
但是在 Chrome Safari 中 disabled 属性由 true 转为 false 后,其前景颜色不会更新至最初的设定色,需要使元素重新获得焦点后浏览器才会对前景色进行更新。

造成的影响

Chrome Safari 中的这个现象可能造成被设置 disabled 的 INPUT、TEXTAREA 元素在使其重新可用后,其被浏览器自动调整的前景色不会更新为最初的设定颜色。

受影响的浏览器

Chrome Safari  

问题分析

W3C 规范中没有明确说明在表单元素设置了 disabled 之后该如何渲染 "失效" 的元素,所以各浏览器之间出现了差异。

首先看看各浏览器对于 "失效" 的 INPUT 元素的渲染差异。

请看以下代码:disabled_input.html

<style> * { font:12px/1 Arial; } input { width:12px; height:12px; padding:0; margin:0; border:0
                none; color:#aaa; float:left; outline:none;} </style> <div style="width:192px;
                overflow:hidden;"> <script> for (var i = 255; i >= 0; i--) { document.write('<input
                type="text" value="W" style="background:rgb(' + i + ',' + i + ',' + i +
                ');" disabled />'); } </script> </div>

代码中创建了 16x16 共 256 个 INPUT 元素,其背景色分别为由白至黑共 256 级灰度颜色。所有的 INPUT 元素设置为 disabled。

这段代码在各浏览器中运行效果为:

IE6 IE7 IE8 Firefox Chrome Safari Opera
IE6 IE7 IE8 MDN Chrome Safari Opera
  • IE6 IE7 IE8 中,INPUT 元素内的文字颜色并没有变化,仍然为 "#AAA",但其下方出现了白色阴影用于区分前景色和背景色;
  • Firefox 中,INPUT 元素内的文字颜色也没有变化,仍然为 "#AAA",所以当前景色与背景色比较靠近时,几乎无法看清楚文字;
  • Chrome Safari 中,浏览器根据 INPUT 元素的背景色自动调整 "失效" 的前景色(调整的计算方法参见本文最后一段),调整后的前景色均为灰度系颜色,这使得当前景色与背景色比较靠近时,仍然可以看到文字内容;
  • Opera 中,INPUT 元素的前景色变为了 "#6D6D6D",但仍然存在前景色与背景色混淆无法识别的情况。

下面继续分析当通过脚本将 INPUT 元素的 disabled 属性重新设置为 false 使其 "可用" 后各浏览器之间的差异。

分析以下代码:disabled_input_and_textarea.html

<style> * { font:12px/1 Arial; } input.i, textarea.t { width:12px; height:12px; padding:0;
                margin:0; border:0 none; color:#aaa; float:left; overflow:hidden; resize:none; outline:none;}
                </style> <select id="aaa"><option>11</option></select><input
                id="" type="text" value="W"
                style="color:#aaa;background:#eaeaea" disabled /> <div style="width:192px;
                overflow:hidden; margin-bottom:5px;"> <script> function enableInput(dis) { for (var i =
                255; i >= 0; i--) { document.getElementById('i' + i).disabled = dis; } } for (var i = 255; i >= 0;
                i--) { document.write('<input id="i' + i + '" class="i" type="text"
                value="W" style="background:rgb(' + i + ',' + i + ',' + i + ');" disabled />'); }
                </script> <div style="float:left; width:100%; height:20px; line-height:1.2;">
                INPUT: <input type="checkbox" id="i"
                onclick="enableInput(this.checked);" checked /><label
                for="i">disabled</label> </div> </div> <div style="width:192px;
                overflow:hidden;"> <script> function enableTextarea(dis) { for (var i = 255; i >= 0;
                i--) { document.getElementById('t' + i).disabled = dis; } } for (var i = 255; i >= 0; i--) {
                document.write('<textarea id="t' + i + '" class="t" type="text"
                style="background:rgb(' + (255 - parseInt(i / 2)) + ',' + (255 - i * 2) + ',' + (128 + parseInt(i /
                2)) + ');" disabled>W</textarea>'); } </script> <div style="float:left;
                width:100%; height:20px; line-height:1.2;"> TEXTAREA: <input type="checkbox"
                id="t" onclick="enableTextarea(this.checked);" checked /><label
                for="t">disabled</label> </div> </div>

上面代码总体结构与之前的相同,新增了对 TEXTAREA 元素的测试。点击 disabled 复选框可以设置 disabled 属性的值。

取消选中 disabled 复选框后,各浏览器中效果如下:

IE6 IE7 IE8 Firefox Opera Chrome Safari
IE6 IE7 IE8 Firefox
                    Opera Chrome Safari

从截图中可以很清楚的看到 Chrome Safari 中对于初始状态下设置了 disabled 的 INPUT 及 TEXTAREA 元素,在通过脚本使其 disabled 属性为 false 变为 "可用" 后,其因为 disabled 状态而改变的文字前景色无法随即更新回原始设定的颜色。

这时候若使 INPUT、TEXTAREA 元素获得焦点,则前景色会更新:
update fore


下面分析在何种情况下 Chrome 和 Safari 中 disabled 的 INPUT、TEXTAREA 元素恢复 "可用" 后其前景色不会更新:

分析以下代码:input_disabling.html

<html> <head> <style> table { font:12px Arial; border-collapse:collapse; } table td,
                table th { border:1px solid #999; } th { background:#ddd; } input { width:100px; color:#aaa;
                background:#eaeaea; } </style> </head> <body> <table> <tr>
                <th>&nbsp;</th> <th>createElement</th> <th>cloneNode</th>
                <th>innerHTML</th> <th>document.write</th> <th>页面</th> </tr>
                <tr> <th>初始 disabled</th> <td id="a1"></td> <td
                id="c1"></td> <td id="i1"></td> <td id="r1">
                <script> document.write('<input id="r1i" type="text" disabled
                value="W" />'); </script> </td> <td id="d1"><input
                id="d1i" type="text" disabled value="W" /></td> </tr>
                <tr> <th>后设置 disabled</th> <td id="a2"></td> <td
                id="c2"></td> <td id="i2"></td> <td id="r2">
                <script> document.write('<input id="r2i" type="text" value="W"
                />'); </script> </td> <td id="d2"><input id="d2i"
                type="text" value="W" /></td> </tr> <tr> <th
                colspan="6">disabled 之后恢复 "可用" </th> </tr> <tr> <th>初始
                disabled</th> <td id="a3"></td> <td id="c3"></td>
                <td id="i3"></td> <td id="r3"> <script>
                document.write('<input id="r3i" type="text" disabled value="W" />');
                </script> </td> <td id="d3"><input id="d3i"
                type="text" disabled value="W" /></td> </tr> <tr> <th>后设置
                disabled</th> <td id="a4"></td> <td id="c4"></td>
                <td id="i4"></td> <td id="r4"> <script>
                document.write('<input id="r4i" type="text" value="W" />');
                </script> </td> <td id="d4"><input id="d4i"
                type="text" value="W" /></td> </tr> </table> <script>
                function $(id) { return document.getElementById(id); } //--------------------------------------- var
                input = document.createElement('input'); input.type = 'text'; input.value = 'W'; input.disabled = true;
                $('a1').appendChild(input); $('i1').innerHTML = '<input id="i1i" type="text"
                disabled value="W" />'; var input_copy = input.cloneNode(true); input_copy.disabled = true;
                $('c1').appendChild(input_copy); //---------------------------------------- var input2 =
                document.createElement('input'); input2.type = 'text'; input2.value = 'W'; $('a2').appendChild(input2);
                input2.disabled = true; $('i2').innerHTML = '<input id="i2i" type="text"
                value="W" />'; $('i2i').disabled = true; $('r2i').disabled = true; var input2_copy =
                input2.cloneNode(true); $('c2').appendChild(input2_copy); input2_copy.disabled = true; $('d2i').disabled
                = true; //--------------------------------------- var input3 = document.createElement('input');
                input3.type = 'text'; input3.value = 'W'; input3.disabled = true; $('a3').appendChild(input3);
                input3.disabled = false; $('i3').innerHTML = '<input id="i3i" type="text"
                disabled value="W" />'; $('i3i').disabled = false; $('r3i').disabled = false; var
                input_copy3 = input3.cloneNode(true); input_copy3.disabled = true; $('c3').appendChild(input_copy3);
                input_copy3.disabled = false; $('d3i').disabled = false; //---------------------------------------- var
                input4 = document.createElement('input'); input4.type = 'text'; input4.value = 'W';
                $('a4').appendChild(input4); input4.disabled = true; input4.disabled = false; $('i4').innerHTML =
                '<input id="i4i" type="text" value="W" />'; $('i4i').disabled =
                true; $('i4i').disabled = false; $('r4i').disabled = true; $('r4i').disabled = false; var input4_copy =
                input4.cloneNode(true); $('c4').appendChild(input4_copy); input4_copy.disabled = true;
                input4_copy.disabled = false; $('d4i').disabled = true; $('d4i').disabled = false; </script>
                </body> </html>

这段代码在 Chrome Safari 中运行效果如下:
update

可见对于通过 createElement、cloneNode 这类标准 DOM 方式创建并插入的 INPUT 元素,在 Chrome Safari 中不存在任何问题。

而通过诸如 innerHTML、document.write 还有页面原始加载时存在于 HTML 文档代码中的 INPUT 元素,在 disabled 前后均不会更新前景色。


解决方案

避免为 INPUT、TEXTAREA 元素设置比较深的背景色,或者在需要使一个文本框在 "disabled=true" 及 "disabled=false" 之间切换时,尽量通过标准的 DOM 方式创建此元素。

或者在设置 "disabled=false" 之后迫使文本框获得焦点,但应注意恢复之前获得焦点的元素。如:

<input type="text" id="a" /> <input type="text" id="i"
                value="www" disabled style="color:#aaa; background:#eaeaea;" /> <script>
                function $(id) { return document.getElementById(id); } var a = $('a'); var i = $('i'); a.focus(); var f
                = document.activeElement; i.disabled = false; i.focus(); f.focus(); </script>

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.8
Chrome 6.0.472.11 dev
Safari 5.0
Opera 10.60
测试页面: disabled_input_and_textarea.html
input_disabling.html
disabled_sol.html
本文更新时间: 2010-08-02

关键字

INPUT TEXTAREA disabled color 更新 失效 颜色