>  기사  >  웹 프론트엔드  >  有哪些经常被误用的HTML、JavaScript、CSS 的元素、方法和属性?

有哪些经常被误用的HTML、JavaScript、CSS 的元素、方法和属性?

PHP中文网
PHP中文网원래의
2017-04-01 16:27:031263검색

有哪些经常被误用的 HTML、JavaScript、CSS 的元素、方法和属性

以前想要把一个元素(input 之类的)设成只读的时候都是用 disabled,后来发现这是不对的。 因为在 HTML 里面,如果一个元素被设置成 disabled, 那么它的值就不会被发送到 server 端。 正确的做法应该是使用 readonly。

那么除了这个 disabled,在 Web 开发中还有哪些东西是经常被误用的?

回复内容:

仅说一下 CSS 方面的吧。

float:left/right 或者 position: absolute 后还写上 display:block,画蛇添足(三者关系:Visual formatting model)

1396.jpg

不分场景的使用 overflow:hidden 来闭合浮动(详见:那些年我们一起清除过的浮动)

1397.jpg

为了让 Chrome 这个脑残支持小于12px 的文字,在 html 设置 -webkit-text-size-adjust:none; (最新的桌面版该属性已经被删除了,变更集:Changeset 145168)

认为 px 是一个绝对单位(px 是相对单位),整个页面都是 px,line-height 也用 px,全家都是 px

1398.jpg

习惯性不分场景的去除 a 标签 focus 时候的焦点

认为布局就是 Float,所有的地方都是 Float,全家都是 Float!(试试 inline-block inline-block 前世今生 吧,试试 Flexbox 吧)

满页面都是用 .clearfix 来闭合浮动,如果已经有了BFC为嘛还要在闭合浮动呢?毒害不浅,某浪微博为例,102个 .clearfix

1399.jpg

好吧我还是说点其他的吧:

搞不拎清 PNG 的分类,认为 PNG24 支持透明,不知道 PNG8 也支持 α 透明(可以看看:PNG的秘密)

我又要吐槽 Label 不加 for ,或者 for 属性加的不对的问题(请看:雅安地震,前端开发者可以做什么?)

看到@贺师俊老湿说道 ul,ol 滥用的问题,我举一个本来应该用 ol 却写成 ul 的例子:
首页 | 微吧 一起扎堆吧!找反面教材,都去渣浪吧,渣浪你承认不?

1400.jpg

查看源码,满屏都是 div 的就不多说了吧……

好吧,我已经原谅你们了,或许你遇到了学习瓶颈:

1401.jpg

【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)!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.