有哪些经常被误用的HTML、JavaScript、CSS 的元素、方法和属性?
以前想要把一个元素(input 之类的)设成只读的时候都是用 disabled,后来发现这是不对的。 因为在 HTML 里面,如果一个元素被设置成 disabled, 那么它的值就不会被发送到 server 端。 正确的做法应该是使用 readonly。
那么除了这个 disabled,在 Web 开发中还有哪些东西是经常被误用的?
回复内容:
仅说一下 CSS 方面的吧。
float:left/right 或者 position: absolute 后还写上 display:block,画蛇添足(三者关系:Visual formatting model)
不分场景的使用 overflow:hidden 来闭合浮动(详见:那些年我们一起清除过的浮动)
为了让 Chrome 这个脑残支持小于12px 的文字,在 html 设置 -webkit-text-size-adjust:none; (最新的桌面版该属性已经被删除了,变更集:Changeset 145168)
认为 px 是一个绝对单位(px 是相对单位),整个页面都是 px,line-height 也用 px,全家都是 px
习惯性不分场景的去除 a 标签 focus 时候的焦点
认为布局就是 Float,所有的地方都是 Float,全家都是 Float!(试试 inline-block inline-block 前世今生 吧,试试 Flexbox 吧)
满页面都是用 .clearfix 来闭合浮动,如果已经有了BFC为嘛还要在闭合浮动呢?毒害不浅,某浪微博为例,102个 .clearfix
好吧我还是说点其他的吧:
搞不拎清 PNG 的分类,认为 PNG24 支持透明,不知道 PNG8 也支持 α 透明(可以看看:PNG的秘密)
我又要吐槽 Label 不加 for ,或者 for 属性加的不对的问题(请看:雅安地震,前端开发者可以做什么?)
看到@贺师俊老湿说道 ul,ol 滥用的问题,我举一个本来应该用 ol 却写成 ul 的例子:
首页 | 微吧 一起扎堆吧!找反面教材,都去渣浪吧,渣浪你承认不?
查看源码,满屏都是 div 的就不多说了吧……
好吧,我已经原谅你们了,或许你遇到了学习瓶颈:
【Update】
写了 xhtml 的 doctype,但是文档连 well-formed 都没做到。比如渣浪微博。腾讯原来也是,不过最近似乎改好了。
【/Update】
几乎每个 HTML 标签都可能被用错,TABLE布局这种我就不说了,下面挑在各互联网大站屡见不鲜的说:
元素方面
1. 滥用 UL、DL
2. 该用 OL 的用 UL
3. 段落不会用 P 只会用 BR 和 DIV
4. 不会用 H1 / H2 / H3 ... 只会用 STRONG 甚至 DIV
5. 不会用 LABEL、FIELDSET、LEGEND
6. 乱用 ABBR、CITE、Q 之类比较少见的标签
7. 不会用或乱用 B / I / S / U 之类在 HTML5 中重新定义过的标签
属性方面
1. 多 class 症(病入膏肓的表现就是几乎每个元素上都有不止一个 class)
2. IMG 的 alt 属性没有意义(比如和title属性一样)
3. 混淆 INPUT 的 disabled 属性和 readonly 属性
4. LABEL 元素的 for 属性
5. 不会使用 lang 属性或 lang 属性写成 zh-CN 等已经废弃的用法
没人谈谈JS?呃,我今天又听到一种奇怪的说法,所以打算写几句。下面谈到的几点,可以说都是因太过「想当然」,想当然以为如此,却并没有去验证,错误的写法就这样一直流传着。
if(value) 与 if (!!value) 语义上没有任何区别。我反对if (!!value)的写法。 同样无聊的写法还有:if ((var1 == var2) == true)。 if 接受“A condition expression that evaluates to true or false”,并非必须PrimitiveBool类型。 在《ECMAScript Spec》中,if (value)的语义相当于:IF (ToBoolean(value))。 而Logical Not的语义相当于:not ToBoolean(value)。 即 !!val 相当于 ToBoolean(value)。 也就是说:if (!!value)的语义相当于 IF (ToBoolean(ToBoolean(value)))。 如果你认为这种写法是合理的,那你为什么不继续写道: if (!!(!!value))、 if (!!(!!(!!value))) ……?
什么时候需要使用Logical Not “!” 转换类型呢?一般函数传参或返回值有这个必要。如果函数文档中说它返回一个Bool类型的值,那么函数作者就有责任保证其返回值的类型为(Primitive)Bool。因为函数的使用者可能会写出依赖返回值类型的代码:
/**@returns Bool*/function has(str,substr) { return !!~str.indexOf(substr); //return ~str.indexOf(substr); // wrong!!!}//函数使用者的代码:JSON.stringify({ //此选项值类型早约定为Enum(0|1) xxxOptionOnOff:+has(s,"xxx") //使用者依赖于Bool to Number的转换});
同作向函数传参也需要注意类型:
/**@param {Bool} flag*/function toggle(flag) { //期望设置className为 toggle-on-true 或toggle-on-false //尽管不推荐这种过于依赖Bool参数类型的代码,但既然文档声明是Bool类型 //传参者就有必要保证参数类型正确,即使是JS这种弱类型语言 ele.className= "toggle-on-"+flag;}toggle(!!btn.checked);//toggle(btn.checked); //wrong! btn.checked可能返回String "checked"
第二个,吃力不讨好的人肉GC:
有人喜欢在遇到闭包时人肉GC:
function foo() { var obj={/*May be a big object*/}; return function () { //返回闭包中实际上没用到obj这个变量 //没有用到的变量解释器本可作优化、不去捕获 //但有人担心obj无法被GC,于是硬生生地... obj=null; // 于是解释器反而要将obj捕获了,笑~ return; };}//还有人以为这样写就蛮好:function bar() { var obj={/*May be a big object*/}; //...lots of code obj=null;//那你以为它就*立即*被GC了吗?没有,同样画蛇添足。 // 不过不排除有浏览器没有实现这种优化 return function () {/*闭包中反正用不到obj*/};}
第三个,效率系列,现在应该很少有人犯这些错误了:
以为 && 、 || 比 if 效率高。
以为 while (i) 比 while(i>0) 效率高。
以为 eval 永远效率非常低。
这点已经有这篇文章讨论过:由eval生成的代码效率真的很差吗?
前置、后置的++、--系列的效率差别早在C语言中就被批的体无完肤了。
以为array[i]总比object[p]快,以致错误地使用了Sparse Array。
...想起了真正毁掉一切Array类型推导的:Array.prototype[9]="KAKA";
以为 …… 反正全都是以为怎么样怎么样。
第四个, `n|0`、`n^0`来取整不是始终OK的,Bitwise Operators先对Operand进行ToInt32,JS中的Number是双精度64位浮点数、不止Int32。Math.pow(2,32)|0 得 0。
想想JS的常见错误确实不好找啊,每天修的Bug太多了,我能记得的Error肯定都是因为它不常见才记得它的啊。HTML、CSS写错了浏览器有时一声不吭,JS写错了就是写错了啊,错误留在那里迟早要见棺材的。
第五个,和jQuery有关的,你的代码中一般不应该出现element.unbind('event')这种Bug prone代码。这个调用是解除该事件所有监听函数,但仔细想一想,除非这个元素准备destroy掉了,这种代码一般是不应该出现的。如果该event所有监听函数都是自己绑定的,那你就应该知道当前Scene该unbind哪些listeners,很难想象绑定上去的listeners会多到超出管理能力unbind时懒得列举的情形;如果该元素是公共元素,其上会有其它代码bind上去监听函数,那这样写会导致或隐藏错误。而且重要的是,它通常是一个Bad Design信号,尤其当bind与unbind同时出现时。如果该元素/该场景没有准备destroy,这通常意味着我还会重复bind监听函数。如:
editor.on("show",function () { submitButton.bind("click",function () { alert("Submit!"); //然后发现editor隐藏再show一次,就会alert执行两次 });});editor.trigger("show");//触发一次show事件就会重复绑定一次代码 //为了FIX上面的问题,于是……editor.on("show",function () { submitButton.unbind("click").bind("click",function () { alert("Submit!"); });});
没错,是Fix了Bug,但是,有没有更好的设计方式呢?有个原则是,绑定事件要趁早,根据不同的情况试举例说明,多出的unbind很可能是错误设计的信号:
//最低级的错误是,其实submitButton的行为不会受到editor状态的影响, 它俩压根没关系submitButton.bind("click",submitAction); //根本不需要等到show时再绑定editor.on("show",showAction); //另一种情况是,editor show时submitButton enable,hide时d isablefunction submitAction() {/*……*/}function enableSubmit() { submitButton.bind("click",submitAction);} function disableSubmit() {submitButton.unbind("click",submitAction);} editor.on("show",enableSubmit);editor.on("hide",disableSubmit); //那你一定忘记其实应在hide状态将其unbind
因为,bind与unbind本应在相反状态的两个Action中出现,如show与hide、enable与disable、on与off;如果不是,通常意味着bind事件与两个状态无关,既然与这些状态无关,为什么还要等状态触发再绑定呢? 若你发现会bind两次就意味着该状态会进入两次,既然会进入两次,就意味着该状态会退出,既然与状态有关,则应在一「进入」状态绑定,在另一「退出」状态解除,bind与unbind应始终保持这种对称关系,才有利于listeners的维护,避免Bug。而当你将bind与unbind分开时,你就会发现自己不会再写出 element.unbind('event') 这样草率的代码。
第六个, +new Date 和 0 + new Date 是不一样的,当然我觉得这类坑都是JS设计上的错误,加法不符合交换律也就罢了,还非要将 Date类型特殊处理。
第七个,在Prototype上放一个NonPrimtive值(Object)作为Instance属性:
Editor.prototype={ width:300, //default width 300 px toolbarItems:["File","Edit","Help"], //default toolbar items //…… addToolbarItem:function (item) { this.toolbarItems.push(item); //Bug! }};
好像我说的都是语法,都不是属性方法之类的啊。反正先写这么多,以后想起来再补充。
以上就是有哪些经常被误用的HTML、JavaScript、CSS 的元素、方法和属性?的内容,更多相关内容请关注PHP中文网(www.php.cn)!
下一篇: Oracle递归查询的原理