整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript 详解:为什么写好的代码非常重要

文将通过简单的术语和真实世界的例子解释 JavaScript 中 this 及其用途,并告诉你写出好的代码为何如此重要。

1.this 适合你吗?

我看到许多文章在介绍 JavaScript 的 this 时都会假设你学过某种面向对象的编程语言,比如 Java、C++ 或 Python 等。但这篇文章面向的读者是那些不知道 this 是什么的人。我尽量不用任何术语来解释 this 是什么,以及 this 的用法。

也许你一直不敢解开 this 的秘密,因为它看起来挺奇怪也挺吓人的。或许你只在 StackOverflow 说你需要用它的时候(比如在 React 里实现某个功能)才会使用。

在深入介绍 this 之前,我们首先需要理解函数式编程和面向对象编程之间的区别。

2.函数式编程 vs 面向对象编程

你可能不知道,JavaScript 同时拥有面向对象和函数式的结构,所以你可以自己选择用哪种风格,或者两者都用。

我在很早以前使用 JavaScript 时就喜欢函数式编程,而且会像躲避瘟疫一样避开面向对象编程,因为我不理解面向对象中的关键字,比如 this。我不知道为什么要用 this。似乎没有它我也可以做好所有的工作。

而且我是对的。

在某种意义上 。也许你可以只专注于一种结构并且完全忽略另一种,但这样你只能是一个 JavaScript 开发者。为了解释函数式和面向对象之间的区别,下面我们通过一个数组来举例说明,数组的内容是 Facebook 的好友列表。

假设你要做一个 Web 应用,当用户使用 Facebook 登录你的 Web 应用时,需要显示他们的 Facebook 的好友信息。你需要访问 Facebook 并获得用户的好友数据。这些数据可能是 firstName、lastName、username、numFriends、friendData、birthday 和 lastTenPosts 等信息。

const data = [
 {
 firstName: 'Bob',
 lastName: 'Ross',
 username: 'bob.ross', 
 numFriends: 125,
 birthday: '2/23/1985',
 lastTenPosts: ['What a nice day', 'I love Kanye West', ...],
 },
 ...
]

假设上述数据是你通过 Facebook API 获得的。现在需要将其转换成方便你的项目使用的格式。我们假设你想显示的好友信息如下:

  • 姓名,格式为`${firstName} ${lastName}`
  • 三篇随机文章
  • 距离生日的天数

3.函数式方式

函数式的方式就是将整个数组或者数组中的某个元素传递给某个函数,然后返回你需要的信息:

const fullNames = getFullNames(data)
// ['Ross, Bob', 'Smith, Joanna', ...]

首先我们有 Facebook API 返回的原始数据。为了将其转换成需要的格式,首先要将数据传递给一个函数,函数的输出是(或者包含)经过修改的数据,这些数据可以在应用中向用户展示。

我们可以用类似的方法获得随机三篇文章,并且计算距离好友生日的天数。

函数式的方式是:将原始数据传递给一个函数或者多个函数,获得对你的项目有用的数据格式。

4.面向对象的方式

对于编程初学者和 JavaScript 初学者,面向对象的概念可能有点难以理解。其思想是,我们要将每个好友变成一个对象,这个对象能够生成你一切开发者需要的东西。

你可以创建一个对象,这个对象对应于某个好友,它有 fullName 属性,还有两个函数 getThreeRandomPosts 和 getDaysUntilBirthday。

function initializeFriend(data) {
 return {
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from data.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use data.birthday to get the num days until birthday
 }
 };
}
const objectFriends = data.map(initializeFriend)
objectFriends[0].getThreeRandomPosts() 
// Gets three of Bob Ross's posts

面向对象的方式就是为数据创建对象,每个对象都有自己的状态,并且包含必要的信息,能够生成需要的数据。

5.这跟 this 有什么关系?

你也许从来没想过要写上面的 initializeFriend 代码,而且你也许认为,这种代码可能会很有用。但你也注意到,这并不是真正的面向对象。

其原因就是,上面例子中的 getThreeRandomPosts 或 getdaysUntilBirtyday 能够正常工作的原因其实是闭包。因为使用了闭包,它们在 initializeFriend 返回之后依然能访问 data。关于闭包的更多信息可以看看这篇文章:作用域和闭包(https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch5.md)。

还有一个方法该怎么处理?我们假设这个方法叫做 greeting。注意方法(与 JavaScript 的对象有关的方法)其实只是一个属性,只不过属性值是函数而已。我们想在 greeting 中实现以下功能:

function initializeFriend(data) {
 return {
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from data.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use data.birthday to get the num days until birthday
 },
 greeting: function() {
 return `Hello, this is ${fullName}'s data!`
 }
 };
}

这样能正常工作吗?

不能!

我们新建的对象能够访问 initializeFriend 中的一切变量,但不能访问这个对象本身的属性或方法。当然你会问,

难道不能在 greeting 中直接用 data.firstName 和 data.lastName 吗?

当然可以。但要是想在 greeting 中加入距离好友生日的天数怎么办?我们最好还是有办法在 greeting 中调用 getDaysUntilBirthday。

这时轮到 this 出场了!

6.终于——this 是什么

this 在不同的环境中可以指代不同的东西。默认的全局环境中 this 指代的是全局对象(在浏览器中 this 是 window 对象),这没什么太大的用途。而在 this 的规则中具有实用性的是这一条:

如果在对象的方法中使用 this,而该方法在该对象的上下文中调用,那么 this 指代该对象本身。

你会说“在该对象的上下文中调用”……是啥意思?

别着急,我们一会儿就说。

所以,如果我们想从 greeting 中调用 getDaysUntilBirtyday 我们只需要写 this.getDaysUntilBirthday,因为此时的 this 就是对象本身。

附注:不要在全局作用域的普通函数或另一个函数的作用域中使用 this!this 是个面向对象的东西,它只在对象的上下文(或类的上下文)中有意义。

我们利用 this 来重写 initializeFriend:

function initializeFriend(data) {
 return {
 lastTenPosts: data.lastTenPosts,
 birthday: data.birthday, 
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from this.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use this.birthday to get the num days until birthday
 },
 greeting: function() {
 const numDays = this.getDaysUntilBirthday() 
 return `Hello, this is ${this.fullName}'s data! It is ${numDays} until ${this.fullName}'s birthday!`
 }
 };
}

现在,在 initializeFriend 执行结束后,该对象需要的一切都位于对象本身的作用域之内了。我们的方法不需要再依赖于闭包,它们只会用到对象本身包含的信息。

好吧,这是 this 的用法之一,但你说过 this 在不同的上下文中有不同的含义。那是什么意思?为什么不一定会指向对象自己?

有时候,你需要将 this 指向某个特定的东西。一种情况就是事件处理函数。比如我们希望在用户点击好友时打开好友的 Facebook 首页。我们会给对象添加下面的 onClick 方法:

function initializeFriend(data) {
 return {
 lastTenPosts: data.lastTenPosts,
 birthday: data.birthday,
 username: data.username, 
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from this.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use this.birthday to get the num days until birthday
 },
 greeting: function() {
 const numDays = this.getDaysUntilBirthday() 
 return `Hello, this is ${this.fullName}'s data! It is ${numDays} until ${this.fullName}'s birthday!`
 },
 onFriendClick: function() {
 window.open(`https://facebook.com/${this.username}`)
 }
 };
}

注意我们在对象中添加了 username 属性,这样 onFriendClick 就能访问它,从而在新窗口中打开该好友的 Facebook 首页。现在只需要编写 HTML:

<button id="Bob_Ross">
 <!-- A bunch of info associated with Bob Ross -->
</button> 

还有 JavaScript:

const bobRossObj = initializeFriend(data[0])
const bobRossDOMEl = document.getElementById('Bob_Ross')
bobRossDOMEl.addEventListener("onclick", bobRossObj.onFriendClick)

在上述代码中,我们给 Bob Ross 创建了一个对象。然后我们拿到了 Bob Ross 对应的 DOM 元素。然后执行 onFriendClick 方法来打开 Bob 的 Facebook 主页。似乎没问题,对吧?

有问题!

哪里出错了?

注意我们调用 onclick 处理程序的代码是 bobRossObj.onFriendClick。看到问题了吗?要是写成这样的话能看出来吗?

bobRossDOMEl.addEventListener("onclick", function() {
 window.open(`https://facebook.com/${this.username}`)
})

现在看到问题了吗?如果把事件处理程序写成 bobRossObj.onFriendClick,实际上是把 bobRossObj.onFriendClick 上保存的函数拿出来,然后作为参数传递。它不再“依附”在 bobRossObj 上,也就是说,this 不再指向 bobRossObj。它实际指向全局对象,也就是说 this.username 不存在。似乎我们没什么办法了。

轮到绑定上场了!

7.明确绑定 this

我们需要明确地将 this 绑定到 bobRossObj 上。我们可以通过 bind 实现:

const bobRossObj = initializeFriend(data[0])
const bobRossDOMEl = document.getElementById('Bob_Ross')
bobRossObj.onFriendClick = bobRossObj.onFriendClick.bind(bobRossObj)
bobRossDOMEl.addEventListener("onclick", bobRossObj.onFriendClick)

之前,this 是按照默认的规则设置的。但使用 bind 之后,我们明确地将 bobRossObj.onFriendClick 中的 this 的值设置为 bobRossObj 对象本身。

到此为止,我们看到了为什么要使用 this,以及为什么要明确地绑定 this。最后我们来介绍一下,this 实际上是箭头函数。

8.箭头函数

你也许注意到了箭头函数最近很流行。人们喜欢箭头函数,因为很简洁、很优雅。而且你还知道箭头函数和普通函数有点区别,尽管不太清楚具体区别是什么。

简而言之,两者的区别在于:

在定义箭头函数时,不管 this 指向谁,箭头函数内部的 this 永远指向同一个东西。

嗯……这貌似没什么用……似乎跟普通函数的行为一样啊?

我们通过 initializeFriend 举例说明。假设我们想添加一个名为 greeting 的函数:

function initializeFriend(data) {
 return {
 lastTenPosts: data.lastTenPosts,
 birthday: data.birthday,
 username: data.username, 
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from this.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use this.birthday to get the num days until birthday
 },
 greeting: function() {
 function getLastPost() {
 return this.lastTenPosts[0]
 }
 const lastPost = getLastPost() 
 return `Hello, this is ${this.fullName}'s data!
 ${this.fullName}'s last post was ${lastPost}.`
 },
 onFriendClick: function() {
 window.open(`https://facebook.com/${this.username}`)
 }
 };
}

这样能运行吗?如果不能,怎样修改才能运行?

答案是不能。因为 getLastPost 没有在对象的上下文中调用,因此getLastPost 中的 this 按照默认规则指向了全局对象。

你说没有“在对象的上下文中调用”……难道它不是从 initializeFriend 返回的内部调用的吗?如果这还不叫“在对象的上下文中调用”,那我就不知道什么才算了。

我知道“在对象的上下文中调用”这个术语很模糊。也许,判断函数是否“在对象的上下文中调用”的好方法就是检查一遍函数的调用过程,看看是否有个对象“依附”到了函数上。

我们来检查下执行 bobRossObj.onFriendClick() 时的情况。“给我对象 bobRossObj,找到其中的 onFriendClick 然后调用该属性对应的函数”。

我们同样检查下执行 getLastPost() 时的情况。“给我名为 getLastPost 的函数然后执行。”看到了吗?我们根本没有提到对象。

好了,这里有个难题来测试你的理解程度。假设有个函数名为 functionCaller,它的功能就是调用一个函数:

functionCaller(fn) {
 fn()
}

如果调用 functionCaller(bobRossObj.onFriendClick) 会怎样?你会认为 onFriendClick 是“在对象的上下文中调用”的吗?this.username有定义吗?

我们来检查一遍:“给我 bobRosObj 对象然后查找其属性 onFriendClick。取出其中的值(这个值碰巧是个函数),然后将它传递给 functionCaller,取名为 fn。然后,执行名为 fn 的函数。”注意该函数在调用之前已经从 bobRossObj 对象上“脱离”了,因此并不是“在对象的上下文中调用”的,所以 this.username 没有定义。

这时可以用箭头函数解决这个问题:

function initializeFriend(data) {
 return {
 lastTenPosts: data.lastTenPosts,
 birthday: data.birthday,
 username: data.username, 
 fullName: `${data.firstName} ${data.lastName}`,
 getThreeRandomPosts: function() {
 // get three random posts from this.lastTenPosts
 },
 getDaysUntilBirthday: function() {
 // use this.birthday to get the num days until birthday
 },
 greeting: function() {
 const getLastPost = () => {
 return this.lastTenPosts[0]
 }
 const lastPost = getLastPost() 
 return `Hello, this is ${this.fullName}'s data!
 ${this.fullName}'s last post was ${lastPost}.`
 },
 onFriendClick: function() {
 window.open(`https://facebook.com/${this.username}`)
 }
 };
}

上述代码的规则是:

在定义箭头函数时,不管 this 指向谁,箭头函数内部的 this 永远指向同一个东西。

箭头函数是在 greeting 中定义的。我们知道,在 greeting 内部的 this 指向对象本身。因此,箭头函数内部的 this 也指向对象本身,这正是我们需要的结果。

9.结论

this 有时很不好理解,但它对于开发 JavaScript 应用非常有用。本文当然没能介绍 this 的所有方面。一些没有涉及到的话题包括:

  • call 和 apply;
  • 使用 new 时 this 会怎样;
  • 在 ES6 的 class 中 this 会怎样。

我建议你首先问问自己在这些情况下的 this,然后在浏览器中执行代码来检验你的结果。

想学习更多关 于this 的内容,可参考《你不知道的 JS:this 和对象原型》:

  • https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes

如果你想测试自己的知识,可参考《你不知道的JS练习:this和对象原型》:

  • https://ydkjs-exercises.com/this-object-prototypes

原文:https://medium.freecodecamp.org/a-deep-dive-into-this-in-javascript-why-its-critical-to-writing-good-code-7dca7eb489e7

作者:Austin Tackaberry,Human API 的软件工程师

译者:弯月,责编:屠敏


HTML作为前端三大基础知识点之一,是每一个前端开发人员都要掌握的部分。今天这篇文章我们来看看一些平时不太会注意,却在面试时可能会问到的题目,来看看你都会吗?

HTML

如何使用div模拟实现textarea?

我们都知道textarea是form表单中一个很常见的元素,用于多行文本输入,可以设置行数和列数。

但是默认的textarea样式在页面上看起来是很丑的,很多页面都是采用div模拟textarea实现。例如QQ空间主页面的发表说说,在你看页面源码后就会发现这个输入框其实是一个div元素,并不是一个textarea元素,现在我们就来看看这是如何实现的吧?

首先来看看实现的效果是什么样的。

实现效果

关键属性:contenteditable

正如这个属性的字面意思,可以理解为可编辑的,如果在页面标签上设置contenteditable=true,该标签就可以进行编辑了。

可以配合user-modify属性,该属性表示的是控制用户能否对页面元素进行编辑,通过设置不同的值可以选择富文本或者纯文本内容,但是由于该属性是非标准属性,很少有人知道。

首先我们来看看页面的HTML部分代码,就是一个很简单的div标签,然后设置contenteditable属性为true。

HTML部分代码

接下来我们就看看整个CSS代码的完整实现吧。

CSS样式

通过min-height和max-height属性可以控制div的高度,在内容超出max-height后会出现滚动条。如果想要固定div的高度,则只需要设置height属性就可以,而不用设置min-height和max-height属性。

src和href的区别

src和href从使用上来看都是对外部资源的一种引用,但是在具体理解上是有差异的。

href的值指定的是资源在网络上的位置,定义的是当前页面上的某个元素与需要的资源文件的一个链接。比如下面一个语句。

href引用

当浏览器解析到页面的这条语句时,会知道在这里引用了一个外部样式文件,但并不会阻止页面解析。这与@import有很大不同,因此在引入外部样式时,推荐使用link标签。

src的值表示的是页面上必不可少的内容,需要将指定内容加载到当前页面中。比如下面一个语句。

src引用

当浏览器解析到页面上的这条语句时,浏览器会对这个文件进行解析,编译和执行,从而导致整个页面加载会被暂停,这也是为什么一般会选择将script标签放在body结束标签的前面。

有一种更好的理解方式,href表示的是一个资源的链接;src是对当前元素的替换,内容最终会嵌入到当前页面中。

DIV+CSS布局和Table布局对比

虽然目前大多数网页都是采用的DIV+CSS布局的方式,但是也有少数的老式Web网页采用的是Table布局,我们可以一起来看看两种布局方式的优劣。

布局对比

  • div+css布局

  1. div+css的布局方式属于W3C标准,而且由于CSS的存在,HTML部分的代码会显得很纯净,满足行为,样式,结构分离的原则。

  2. 页面加载速度更快,这是目前DIV+CSS使用更广泛的一个非常重要的原因。

  3. 页面编码量相对于Table布局会少很多。

  4. 页面内容更容易维护,由于样式都存在CSS文件中,只需要修改CSS文件即可,对HTML文件不会有影响。

  5. 由于DIV+CSS布局更容易进行SEO优化,所以更方便被搜索引擎收录。

  • Table布局

虽然DIV+CSS有各种各样的优势,但是Table布局也并不是完全无用的。这里也可以列举出几个采用Table布局的优势。

  1. 新手学习方便(相信有很多后端RD在进行前端学习时刚开始都是从table布局开始的)。

  2. 兼容性更好,由于Table布局是从最古老的浏览器发展而来的,在兼容性上会满足所有浏览器。而CSS3的出现却要考虑浏览器的支持程度,一个样式要考虑加上几个不同浏览器前缀,类似于-webkit,-moz等

结束语

今天这篇文章主要讲解了几个关于HTML的知识点,大家都掌握了吗?

TML 代码约定

很多 Web 开发人员对 HTML 的代码规范知之甚少。

在2000年至2010年,许多Web开发人员从 HTML 转换到 XHTML。

使用 XHTML 开发人员逐渐养成了比较好的 HTML 编写规范。

而针对于 HTML5 ,我们应该形成比较好的代码规范,以下提供了几种规范的建议。

使用正确的文档类型

文档类型声明位于HTML文档的第一行:

<!DOCTYPE html>

如果你想跟其他标签一样使用小写,可以使用以下代码:

<!doctype html>

使用小写元素名

HTML5 元素名可以使用大写和小写字母。

推荐使用小写字母:

  • 混合了大小写的风格是非常糟糕的。

  • 开发人员通常使用小写 (类似 XHTML)。

  • 小写风格看起来更加清爽。

  • 小写字母容易编写。

不推荐:

<SECTION>

<p>这是一个段落。</p>

</SECTION>

非常糟糕:

<Section>

<p>这是一个段落。</p>

</SECTION>

推荐:

<section>

<p>这是一个段落。</p>

</section>

关闭所有 HTML 元素

在 HTML5 中, 你不一定要关闭所有元素 (例如 <p> 元素),但我们建议每个元素都要添加关闭标签。

不推荐:

<section>

<p>这是一个段落。

<p>这是一个段落。

</section>

推荐:

<section>

<p>这是一个段落。</p>

<p>这是一个段落。</p>

</section>

关闭空的 HTML 元素

在 HTML5 中, 空的 HTML 元素也不一定要关闭:

我们可以这么写:

<meta charset="utf-8">

也可以这么写:

<meta charset="utf-8" />

在 XHTML 和 XML 中斜线 (/) 是必须的。

如果你期望 XML 软件使用你的页面,使用这种风格是非常好的。

使用小写属性名

HTML5 属性名允许使用大写和小写字母。

我们推荐使用小写字母属性名:

  • 同时使用大小写是非常不好的习惯。

  • 开发人员通常使用小写 (类似 XHTML)。

  • 小写风格看起来更加清爽。

  • 小写字母容易编写。

不推荐:

<div CLASS="menu">

推荐:

<div class="menu">

属性值

HTML5 属性值可以不用引号。

属性值我们推荐使用引号:

  • 如果属性值含有空格需要使用引号。

  • 混合风格不推荐的,建议统一风格。

  • 属性值使用引号易于阅读。

以下实例属性值包含空格,没有使用引号,所以不能起作用:

<table class=table striped>

以下使用了双引号,是正确的:

<table class="table striped">

图片属性

图片通常使用 alt 属性。 在图片不能显示时,它能替代图片显示。

<img src="html5.gif" alt="HTML5" style="width:128px;height:128px">

定义好图片的尺寸,在加载时可以预留指定空间,减少闪烁。

<img src="html5.gif" alt="HTML5" style="width:128px;height:128px">

空格和等号

等号前后可以使用空格。

<link rel = "stylesheet" href = "styles.css">

但我们推荐少用空格:

<link rel="stylesheet" href="styles.css">

避免一行代码过长

使用 HTML 编辑器,左右滚动代码是不方便的。

每行代码尽量少于 80 个字符。

空行和缩进

不要无缘无故添加空行。

为每个逻辑功能块添加空行,这样更易于阅读。

缩进使用两个空格,不建议使用 TAB。

比较短的代码间不要使用不必要的空行和缩进。

不必要的空行和缩进:

<body>

<h1>菜鸟教程</h1>

<h2>HTML</h2>

<p>

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想,

菜鸟教程,学的不仅是技术,更是梦想。

</p>

</body>

推荐:

<body>

<h1>菜鸟教程</h1>

<h2></h2>

<p>菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。</p>

</body>

表格实例:

<table>

<tr>

<th>Name</th>

<th>Description</th>

</tr>

<tr>

<td>A</td>

<td>Description of A</td>

</tr>

<tr>

<td>B</td>

<td>Description of B</td>

</tr>

</table>

列表实例:

<ol>

<li>London</li>

<li>Paris</li>

<li>Tokyo</li>

</ol>

省略 <html> 和 <body>?

在标准 HTML5 中, <html> 和 <body> 标签是可以省略的。

以下 HTML5 文档是正确的:

实例:

<!DOCTYPE html>

<head>

<title>页面标题</title>

</head>

<h1>这是一个标题</h1>

<p>这是一个段落。</p>

尝试一下 »

不推荐省略 <html> 和 <body> 标签。

<html> 元素是文档的根元素,用于描述页面的语言:

<!DOCTYPE html>

<html lang="zh">

声明语言是为了方便屏幕阅读器及搜索引擎。

省略 <html> 或 <body> 在 DOM 和 XML 软件中会崩溃。

省略 <body> 在旧版浏览器 (IE9)会发生错误。

省略 <head>?

在标准 HTML5 中, <head>标签是可以省略的。

默认情况下,浏览器会将 <body> 之前的内容添加到一个默认的 <head> 元素上。

实例

<!DOCTYPE html>

<html>

<title>页面标题</title>

<body>

<h1>这是一个标题</h1>

<p>这是一个段落。</p>

</body>

</html>

尝试一下 »

现在省略 head 标签还不推荐使用。

元数据

HTML5 中 <title> 元素是必须的,标题名描述了页面的主题:

<title>菜鸟教程</title>

标题和语言可以让搜索引擎很快了解你页面的主题:

<!DOCTYPE html>

<html lang="zh">

<head>

<meta charset="UTF-8">

<title>菜鸟教程</title>

</head>

HTML 注释

注释可以写在 <!-- 和 --> 中:

<!-- 这是注释 -->

比较长的评论可以在 <!-- 和 --> 中分行写:

<!--

这是一个较长评论。 这是 一个较长评论。这是一个较长评论。

这是 一个较长评论 这是一个较长评论。 这是 一个较长评论。

-->

长评论第一个字符缩进两个空格,更易于阅读。

样式表

样式表使用简洁的语法格式 ( type 属性不是必须的):

<link rel="stylesheet" href="styles.css">

短的规则可以写成一行:

p.into {font-family: Verdana; font-size: 16em;}

长的规则可以写成多行:

body {

background-color: lightgrey;

font-family: "Arial Black", Helvetica, sans-serif;

font-size: 16em;

color: black;

}

  • 将左花括号与选择器放在同一行。

  • 左花括号与选择器间添加以空格。

  • 使用两个空格来缩进。

  • 冒号与属性值之间添加已空格。

  • 逗号和符号之后使用一个空格。

  • 每个属性与值结尾都要使用符号。

  • 只有属性值包含空格时才使用引号。

  • 右花括号放在新的一行。

  • 每行最多 80 个字符。

在逗号和分号后添加空格是常用的一个规则。

在 HTML 中载入 JavaScript

使用简洁的语法来载入外部的脚本文件 ( type 属性不是必须的 ):

<script src="myscript.js">

使用 JavaScript 访问 HTML 元素

一个糟糕的 HTML 格式可能会导致 JavaScript 执行错误。

以下两个 JavaScript 语句会输出不同结果:

实例

var obj = getElementById("Demo")

var obj = getElementById("demo")

HTML 中 JavaScript 尽量使用相同的命名规则。

访问 JavaScript 代码规范。

使用小写文件名

大多 Web 服务器 (Apache, Unix) 对大小写敏感: london.jpg 不能通过 London.jpg 访问。

其他 Web 服务器 (Microsoft, IIS) 对大小写不敏感: london.jpg 可以通过 London.jpg 或 london.jpg 访问。

你必须保持统一的风格,我们建议统一使用小写的文件名。

文件扩展名

HTML 文件后缀可以是 .html (或r .htm)。

CSS 文件后缀是 .css

JavaScript 文件后缀是 .js

.htm 和 .html 的区别

.htm 和 .html 的扩展名文件本质上是没有区别的。浏览器和 Web 服务器都会把它们当作 HTML 文件来处理。

区别在于:

.htm 应用在早期 DOS 系统,系统现在或者只能有三个字符。

在 Unix 系统中后缀没有特别限制,一般用 .html。

技术上区别

如果一个 URL 没有指定文件名 (如 http://www.runoob.com/css/), 服务器会返回默认的文件名。通常默认文件名为 index.html, index.htm, default.html, 和 default.htm。

如果服务器只配置了 "index.html" 作为默认文件,你必须将文件命名为 "index.html", 而不是 "index.htm"。

但是,通常服务器可以设置多个默认文件,你可以根据需要设置默认文件吗。

不管怎样,HTML 完整的后缀是 ".html"。

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!