探新Web前端开发(六)

来源:互联网 发布:神话软件下载 编辑:程序博客网 时间:2024/06/08 10:53

JavaScript 中的继承

JavaScript中继承的对象函数并不是通过复制而来,而是通过原型链继承。
让我们通过具体的例子来解释上述概念

开始

你能看到一个只定义了一些属性的Person构造器,与之前通过模块来实现所有功能的Person的构造器类似。
function Person(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
};

所有的方法都定义在构造器的prototype上,比如:
Person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};

比如我们想要创建一个Teacher类,就像我们前面在面向对象概念解释时用的那个一样。这个类会继承Person的所有成员

定义 Teacher() 构造函数

创建一个Teacher()构造器
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}

这在很多方面看起来都和Person的构造器很像,但是这里有一些我们从没见过的奇怪玩意——call()函数。基本上,这个函数允许你调用一个在这个文件里别处定义的函数。第一个参数指明了在你运行这个函数时想对“this”指定的值,也就是说,你可以重新指定你调用的函数里所有“this”指向的对象。其他的变量指明了所有目标函数运行时接受的参数。

设置Teacher() 的prototype 和constructor引用

我们已经定义了一个新的构造器,这个构造器默认有一个空的原型属性。我们需要让Teacher()从Person()的原型对象里继承方法。我们要怎么做呢?

  1. 在你上的添加内容的下面加上以下这一行:
    Teacher.prototype = Object.create(Person.prototype);
    在这个例子里我们用这个函数来创建一个和一样的新的原型属性值(这个属性指向一个包括属性和方法的对象),然后将其作为的属性值。这意味着现在会继承的所有属性和方法。
  2. 在我们接下去做之前,还需要完成一件事—现在Teacher()的prototype的constructor属性指向的是Person(),这是因为我们生成Teacher()的方式决定的。输入以下代码来确认:
    Teacher.prototype.constructor
  3. 这或许会成为很大的问题,所以我们需要将其正确设置——你可以回到源代码,在底下加上这一行代码来解决:
    Teacher.prototype.constructor = Teacher;

向Teacher() 增加新的函数greeting()

为了完善代码,你还需在构造函数Teacher()上定义一个新的函数greeting()。
Teacher.prototype.greeting = function() {
var prefix;
if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
prefix = 'Mr.';
} else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
prefix = 'Mrs.';
} else {
prefix = 'Mx.';
}
alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
};

Working with JSON data

JSON是一种按照JavaScript对象语法的数据格式,虽然它是基于Javascript语法,但它独立于javaScript,这也是为什么许多程序环境能够读取(解读)和生成JSON。 JSON可以作为一个对象或者字符串存在,前者用于解读JSON中的数据,后者用于通过网络传输JSON数据。一个JSON对象可以被储存在它自己的文件中,这基本上就是一个文本文件,扩展名为.json,还有 MIME type用于 application/json.

JSON 结构

{
“homeTown” : “Metro City”,
“formed” : 2016,
“active” : true,
“members” : [
{
…………………
},
{
…………….
},
]
}

JSON 数组

[
{
“name” : “Molecule Man”,
“age” : 29,
“powers” : [
“Radiation resistance”
]
},
{
“name” : “Madame Uppercut”,
“age” : 39,
“powers” : [
“Million tonne punch”
]
}
]
上面是完全合法的 JSON。你只需要通过数组索引就可以访问数组元素,如[0][“powers”][0]。

加载我们的JSON

为了载入 JSON 到页面中,我们将使用 一个名为 XMLHttpRequest 的API(常称为XHR)。这是一个非常有用的 JavaScript 对象,使我们能够通过代码来向服务器请求资源文件(如:图片,文本,JSON,甚至HTML片段),意味着我们可以更新小段内容而不用重新加载整个页面。

  1. 首先,我们将保存一个即将访问的 URL 作为变量。在你的 JavaScript 代码的底部添加下面的代码:
    var requestURL = 'https://.........superheroes.json';
  2. 为了创建一个Http请求,我们需要创建一个Http请求对象,通过 new 构造函数的形式。在你最下面的代码中写入:
    var request = new XMLHttpRequest();
  3. 现在我们需要使用 open() 函数打开一个新的请求,添加如下代码:
    request.open('GET', requestURL);
  4. 接下来添加两行代码,我们设定 responseType 为 JSON,所以服务器将知道我们想要返回一个 JSON 对象,然后发送请求 :
    request.responseType = 'json';
    request.send();
  5. 最后一点内容涉及相应来自服务器的返回数据,然后处理它,添加如下代码在你先前的代码下方:
    request.onload = function() {
    var superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    }

    这儿我们保存了相应我们请求的数据(访问 response 属性) 于变量 superHeroes ;这个变量现在含有 JSON!我们现在把 superHeroes 传给两个函数,第一个函数将会用正确的数据填充<header>,同时第二个函数将创建一个信息卡片,然后把它插入<section>中。
    如populateHeader()函数:
    function populateHeader(jsonObj) {
    var myH1 = document.createElement('h1');
    myH1.textContent = jsonObj['squadName'];
    header.appendChild(myH1);
    var myPara = document.createElement('p');
    myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
    header.appendChild(myPara);
    }

对象和文本间的转换

上述示例就访问 JSON 而言是简单的,因为我们设置了 XHR 来访问 JSON 格式数据:
request.responseType = 'json';
但是有时候我们没有那么幸运,我们接收到一些 字符串作为 JSON 数据,然后我们想要将它转换为对象。当我们想要发送 JSON 数据作为信息,我们将需要转换它为字符串,我们经常需要正确的转换数据,幸运的是,这两个问题在web环境中是那么普遍以至于浏览器拥有一个内建的 JSON,包含以下两个方法:

  • parse(): 以文本字符串形式接受JSON对象作为参数,并返回相应的对象。
  • stringify(): 接收一个对象作为参数,返回一个对应的JSON字符串。

无障碍多媒体

可访问的音频和视频控制

HTML5视频和音频实例甚至带有一组内置的控件,可让您直接控制媒体。例如:

<audio controls>  <source src="viper.mp3" type="audio/mp3">  <source src="viper.ogg" type="audio/ogg">  <p>Your browser doesn't support HTML5 audio. Here is a <a href="viper.mp3">link to the audio</a> instead.</p></audio><br><video controls>  <source src="rabbit320.mp4" type="video/mp4">  <source src="rabbit320.webm" type="video/webm">  <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p></video>

控件属性提供播放/暂停按钮,搜索栏等 - 您期望从媒体播放器的基本控制
但是,这些控件有问题:

  • 它们不是键盘可访问的,除了Opera之外的任何浏览器
  • 不同的浏览器使本机控件具有不同的样式和功能。

为了解决这个问题,我们可以创建自己的自定义控件。

创建自定义音频和视频控件

HTML5视频和音频共享一个API - HTML媒体元素 - 它允许你将自定义功能映射到按钮和其他控件 - 这两个都是自己定义的。
首先,我们来看看HTML中的视频播放器的HTML:

<section class="player">  <video controls>    <source src="rabbit320.mp4" type="video/mp4">    <source src="rabbit320.webm" type="video/webm">    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>  </video>  <div class="controls">    <button class="playpause">Play</button>    <button class="stop">Stop</button>    <button class="rwd">Rwd</button>    <button class="fwd">Fwd</button>    <div class="time">00:00</div>  </div></section>

我们在我们的视频下面插入了一些简单的控制按钮 这些控制当然不会在默认情况下做任何事情; 要添加功能,我们将使用JavaScript。
我们首先需要存储对每个控件的引用 - 将以下内容添加到JavaScript文件的顶部:

var playPauseBtn = document.querySelector('.playpause');var stopBtn = document.querySelector('.stop');var rwdBtn = document.querySelector('.rwd');var fwdBtn = document.querySelector('.fwd');var timeLabel = document.querySelector('.time');

接下来,我们需要获取对视频/音频播放器本身的引用 - 将以下行添加到以下行中:
var player = document.querySelector('video');
这包含一个HTMLMediaElement对象的引用,它有几个可用的属性和方法可用于将功能连接到我们的按钮。

在开始创建按钮功能之前,让我们删除本机控件,这样就不会妨碍我们的自定义控件。再次添加以下内容,您的JavaScript底部:
player.removeAttribute('controls');
这样做,而不是仅仅不包括控件属性在第一位的优势是,如果我们的JavaScript由于任何原因失败,用户仍然有一些可用的控件

接线我们的按钮

首先,让我们设置播放/暂停按钮。我们可以通过一个简单的条件函数来获得它在播放和暂停之间切换,如下所示。将其添加到代码底部:

playPauseBtn.onclick = function() {  if(player.paused) {    player.play();    playPauseBtn.textContent = 'Pause';  } else {    player.pause();    playPauseBtn.textContent = 'Play';  }};

接下来,将此代码添加到底部,控制停止按钮:

stopBtn.onclick = function() {  player.pause();  player.currentTime = 0;  playPauseBtn.textContent = 'Play';};

接下来,快退和快进按钮:

//快退rwdBtn.onclick = function() {  player.currentTime -= 3;};//快进fwdBtn.onclick = function() {  player.currentTime += 3;  if(player.currentTime >= player.duration || player.paused) {    player.pause();    player.currentTime = 0;    playPauseBtn.textContent = 'Play';  }};

这些非常简单,只需在currentTime每次点击时添加或减去3秒钟。
请注意,当按下Fwd按钮时,我们还会检查是否currentTime超过总媒体duration,或者媒体未播放。如果任一条件都为真,我们只需停止视频,以避免用户界面出现错误,如果在视频未播放时尝试快进,或者快速转到视频结尾。

最后,将以下内容添加到代码的末尾,以控制经过的时间显示:

player.ontimeupdate = function() {  var minutes = Math.floor(player.currentTime / 60);  var seconds = Math.floor(player.currentTime - minutes * 60);  var minuteValue;  var secondValue;  if (minutes<10) {    minuteValue = "0" + minutes;  } else {    minuteValue = minutes;  }  if (seconds<10) {    secondValue = "0" + seconds;  } else {    secondValue = seconds;  }  mediaTime = minuteValue + ":" + secondValue;  timeLabel.textContent = mediaTime;};

每次时间更新(每秒一次),我们启动此功能。它从给定的currentTime值(以秒为单位)输出分钟数和秒数,如果分钟或秒值小于10,则添加前缀0,然后创建显示读数并将其添加到时间标签。