经验总结:5个应该避免的前端糟糕实践

简介:

这几天在产品的某个模块上上添加新功能,该模块之前是由其他同事维护。也就是说,需要在同事原有代码的基础上进行修改。过程中遇到了一些坑,主要是由一些不合理的代码实践导致的。

这里抛开大的设计话题,仅挑出其中一些自己认为不是很合理的代码细节。原因很简单:当我们在审视别人代码的时候,总会看到这样那样的不合理之处,而等到自己撸起袖子上阵时,其实也很难保证自己不会犯同样的错误。可能是一时偷懒,也可能是赶需求导致的考虑步骤等。

本文代码示例点击下载

糟糕实践一:依赖节点之间的顺序

我们来看下面代码,大家应该对这样的代码非常熟悉了,这也是初学者比较容易犯的一个错误:节点的查询依赖于节点当前所处的位置。下面 

getElementsByTagName('span')[0] 这样的写法存在很大的隐患,很简单,主要节点的顺序一发生变化,就出事了。
复制代码
<h2>不要依赖节点顺序</h2>
<div id="1111">
    <span></span><span>爱好:动漫</span>
</div>

<script type="text/javascript">
    var $ = function(id) {
        return document.getElementById(id);
    }
    $('1111').getElementsByTagName('span')[0].innerHTML = '昵称:程序猿小卡';
</script>
复制代码

比如节点的顺序变成,那就会发生一些意料之外的事情了,第一个span节点之间的“简介:”就被无情地覆盖了。

复制代码
<h2>不要依赖节点顺序</h2>
<div id="222">
    <span>简介:</span>
    <span></span><span>爱好:动漫</span>
</div>
复制代码

解决方案

千万不要用 element.getElementsByTagName(tagName)[index] 这样的方式可以来获取节点,除非你有非这样做不可的理由。

取而代之可以用类似 element.getElementById(id) 来获取,或者采用下文提到的 element.querySelector(selector) 这样的方式~

 

糟糕实践二:依赖标签的排版

 上面我们已经提到说节点查询的时候不要依赖于节点的顺序,原因是节点的顺序是有可能改变的。那么,如果节点顺序没有“发生变化”,那就能够确保平安无事了吗?答案是未必。

且看下面的代码,也是很常见的代码,获得id为“333”的元素的第一个子节点,并将该子节点的color设置为 #ccc。

复制代码
<h2>顺序没变,但脚本错误了</h2>
<div id="333"><span>昵称:程序猿小卡</span><span>爱好:动漫</span></div>

<script type="text/javascript"> $('333').childNodes[0].style.color = '#ccc'; </script>
复制代码

顺序不变也会出事?可能有的同学会有这样的疑惑。好吧,本人稍微有一点排版上的强迫症,看上上面类似的标签排班时,总是忍不住想要去小小调整下,好让标签看上去更清晰些,于是我小小调整了下排版,变成下面这个样子。

复制代码
<h2>顺序没变,但脚本错误了</h2>
<div id="444">
    <span>昵称:程序猿小卡</span>
    <span>爱好:动漫</span>
</div>
<script type="text/javascript">

    $('444').childNodes[0].style.color = '#ccc';

</script>
复制代码

子节点顺序并没有发生改变,只是排版变了,按理来说不会有什么影响吧。好,让我们打开chrome看下,控制台下输出这样的信息:

Uncaught TypeError: Cannot set property 'color' of undefined 

什么原因呢?眼尖的同学可能已经看出来了,childNodes属性可以获得一个节点的所有子节点,而这些子节点里面包含了文本节点,甚至是标签末尾的换行、空格。不难想到,下面的标签同样会导致同样的bug,而这里的标签跟最初的标签,唯一的区别仅在于:第一个span标签前面多了个空格。

这个bug隐蔽指数相当高,很可能放在那里几年都没有人触发。毕竟,有谁会想到,换个行,加个空格都会导致出bug呢,而且在旧版本IE里面,childNodes是将文本节点排除在外的,也就是说,即使你加了换行、排版,在旧版本IE里测试也是完全ok的,巨坑。

<h2>顺序没变,但脚本错误了</h2>
<div id="555"> <span>昵称:程序猿小卡</span><span>爱好:动漫</span>
</div>
<script type="text/javascript">
    $('555').childNodes[0].style.color = '#ccc';
</script>

解决方案

参见糟糕实践一的解决方案

 

 糟糕实践三:依赖特定的节点类型

项目中依赖的基础库是jQuery,jq提供了非常强大的选择器,很常见的就是可以通过节点类型进行选择,比如下面代码。如果你那么写的话,接手你代码的兄弟估计会恨死你。

复制代码
<h2>依赖节点类型</h2>
<div id="666">
    <ul></ul>
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    $('#666 ul').html('<li>昵称:程序猿小卡</li><li>爱好:漫画</li>');
</script>
复制代码

问题很明显,$('#666 ul')选中了id为666的节点下所有节点类型为UL的子节点、孙节点、曾孙节点。。。我就掉这个坑里了,但是需要在上面加多个下拉列表,于是毫不犹豫地采用UL来模拟,大致如下。运行的结果绝对让你抓狂。

复制代码
<h2>依赖节点类型</h2>
<div id="777">
    <ul></ul>
    <ul>
        <li>选项一</li>
        <li>选项二</li>
        <li>选项三</li>
    </ul>
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    $('#777 ul').html('<li>昵称:程序猿小卡</li><li>爱好:漫画</li>');
</script>
复制代码

 解决方案

参见糟糕实践一的解决方案。

 

 糟糕实践四:不合理利用元素选择器声明样式

跟上面的例子其实很类似,还是用上面的标签来说明问题。同事的愿望很朴素,就是希望将ul节点下的文本都设置为红色而已。

复制代码
<style type="text/css">
    ul{
        color: red;
    }
</style>
<h2>依赖节点类型</h2>
<div id="666">
    <ul></ul>
</div>
复制代码

然后,我往里面查了另一个ul元素来模拟下拉列表,悲剧了,原先声明的样式伤及无辜。。

复制代码
<h2>依赖节点类型</h2>
<div id="777">
    <ul></ul>
    <ul>
        <li>选项一</li>
        <li>选项二</li>
        <li>选项三</li>
    </ul>
</div>
复制代码

 解决方案

尽可能地避免通过元素选择器来声明样式(reset css的除外),如果非用不可,那么尽可能地将杀伤范围限制得足够小,如在某个特定的id、class内部用元素选择器,就像下面这样这样。

注意:尽管这样做看上去安全了些,但还是有不小的隐患,千万小心

.restrict_style ul{ color: red; } // 通过外层容器,限制选择器的

 

糟糕实践五:节点查询依赖于样式类名

在一个页面中,id是唯一的,给太多的节点加上id,很容易造成节点id的冲突。常用的推荐解决方案是,给最外层的容器节点加上id,而对于子节点,则加上相应的class,以此达到方便查询、避免冲突的目的。下面这样的代码相信大家不陌生,包括不少开源组件都是这么个思路。

复制代码
<h2>节点查询依赖于类名</h2>
<div id="888">
    <span class="nick">昵称:程序猿小卡</span>
    <span class="hobby">爱好:动漫</span>
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    $('#888 .nick').css('color', 'green');
    $('#888 .hobby').css('color', 'orange');
</script>
复制代码

上面的代码看上去没什么问题,那究竟为什么说它糟糕呢?因为:1、不利于样式重构 2、修改容易导致bug

假设某个晴朗的早晨,产品同学找到你说,这里这里的样式需要改版,你稍微一评估,自信满满地说:没问题,很简单。于是你就开工了,既然是改版,肯定是大动刀了。过了一会,你的眼球突然被<span class="nick"></span>这个标签吸引了:好好的炎黄子孙class名干嘛起得这样洋里洋气的,太装了吧(很不恰当的例子哈,只是为了说明因某些原因需要修改类名)。于是果断将“nick”改成了“nicheng”,多通俗易懂啊。

于是,悲剧了,在本文的例子里,把“nick”改成“nicheng”,只是会导致样式稍微有点不正常,但严重的时候脚本错误都有可能

复制代码
<h2>节点查询依赖于类名</h2>
<div id="999">
    <span class="nicheng">昵称:程序猿小卡</span>
    <span class="aihao">爱好:动漫</span>
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    $('#999 .nick').css('color', 'green');  // 节点取不到了
    $('#999 .hobby').css('color', 'orange');

    $('#999 .nick')[0].innerHTML = '程序猿小卡'; /// 出错了,因为$('#999 .nick')[0]为undefined
</script>
复制代码

解决思路

大家都推崇的开发方式(外层id,内层class),是不是就不要用了呢?当然不是,只不过可以稍微调整下:

1、外层容器用id

2、子节点用class,但class前需要加上“js-”等特殊前缀,标识该样式为js代码里需要用到的。对这样的class不要随便动它,如果需要修改,请先搜索下整个工程目录,确保你的修改不会导致bug。

简单修改下上面的例子,好了,nick、hobby,随你修改了~

复制代码
<h2>节点查询不依赖于样式类名</h2>
<div id="1010">
    <span class="js-nick nick">昵称:程序猿小卡</span>
    <span class="js-hobby aihao">爱好:动漫</span>
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    $('#999 .js-nick').css('color', 'green');  // 节点取不到了
    $('#999 .js-hobby').css('color', 'orange');

    $('#999 .js-nick')[0].innerHTML = '程序猿小卡'; /// 出错了,因为$('#999 .nick')[0]为undefined
</script>
复制代码

 

更多糟糕实践

待补充

相关文章
|
16天前
|
前端开发 编解码 数据格式
浅谈响应式编程在企业级前端应用 UI 开发中的实践
浅谈响应式编程在企业级前端应用 UI 开发中的实践
17 0
浅谈响应式编程在企业级前端应用 UI 开发中的实践
|
3月前
|
前端开发 开发者
探索前端框架的新趋势:React Hooks的应用与实践
本文将深入探讨前端开发中的新趋势,重点介绍React Hooks的应用与实践。通过学习和使用React Hooks,开发者可以更高效地构建可维护、可扩展的前端应用程序。本文将详细介绍React Hooks的原理、优势以及如何在实际项目中运用Hooks来提高开发效率并改善代码结构。无论你是刚入门前端开发还是经验丰富的工程师,本文都将对你有所启发。
|
3月前
|
前端开发 UED
探索前端开发中的无障碍设计与实践
在当今数字化时代,无障碍设计已经成为前端开发中不可忽视的重要环节。本文将介绍无障碍设计的概念和原则,并结合前端开发实践,探索如何为用户提供更加包容和友好的用户体验。
36 2
|
3月前
|
前端开发
构建工具对比:Webpack与Rollup的前端工程化实践
在现代前端开发中,前端工程化变得愈发重要。本文将对两个常用的构建工具——Webpack和Rollup进行比较,探讨它们在前端工程化实践中的特点、优势和适用场景。无论是大型应用的打包优化还是轻量级库的构建,选择适合的构建工具都能提高开发效率和项目性能。
28 1
|
2月前
|
编解码 前端开发 搜索推荐
前端开发中的响应式设计原则与实践
本文将探讨前端开发中的响应式设计原则与实践。我们将介绍什么是响应式设计,为什么在现代Web开发中它如此重要,并提供一些实用的技巧和工具,帮助开发人员创建适应不同设备和屏幕尺寸的用户界面。
|
26天前
|
前端开发 数据可视化 搜索推荐
数据驱动的前端设计与开发实践
本文将介绍如何在前端设计与开发中充分利用数据驱动的方法,通过数据分析、用户行为追踪和可视化等手段,指导前端界面设计和功能开发,提高用户体验和产品质量。
|
26天前
|
机器学习/深度学习 前端开发 算法
利用机器学习优化Web前端性能的探索与实践
本文将介绍如何利用机器学习技术来优化Web前端性能,探讨机器学习在前端开发中的应用,以及通过实际案例展示机器学习算法对前端性能优化的效果。通过结合前端技术和机器学习,提升Web应用的用户体验和性能表现。
|
1月前
|
监控 前端开发 JavaScript
构建高性能Web应用:前端性能优化的关键策略与实践
本文将深入探讨前端性能优化的关键策略与实践,从资源加载、渲染优化、代码压缩等多个方面提供实用的优化建议。通过对前端性能优化的深入剖析,帮助开发者全面提升Web应用的用户体验和性能表现。
|
1月前
|
缓存 前端开发 JavaScript
前端性能优化实践:从理论到实际操作
【2月更文挑战第25天】在互联网高速发展的今天,用户对于网页加载速度的要求越来越高。作为前端开发者,我们不仅要关注页面的视觉效果,还要关注页面的性能。本文将从前端性能优化的理论出发,结合实际操作,为大家介绍一些实用的前端性能优化技巧。
32 6
|
1月前
|
前端开发 JavaScript 开发者
构建响应式Web界面:现代前端开发实践
【2月更文挑战第17天】 随着移动设备用户群体的激增,为各种屏幕尺寸和分辨率构建兼容且优雅的Web界面变得至关重要。本文将深入探讨响应式设计的核心概念,并通过实际案例分析展示如何利用HTML5、CSS3以及JavaScript框架创建流畅的用户体验。我们将着重讨论媒体查询、弹性布局和网格系统等技术的应用,并分享优化响应式网站性能的最佳实践。通过阅读本文,开发者将获得设计和实现适应不同设备的前端项目所需的知识和技能。