最好的JavaScript在线教程

在互联网发展的早期,JavaScript就已经成为支持网页内容交互体验的基础技术。随着时间推移,JavaScript业已升级成为互联网的核心技术。

长期以来,我都在学习JavaScript。学习JS一时爽,一直学习一直爽。

在学习过程中,接触很多学习资料,图书、视频等不一而足。

今天给大家介绍两个线上教程,都是广受好评的,相信你一定也看过。

1 Mozilla 开发者社区 JavaScript 教程

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

教程内容:

  • 对于完全初学者
    • JavaScript 第一步
    • JavaScript 基本结构
    • 介绍JavaScript 对象
  • JavaScript 指南
  • 中级内容
    • 客户端 Web API
    • 重新介绍 JavaScript(JS 教程)
    • JavaScript 数据结构
    • 如何使用比较操作符
    • 闭包
  • 高级内容
    • 继承和原型链
    • 严格模式
    • JavaScript 类型数组
    • 内存管理
    • 并发模型以及事件循环

2 现代 JavaScript 教程

https://zh.javascript.info/

教程内容:

第 一 部分 JavaScript 编程语言

在这儿我们将从头开始学习 JavaScript,也会学习 OOP 等相关高级概念。

第 二 部分 浏览器:文档,事件,接口

学习如何管理浏览器页面:添加元素,操纵元素的大小和位置,动态创建接口并与访问者互动。

第 三 部分 其他文章

教程的前两部分未涉及的其他主题的内容列表。此处没有明确的层次结构,你可以按你需要的顺序阅读文章。

js代码解析:获取服务器数据并展示

<script>

const EXCHANGE_MAP = {

\’SHFE\’: 113,

\’DCE\’: 114,

\’CZCE\’: 115,

\’GFEX\’: 225,

\’INE\’: 142,

\’CFFEX\’: 220

};

async function fetchVarieties() {

try {

const response = await fetch(\’https://q.xxx.biz/\’);

const data = await response.json();

const groupedData = {};

data.list.forEach(item => {

const [exchange, code] = item.uid.split(\’|\’);

const variety = code.replace(/\\d+/g, \’\’);

if (!groupedData[exchange]) {

groupedData[exchange] = new Set();

}

groupedData[exchange].add({

code: variety,

name: item.name.replace(/\\d+/g, \’\’)

});

});

const select = document.getElementById(\’varietySelect\’);

Object.entries(groupedData).forEach(([exchange, varieties]) => {

const optgroup = document.createElement(\’optgroup\’);

optgroup.label = exchange;

varieties.forEach(variety => {

const option = document.createElement(\’option\’);

option.value = `${EXCHANGE_MAP[exchange]}_${variety.code}`;

option.textContent = variety.name;

optgroup.appendChild(option);

});

select.appendChild(optgroup);

});

} catch (error) {

console.error(\’Error fetching varieties:\’, error);

}

}

async function fetchContracts(variety) {

try {

const response = await fetch(`https://q.xxx.ink/redis?msgid=${variety}`);

const data = await response.json();

return data

.filter(item => /\\d+/.test(item.code))

.map(item => `${item.mktid}_${item.code}`);

} catch (error) {

console.error(\’Error fetching contracts:\’, error);

return [];

}

}

async function fetchPrices(contracts) {

try {

console.log(\’Fetching prices for contracts:\’, contracts);

const response = await fetch(`https://q.xxx.ink/custom/${contracts.join(\’,\’)}?orderBy=code&sort=asc&pageSize=100&pageIndex=0&callbackName=`);

const text = await response.text();

console.log(\’Raw response:\’, text);

const jsonStr = text.replace(/^[^({]*\\(|\\)[^}]*$/g, \’\’);

console.log(\’Processed JSON string:\’, jsonStr);

try {

const data = JSON.parse(jsonStr);

console.log(\’Parsed data:\’, data);

if (data && Array.isArray(data.list)) {

return data.list;

}

return [];

} catch (parseError) {

console.error(\’Error parsing JSON:\’, parseError);

console.log(\’Problematic JSON string:\’, jsonStr);

return [];

}

} catch (error) {

console.error(\’Error fetching prices:\’, error);

return [];

}

}

function updatePriceTable(prices) {

const tbody = document.querySelector(\’#priceData tbody\’);

tbody.innerHTML = \’\’;

if (!Array.isArray(prices) || prices.length === 0) {

const row = document.createElement(\’tr\’);

row.innerHTML = \'<td colspan=\”4\” style=\”text-align: center;\”>暂无数据</td>\’;

tbody.appendChild(row);

return;

}

prices.forEach(item => {

const row = document.createElement(\’tr\’);

row.innerHTML = `

<td>${item.name || \’-\’}</td>

<td>${item.p || \’-\’}</td>

<td>${item.zdf || \’-\’}%</td>

<td>${item.vol || 0}</td>

<td>${item.ccl || 0}</td>

`;

tbody.appendChild(row);

});

}

function sortContracts(prices) {

return prices.sort((a, b) => {

const monthA = a.name.match(/\\d+/)[0];

const monthB = b.name.match(/\\d+/)[0];

return monthA – monthB;

});

}

function updateChart(prices) {

const chartDom = document.getElementById(\’chartContainer\’);

const myChart = echarts.init(chartDom);

const sortedPrices = sortContracts(prices);

const option = {

title: {

text: \’月间合约对比\’,

left: \’center\’

},

tooltip: {

trigger: \’axis\’,

axisPointer: {

type: \’cross\’

}

},

legend: {

data: [\’价格\’, \’成交量\’, \’持仓量\’],

top: 30,

left: \’center\’

},

grid: [{

left: \’3%\’,

right: \’3%\’,

height: \’50%\’

}, {

left: \’3%\’,

right: \’3%\’,

top: \’65%\’,

height: \’25%\’

}],

xAxis: [{

type: \’category\’,

data: sortedPrices.map(item => item.name),

axisLine: { onZero: true },

grid: { top: \’50%\’ }

}, {

type: \’category\’,

gridIndex: 1,

data: sortedPrices.map(item => item.name),

position: \’bottom\’

}],

yAxis: [{

name: \’价格\’,

type: \’value\’,

splitLine: {

show: true

},

min: function (value) {

return value.min * 0.99; // 设置 Y 轴最小值为数据最小值的 0.9 倍

},

max: function (value) {

return value.max * 1.01; // 设置 Y 轴最大值为数据最大值的 1.1 倍

}

}, {

gridIndex: 1,

name: \’成交量/持仓量\’,

type: \’value\’,

splitLine: {

show: true

},

min: function (value) {

return value.min * 0.99; // 设置 Y 轴最小值为数据最小值的 0.9 倍

},

max: function (value) {

return value.max * 1.01; // 设置 Y 轴最大值为数据最大值的 1.1 倍

}

}],

series: [{

name: \’价格\’,

type: \’line\’,

data: sortedPrices.map(item => item.p || 0),

smooth: true,

lineStyle: {

width: 2

},

itemStyle: {

color: \’#5470c6\’

}

}, {

name: \’成交量\’,

type: \’bar\’,

xAxisIndex: 1,

yAxisIndex: 1,

data: sortedPrices.map(item => item.vol || 0),

itemStyle: {

color: \’#91cc75\’

}

}, {

name: \’持仓量\’,

type: \’bar\’,

xAxisIndex: 1,

yAxisIndex: 1,

data: sortedPrices.map(item => item.ccl || 0),

itemStyle: {

color: \’#fac858\’

}

}],

dataZoom: [{

type: \’inside\’,

xAxisIndex: [0, 1],

start: 0,

end: 100

}, {

show: true,

xAxisIndex: [0, 1],

type: \’slider\’,

bottom: 10,

start: 0,

end: 100

}]

};

myChart.setOption(option);

window.addEventListener(\’resize\’, () => {

myChart.resize();

});

}

document.getElementById(\’varietySelect\’).addEventListener(\’change\’, async (e) => {

const variety = e.target.value;

if (!variety) {

document.getElementById(\’contractList\’).textContent = \’\’;

updatePriceTable([]);

const chartDom = document.getElementById(\’chartContainer\’);

const myChart = echarts.init(chartDom);

myChart.clear();

return;

}

document.querySelector(\’.loading\’).style.display = \’block\’;

try {

const contracts = await fetchContracts(variety);

document.getElementById(\’contractList\’).textContent =

`[${contracts.map(c => c.split(\’_\’)[1]).join(\’,\’)}]`;

const prices = await fetchPrices(contracts);

updatePriceTable(prices);

if (prices && prices.length > 0) {

updateChart(prices);

}

} catch (error) {

console.error(\’Error updating data:\’, error);

document.getElementById(\’contractList\’).textContent = \’获取数据失败\’;

updatePriceTable([]);

} finally {

document.querySelector(\’.loading\’).style.display = \’none\’;

}

});

// 从URL中获取默认品种

(async function() {

const urlParams = new URLSearchParams(window.location.search);

const defaultVariety = urlParams.get(\’variety\’);

if (defaultVariety) {

document.getElementById(\’varietySelect\’).value = defaultVariety;

await fetchContracts(defaultVariety);

const contracts = await fetchContracts(defaultVariety);

document.getElementById(\’contractList\’).textContent =

`[${contracts.map(c => c.split(\’_\’)[1]).join(\’,\’)}]`;

const prices = await fetchPrices(contracts);

updatePriceTable(prices);

if (prices && prices.length > 0) {

updateChart(prices);

}

} else {

await fetchVarieties();

}

})();

</script>

这段代码涉及到了很多JavaScript的知识点,以下是一些主要的知识点:

1. 变量和常量

●使用const声明常量,例如EXCHANGE_MAP。

●变量的解构赋值,如const [exchange, code] = item.uid.split(\’|\’);。

2. 数据结构

●使用对象({})和Map进行数据存储和检索。

●使用Set来存储唯一值。

3. 异步编程

●使用async/await进行异步操作,简化Promise的使用。

●使用fetchAPI进行网络请求。

4. 数组和字符串方法

●数组的forEach、map、filter等方法。

●字符串的split、replace、match等方法。

5. DOM操作

●使用document.getElementById、document.createElement等方法操作DOM。

●使用appendChild方法添加子元素。

6. 事件处理

●使用addEventListener为DOM元素添加事件监听器。

7. 错误处理

●使用try…catch语句进行错误捕获和处理。

8. JSON处理

●使用JSON.parse解析JSON字符串。

●处理JSON解析错误。

9. 正则表达式

●使用正则表达式进行字符串匹配和替换,如/\\d+/g。

10. 排序

●使用数组的sort方法进行排序。

11. ECharts库

●使用ECharts库进行数据可视化,包括图表的配置和更新。

12. 模块化

●代码结构体现了模块化的思想,将不同的功能封装在不同的函数中。

13. 立即执行函数表达式(IIFE)

●使用IIFE来封装一些初始化代码,避免污染全局作用域。

14. URL和查询参数处理

●使用URLSearchParams处理URL查询参数。

15. 条件渲染

●根据数据是否存在来决定渲染内容,例如在没有数据时显示“暂无数据”。

这些知识点覆盖了JavaScript的基础语法、异步编程、DOM操作、数据处理和可视化等多个方面,展示了现代JavaScript开发的综合应用。

JavaScript代码的三种引入方式【操作演示】

在网页中编写JavaScript代码时,需要先引入JavaScript代码。JavaScript代码有3种引入方式,分别是行内式、嵌入式和外链式,下面分别进行讲解。

行内式是将JavaScript代码作为HTML标签的属性值使用。例如,在单击超链接“test”时,弹出一个警告框提示“Hello”,示例代码如下:

需要说明的是,行内式只有在临时测试或者特殊情况下使用,一般情况下不推荐使用行内式,因为行内式有如下缺点。

(1)行内式可读性较差,尤其是在HTML文件中编写大量JavaScript代码时,不方便阅读。

(2)行内式在遇到多层引号嵌套的情况时,引号非常容易混淆,导致代码出错。

嵌入式(或称内嵌式)使用<scrip>标签包裹JavaScript代码,直接编写到HTML文件中,通常将其放到<head>标签<body>或标签中。<scrip>标签的type属性用于告知浏览器脚本类型,HTML.5中该属性的默认值为“text/javascript”,因此在使用HTML5时可以省略ype属性。嵌入式的示例代码如下:

外链式(或称外部式)是将JavaScript 代码写在一个单独的文件中,一般使用“js”作为文件的扩展名,在HTML页面中使用<script>标签的src属性引人“js”文件。外链式适合javascript代码量较多的情况。在html页面中引入“js”文件,示例代码如下:

上述代码表示引入当前目录下的tesL.js文件。需要注意的是,外链式的标签内不可以编写JavaScript 代码。

为了帮助初学者更好地理解外链式,下面利用外链式实现浏览网页时在页面中自动弹出警告框。创建Example02.html文件,引入Example02.js文件,具体代码如例1-2所示。

标签的src属性设置了要引入的文件为Example02.js。

创建Example02.js文件,在该文件中编写如下代码:

保存代码,在浏览器中访问Example02.html文件,页面效果与例1-1相同。

以上讲解了JavaScript的3种引入方式。现代网页开发中提倡结构、样式、行为的分离,即分离HTML、CSS、JavaScrixt这3部分代码,这样更有利于文件的维护。当需要编写大量的、逻辑复杂的、具有特定功能的JavaScrigt代码时,推荐使用外链式。外链式相比嵌入式,具有以下3点优势:

(1)外链式存在于独立文件中,有利于修改和维护,而嵌人式会导致HTML代码与JavaScript代码混合在一起。

(2)外链式可以利用浏览器缓存提高速度。例如,在多个页面中引入相同的JavaScript文件时,打开第1个页面后,浏览器将JavaScript文件缓存下来,下次打开其他页面时就不用重新下载该文件了。

(3)外链式有利于HTML页h代码结构化,把大段的JavaScript代码分离到HTML页面之外,既美观,也方便文件级别的代码复用。

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。