整合营销服务商

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

免费咨询热线:

如何在HTML中使用JavaScript:从基础到高级的全面指南!

这里是云端源想IT,帮你轻松学IT”

嗨~ 今天的你过得还好吗?

我们总是先扬起尘土

然后抱怨自己看不见

- 2024.04.17 -

JavaScript是一种轻量级的编程语言,通常用于网页开发,以增强用户界面的交互性和动态性。然而在HTML中,有多种方法可以嵌入和使用JavaScript代码。

本文就带大家深入了解如何在HTML中使用JavaScript。



一、使用 script 标签

要在HTML中使用JavaScript,我们需要使用<script>标签。这个标签可以放在<head>或<body>部分,但通常我们会将其放在<body>部分的底部,以确保在执行JavaScript代码时,HTML文档已经完全加载。

使用 <script> 标签有两种方式:直接在页面中嵌入 JavaScript 代码包含外部 JavaScript 文件。


包含在 <script> 标签内的 JavaScript 代码在浏览器总按照从上至下的顺序依次解释。


所有 <script> 标签都会按照他们在 HTML 中出现的先后顺序依次被解析。



HTML 为 <script> 定义了几个属性:

1)async:可选。表示应该立即下载脚本,但不妨碍页面中其他操作。该功能只对外部 JavaScript 文件有效。


如果给一个外部引入的js文件设置了这个属性,那页面在解析代码的时候遇到这个<script>的时候,一边下载该脚本文件,一边异步加载页面其他内容。


2)defer:可选。表示脚本可以延迟到整个页面完全被解析和显示之后再执行。该属性只对外部 JavaScript 文件有效。


3)src:可选。表示包含要执行代码的外部文件。


4)type:可选。表示编写代码使用的脚本语言的内容类型,目前在客户端,type 属性值一般使用 text/javascript。不过这个属性并不是必需的,如果没有指定这个属性,则其默认值仍为text/javascript。



1.1 直接在页面中嵌入JavaScript代码

内部JavaScript是将JavaScript代码放在HTML文档的<script>标签中。这样可以将JavaScript代码与HTML代码分离,使结构更清晰,易于维护。


在使用<script>元素嵌入JavaScript代码时,只须为<script>指定type属性。然后,像下面这样把JavaScript代码直接放在元素内部即可:

<script type="text/javascript">
function sayHi(){
alert("Hi!");
}
</script>


如果没有指定script属性,则其默认值为text/javascript。


包含在<script>元素内部的JavaScript代码将被从上至下依次解释。在解释器对<script>元素内部的所有代码求值完毕以前,页面中的其余内容都不会被浏览器加载或显示。


在使用<script>嵌入JavaScript代码的过程中,当代码中出现"</script>"字符串时,由于解析嵌入式代码的规则,浏览器会认为这是结束的</script>标签。可以通过转义字符“\”写成<\/script>来解决这个问题。


1.2 包含外部 JavaScript 文件

外部JavaScript是将JavaScript代码放在单独的.js文件中,然后在HTML文档中通过<script>标签的src属性引用这个文件。这种方法可以使代码更加模块化,便于重用和共享。


如果要通过<script>元素来包含外部JavaScript文件,那么src属性就是必需的。这个属性的值是一个指向外部JavaScript文件的链接。

<script type="text/javascript" src="example.js"></script>


  • 外部文件example.js将被加载到当前页面中。
  • 外部文件只须包含通常要放在开始的<script>和结束的</script>之间的那些JavaScript代码即可。



与解析嵌入式JavaScript代码一样,在解析外部JavaScript文件(包括下载该文件)时,页面的处理也会暂时停止。

注意:带有src属性的<script>元素不应该在其<script>和</script>标签之间再包含额外的JavaScript代码。如果包含了嵌入的代码,则只会下载并执行外部脚本文件,嵌入的代码会被忽略。

通过<script>元素的src属性还可以包含来自外部域的JavaScript文件。它的src属性可以是指向当前HTML页面所在域之外的某个域中的完整URL。

<script type="text/javascript" src="http://www.somewhere.com/afile.js"></script>

于是,位于外部域中的代码也会被加载和解析。


1.3 标签的位置

在HTML中,所有的<script>标签会按照它们出现的先后顺序被解析。在不使用defer和async属性的情况下,只有当前面的<script>标签中的代码解析完成后,才会开始解析后面的<script>标签中的代码。


通常,所有的<script>标签应该放在页面的<head>标签中,这样可以将外部文件(包括CSS和JavaScript文件)的引用集中放置。



然而,如果将所有的JavaScript文件都放在<head>标签中,会导致浏览器在呈现页面内容之前必须下载、解析并执行所有JavaScript代码,这可能会造成明显的延迟,导致浏览器窗口在加载过程中出现空白。


为了避免这种延迟问题,现代Web应用程序通常会将所有的JavaScript引用放置在<body>标签中的页面内容的后面。这样做可以确保在解析JavaScript代码之前,页面的内容已经完全呈现在浏览器中,从而加快了打开网页的速度。


二、执行JavaScript 程序

JavaScript 解析过程包括两个阶段:预处理(也称预编译)执行

  • 在编译期,JavaScript 解析器将完成对 JavaScript 代码的预处理操作,把 JavaScript 代码转换成字节码;
  • 在执行期,JavaScript 解析器把字节码生成二进制机械码,并按顺序执行,完成程序设计的任务。


1、执行过程

HTML 文档在浏览器中的解析过程是:按照文档流从上到下逐步解析页面结构和信息。

JavaScript 代码作为嵌入的脚本应该也算做 HTML 文档的组成部分,所以 JavaScript 代码在装载时的执行顺序也是根据 <script> 标签出现的顺序来确定。

你是不是厌倦了一成不变的编程模式?想要突破自我,挑战新技术想要突破自我,挑战新技术?却迟迟找不到可以练手的项目实战?是不是梦想打造一个属于自己的支付系统?那么,恭喜你,云端源想免费实战直播——《微实战-使用支付宝/微信支付服务,网站在线支付功能大揭秘》正在进行,点击前往获取源码!云端源想

2、预编译

当 JavaScript 引擎解析脚本时候,他会在与编译期对所有声明的变量和函数预先进行处理。当 JavaScript 解析器执行下面脚本时不会报错。

alert(a); //返回值 undefined
var a = 1;
alert(a); //返回值 1


由于变量声明是在预编译期被处理的,在执行期间对于所有的代码来说,都是可见的,但是执行上面代码,提示的值是 undefined 而不是 1。

因为变量初始化过程发生在执行期,而不是预编译期。在执行期,JavaScript 解析器是按照代码先后顺序进行解析的,如果在前面代码行中没有为变量赋值,则 JavaScript 解析器会使用默认值 undefined 。


由于第二行中为变量 a 赋值了,所以在第三行代码中会提示变量 a 的值为 1,而不是 undefined。

fun(); //调用函数,返回值1
function fun(){
alert(1);
}

函数声明前调用函数也是合法的,并能够正确解析,所以返回值是 1。但如果是下面这种方式则 JavaScript 解释器会报错。

fun(); //调用函数,返回语法错误
var fun = function(){
alert(1);
}

上面的这个例子中定义的函数仅作为值赋值给变量 fun 。在预编译期,JavaScript 解释器只能够为声明变量 fun 进行处理,而对于变量 fun 的值,只能等到执行期时按照顺序进行赋值,自然就会出现语法错误,提示找不到对象 fun。

总结:声明变量和函数可以在文档的任意位置,但是良好的习惯应该是在所有 JavaScript 代码之前声明全局变量和函数,并对变量进行初始化赋值。在函数内部也是先声明变量,后引用。

通过今天的分享,相信大家已经对JavaScript在HTML中的应用有了一定的了解。这只是冰山一角,JavaScript的潜力远不止于此。希望这篇文章能激发大家对编程的热情,让我们一起在编程的世界里探索更多的可能性!



我们下期再见!


END

文案编辑|云端学长

文案配图|云端学长

内容由:云端源想分享

目开发中一些常用的es6知识,主要是为以后分享小程序开发、node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫。

项目开发常用es6介绍

  • 1、块级作用域 let const
  • 2、箭头函数及this指向
  • 3、promise、asnyc await语法
  • 4、模块化 module export和import
  • 5、解构赋值、字符串模板
  • ……

Module

Module即模块的意思,在一些小项目中可能用不到这个概念。但是对于一些大型的、复杂的项目尤其在多人协作的情况下几乎是必须的。

在 ES6 之前,最主要的有 CommonJS 和 AMD 两种模块化解决方案。前者用于服务器,后者用于浏览器。ES6 的出现实现了模块功能,而且实现得相当简单完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

简单的说ES6 模块是通过export命令指定输出的代码,再通过import命令导入

下面我们直接通过代码来演示:

<!
DOCTYPE html
>
<
html
>
<
head lang
=
"en"
>
 
<
meta charset
=
"UTF-8"
>
 
<
title
></
title
>
</
head
>
<
body
>
 
<
script type
=
"module"
>
 
//index.html
 
import
 
*
 as util from 
"./js/scrpit.js"
;
 
//用星号(*)指定一个对象,所有输出值都加载在这个对象上面
 util
.
func1
()
 
//1
 util
.
func2
()
 
//2
 console
.
log
(
util
.
a
==
3
)
 
//true
 
</
script
>
</
body
>
</
html
>
//script.js
export
 
function
 func1
()
 
{
 console
.
log
(
1
)
}
export
 
function
 func2
()
 
{
 console
.
log
(
2
)
}
export
 
var
 a 
=
 
3
;

可以看到body里面的script标签与我们平常写的稍有不同,加入了type="module"属性,这样浏览器才会知道这是一个 ES6 模块。

当然,模块的导入导出还可以有别的方式:

比如常用的导出模块的两种方式:

//script.js 方式1
export
 
function
 func1
()
 
{
 console
.
log
(
1
)
}
export
 
function
 func2
()
 
{
 console
.
log
(
2
)
}
export
 
var
 a 
=
 
3
;
//script.js 方式2
function
 func1
()
 
{
 console
.
log
(
1
)
}
function
 func2
()
 
{
 console
.
log
(
2
)
}
var
 a 
=
 
3
;
export
 
{
func1
,
func2
,
a
}

常用的导入模块的两种方式:

///方式1
import
 
{
func1
,
func2
,
a
}
 from 
"./js/scrpit.js"
;
func1
()
 
//1
func2
()
 
//2
console
.
log
(
a
==
3
)
 
//true
///方式2
import
 
*
 as util from 
"./js/scrpit.js"
;
util
.
func1
()
 
//1
util
.
func2
()
 
//2
console
.
log
(
util
.
a
==
3
)
 
//true

解构赋值

其实在模块的导入中就已经用到了解构赋值。即按照一定模式,从数组和对象中提取值,并对变量进行赋值。

下面列举一些简单的示例,如需深入学习建议大家去学习阮一峰写的es6入门哈

//情景1
let 
[
foo
,
 
[[
bar
],
 baz
]]
 
=
 
[
1
,
 
[[
2
],
 
3
]];
foo 
// 1
bar 
// 2
baz 
// 3
//情景2
let 
[
 
,
 
,
 third
]
 
=
 
[
"foo"
,
 
"bar"
,
 
"baz"
];
third 
// "baz"
//情景3
let 
[
x
,
 
,
 y
]
 
=
 
[
1
,
 
2
,
 
3
];
x 
// 1
y 
// 3
//情景4
let 
[
head
,
 
...
tail
]
 
=
 
[
1
,
 
2
,
 
3
,
 
4
];
head 
// 1
tail 
// [2, 3, 4]
//情景5
let 
[
x
,
 y
,
 
...
z
]
 
=
 
[
'a'
];
x 
// "a"
y 
// undefined
z 
// []

如果解构不成功,变量的值就等于undefined。

let 
[
foo
]
 
=
 
[];
let 
[
bar
,
 foo
]
 
=
 
[
1
];

以上两种情况都属于解构不成功,foo的值都会等于undefined。

另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let 
[
x
,
 y
]
 
=
 
[
1
,
 
2
,
 
3
];
x 
// 1
y 
// 2
let 
[
a
,
 
[
b
],
 d
]
 
=
 
[
1
,
 
[
2
,
 
3
],
 
4
];
a 
// 1
b 
// 2
d 
// 4

上面两个例子,都属于不完全解构,但是可以成功。

如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。

// 报错
let 
[
foo
]
 
=
 
1
;
let 
[
foo
]
 
=
 
false
;
let 
[
foo
]
 
=
 
NaN
;
let 
[
foo
]
 
=
 
undefined
;
let 
[
foo
]
 
=
 
null
;
let 
[
foo
]
 
=
 
{};

解构赋值允许指定默认值。

注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let 
[
foo 
=
 
true
]
 
=
 
[];
foo 
// true
let 
[
x
,
 y 
=
 
'b'
]
 
=
 
[
'a'
];
 
// x='a', y='b'
let 
[
x
,
 y 
=
 
'b'
]
 
=
 
[
'a'
,
 
undefined
];
 
// x='a', y='b'
let 
[
x 
=
 
1
]
 
=
 
[
undefined
];
x 
// 1
let 
[
x 
=
 
1
]
 
=
 
[
null
];
x 
// null
//上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

解构不仅可以用于数组,还可以用于对象。

let 
{
 foo
,
 bar 
}
 
=
 
{
 foo
:
 
"aaa"
,
 bar
:
 
"bbb"
 
};
foo 
// "aaa"
bar 
// "bbb"

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let 
{
 bar
,
 foo 
}
 
=
 
{
 foo
:
 
"aaa"
,
 bar
:
 
"bbb"
 
};
foo 
// "aaa"
bar 
// "bbb"
let 
{
 baz 
}
 
=
 
{
 foo
:
 
"aaa"
,
 bar
:
 
"bbb"
 
};
baz 
// undefined

如果变量名与属性名不一致,必须写成下面这样。

let 
{
 foo
:
 baz 
}
 
=
 
{
 foo
:
 
'aaa'
,
 bar
:
 
'bbb'
 
};
baz 
// "aaa"
let obj 
=
 
{
 first
:
 
'hello'
,
 last
:
 
'world'
 
};
let 
{
 first
:
 f
,
 last
:
 l 
}
 
=
 obj
;
f 
// 'hello'
l 
// 'world'

对象的解构也可以指定默认值。默认值生效的条件是,对象的属性值严格等于undefined。

var
 
{
x 
=
 
3
}
 
=
 
{
x
:
 
undefined
};
x 
// 3
var
 
{
x 
=
 
3
}
 
=
 
{
x
:
 
null
};
x 
// null

模板字符串

传统的 JavaScript 语言,输出模板通常是这样写的:

$
(
'#result'
).
append
(
 
'There are <b>'
 
+
 basket
.
count 
+
 
'</b> '
 
+
 
'items in your basket, '
 
+
 
'<em>'
 
+
 basket
.
onSale 
+
 
'</em> are on sale!'
);

上面这种写法相当繁琐不方便,ES6 引入了模板字符串解决这个问题。

$
(
'#result'
).
append
(`
 
There
 are 
<
b
>
$
{
basket
.
count
}</
b
>
 items
 in your basket
,
 
<
em
>
$
{
basket
.
onSale
}</
em
>
 are on sale
!
`);

即用反引号(Tab上面的按键)表示,如果模板字符串中嵌入变量,需要将变量名写在${}之中。这样就不需要使用大量的引号和加号,大大节约了开发时间。

注:在本地浏览器中使用模块化需要配置服务环境,如果使用的是vscode编辑器可以安装Open with live server插件,安装完成后重启编辑器就可以在.html文件上右键选择Open with live server,然后浏览器输入localhost:5500打开,端口号看编辑器最下方提示。如果是Hbuilder编辑器则需要配置一下web服务器,其它编辑器具体的可以百度一下哈。阿门~

关注我的头条号,分享更多的技术学习文章,我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。


者:*5102

转发链接:https://juejin.im/post/5e9f0bdce51d4546f5791989