菜鸟学完之后,总是感觉学了也还是不会,主要就是因为没有实践,不知道自己到底哪里有问题!虽然说我还没复习完,前端很大一部分都处于模糊阶段,但是感觉还是应该先尽力做一个简单的东西,把这几天学的都用进去,遇到困难,才知道自己的不足!而菜鸟感觉自己的天赋可能就在于,学习完之后,可以马上想一个运用到学习完了的知识点的项目φ(゜▽゜*)♪
菜鸟大致要做的就是这样的:
可以拖动左侧的小乐谱(下拉图)到中间变成大乐谱,然后右边有演示视频,按键通过按键盘上的字母发出对应的音阶!
一开始,菜鸟的代码是这样的
HTML:
<ul style="list-style: none;" class="head_left_ul">
<li>
<div class="head_music_name">
<img onclick="show1()" src="img/尖括号右.png">
<p>两只老虎p>
div>
<div class="head_music" id="twotiger_music">
<img style="width: 140px;height: 100px;" src="img/twotiger.jpg">
div>
li>
<li>
<div class="head_music_name">
<img onclick="show2()" src="img/尖括号右.png">
<p>小星星p>
div>
<div class="head_music" id="star_music">
<img style="width: 140px;height: 100px;" src="img/star.jpg">
div>
li>
<li>
<div class="head_music_name">
<img onclick="show3()" src="img/尖括号右.png">
<p>虫儿飞p>
div>
<div class="head_music" id="worm_music">
<img style="width: 140px;height: 100px;" src="img/worm.jpg">
div>
li>
ul>
css:
.head_left_ul li{
background-color: rgba(128, 128, 128,0.7);
color: white;
width: 140px;
}
.head_music_name P{
display: inline-block;
margin: 0 0 0 30px;
vertical-align: bottom;
}
.head_music {
display: none;
}
js:
function show1() {
let a = document.querySelector("#twotiger_music");
console.log(a);
console.log(a.style.display);
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
} else {
a.style.display = "none";
}
}
function show2() {
let a = document.querySelector("#star_music");
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
} else {
a.style.display = "none";
}
}
function show3() {
let a = document.querySelector("#worm_music");
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
} else {
a.style.display = "none";
}
}
这里之前的讲过,但是有点不一样,先讲的是文字在前面,图片在后面,现在这种情况正好反过来,不过在浏览器中进行调试,可以很清楚的知道该用什么,记下来不如会调试。如果想看的话 ,见 重学前端 p多大 / 浏览器最小文字 / 详解img / object-fit和object-posit / 详解map / 空白区域 / 文字与图片对齐 / vertical-align(第一天)
querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。
注意:
querySelector() 方法仅仅返回匹配指定选择器的第一个元素,如果你需要返回所有的元素,请使用 querySelectorAll() 方法替代。
资料:
HTML DOM querySelector() 方法
第一种:使用 cssText 全属性
*.style.cssText = "width: 666px; color: red";
第二种:使用 setProperty(属性名,属性值) 方法
*.style.setProperty("width", "666px");
第三种:直接使用单属性
*.style.width="666px";
一·、这里菜鸟打印a.style.display,就是想看第一次点击的时候,浏览器会默认display:none为什么东西,结果就是空白,也就是“”
二、菜鸟之所以会用三个show函数,是因为,如果使用querySelector() 方法仅仅返回匹配指定选择器的第一个元素,那样菜鸟不知道怎么区分三个li
然后,菜鸟感觉不行,应该把箭头也变一下,不能一直都是向右的箭头,点击之后应该向下!
于是代码变成了这样(css写好了就无变化了,后面不再列举)。
HTML:
<ul style="list-style: none;" class="head_left_ul">
<li>
<div class="head_music_name">
<img id="head_arrows" onclick="show1(this)" src="img/尖括号右.png">
<p>两只老虎p>
div>
<div class="head_music" id="twotiger_music">
<img style="width: 140px;height: 100px;" src="img/twotiger.jpg">
div>
li>
<li>
<div class="head_music_name">
<img id="head_arrows" onclick="show2(this)" src="img/尖括号右.png">
<p>小星星p>
div>
<div class="head_music" id="star_music">
<img style="width: 140px;height: 100px;" src="img/star.jpg">
div>
li>
<li>
<div class="head_music_name">
<img id="head_arrows" onclick="show3(this)" src="img/尖括号右.png">
<p>虫儿飞p>
div>
<div class="head_music" id="worm_music">
<img style="width: 140px;height: 100px;" src="img/worm.jpg">
div>
li>
ul>
js:
function show1(element) {
let a = document.querySelector("#twotiger_music");
console.log(element);
console.log(a);
console.log(a.style.display);
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
function show2(element) {
let a = document.querySelector("#star_music");
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
function show3(element) {
let a = document.querySelector("#worm_music");
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
菜鸟这里想到了用this,是因为,感觉如果通过document.querySelector的方式获取,那么又得像show函数那样,写三次了!这里的id = ”head-arrows" 是可以去掉的!
οnclick=xxx(this)表示一个单击事件,来进行调用xxx(this)这个JavaScript函数,而xxx(this)函数中的this表示你要进行单击对象的本身。
菜鸟感觉重复代码过多,所以必须得提出一个函数,然后在其它函数里面调用。
代码如下(这里html并未改变,所以这里只列举js)
js:
function show1(element) {
let a = document.querySelector("#twotiger_music");
console.log(element);
console.log(a);
console.log(a.style.display);
this.change(a,element);
}
function show2(element) {
let a = document.querySelector("#star_music");
this.change(a,element);
}
function show3(element) {
let a = document.querySelector("#worm_music");
this.change(a,element);
}
function change(a, element) {
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
菜鸟突然记起来data-*,是可以传递参数的,而document.querySelectorAll得到的又是数组,那么是不是可以直接靠传参实现一个show函数呢?
代码如下
HTML:
<ul style="list-style: none;" class="head_left_ul">
<li>
<div class="head_music_name">
<img data-index="0" onclick="show1(this)" src="img/尖括号右.png">
<p>两只老虎p>
div>
<div class="head_music">
<img style="width: 140px;height: 100px;" src="img/twotiger.jpg">
div>
li>
<li>
<div class="head_music_name">
<img data-index="1" onclick="show1(this)" src="img/尖括号右.png">
<p>小星星p>
div>
<div class="head_music">
<img style="width: 140px;height: 100px;" src="img/star.jpg">
div>
li>
<li>
<div class="head_music_name">
<img data-index="2" onclick="show1(this)" src="img/尖括号右.png">
<p>虫儿飞p>
div>
<div class="head_music">
<img style="width: 140px;height: 100px;" src="img/worm.jpg">
div>
li>
ul>
js:
function show1(element) {
console.log(element.dataset.index);
let index = element.dataset.index;
let b = document.querySelectorAll(".head_music");
let a = b[index];
this.change(a, element);
}
function change(a, element) {
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
菜鸟突然发现越是简洁的代码,其实就暗示着思路越发清晰,运用越发熟练,菜鸟得向简洁的代码奋斗!
(2020/8/2,今天已经是准备写这篇文章的第三天了,前面的倒是慢慢的写的,还能说出条理,后面的完全就是自己在写代码,然后想写的这个博客的时候却发现,忘记先写的代码了,咳咳咳,这里直接把成品展示出来就好)
这就是效果,然后代码已经上传到GitHub上去了,有兴趣的读者可以直接克隆一份
$git clone [email protected]:pbw-langwang/Git_warehouse.git
$ git switch -c dev origin/dev
代码都有注释的!
直接访问连接:https://github.com/pbw-langwang/Git_warehouse
如果不想下,下面就是代码,请慢慢欣赏
HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>weekworktitle>
<link rel="stylesheet" href="style.css">
<script src="dom.js">script>
<noscript>
<div
style="width: 1000px;height:500px;background-color: aqua;display: flex;justify-content: center;align-items: center;">
<div style="width: 500px;height: 300px;background-color: pink;">
<h1>抱歉,你的浏览器不支持 JavaScript!h1>
<p>难受≧ ﹏ ≦p>
div>
div>
noscript>
head>
<body onkeydown="playaudio(event)">
<div
style="background-image: url(img/light.jpg);background-repeat:no-repeat;background-size:100% 100%;width: 100%;height: 100%;">
<div class="head" style="display: flex;justify-content: space-around;">
<div class="head_lelf">
<ul class="head_left_ul">
<li>
<div class="head_music_name">
<img data-index="0" onclick="show1(this)" src="img/尖括号右.png">
<p>两只老虎p>
div>
<div class="head_music" data-id="twotiger" style="width: 200px;height: 100px"
ondrop="drop2(event)" ondragover="allowDrop(event)">
<img id="twotiger" style="width: 100%;height: 100%;" ondragstart="move(event)"
src="img/twotiger.jpg">
div>
li>
<li>
<div class="head_music_name">
<img data-index="1" onclick="show1(this)" src="img/尖括号右.png">
<p>小星星p>
div>
<div class="head_music" data-id="star" style="width: 200px;height: 100px" ondrop="drop2(event)"
ondragover="allowDrop(event)">
<img id="star" style="width: 100%;height: 100%;" src="img/star.jpg"
ondragstart="move(event)">
div>
li>
<li>
<div class=" head_music_name">
<img data-index="2" onclick="show1(this)" src="img/尖括号右.png">
<p>虫儿飞p>
div>
<div class="head_music" data-id="worm" style="width: 200px;height: 100px" ondrop="drop2(event)"
ondragover="allowDrop(event)">
<img id="worm" style="width: 100%;height: 100%" src="img/worm.jpg"
ondragstart="move(event)">
div>
li>
ul>
div>
<div class=" head_center"
style="width: 600px;height: 400px;position: relative;background-color: rgba(0, 89, 255,0.8);border: solid 3px blue;margin: auto 0;">
<div style="width: 600px;height: 350px;" ondrop="drop(event)" ondragover="allowDrop(event)">
div>
<p style="
position: absolute;
bottom: 0;
color: white;
font-size: 30px;
font-weight: 500;
width: 100%;
height: 50px;
text-align: center;
margin: 0;
background-color: aqua;">
乐谱
p>
div>
<div class="head_end">
<ul class="head_end_ul">
<li>
<div class="head_end_musicname" data-index2="0" onclick="show2(this)">
<p>两只老虎p>
<img src="img/尖括号左.png">
div>
<div data-id="twotiger2" style="width: 200px;height: 100px" class="head_end_video"
ondrop="drop2(event)" ondragover="allowDrop(event)">
<video id="twotiger2" draggable="true" style="width: 100%;height: 100%;" controls="controls"
src="video/twotiger.mp4" ondragstart="move(event)">video>
div>
li>
<li>
<div class="head_end_musicname" data-index2="1" onclick="show2(this)">
<p>小星星p>
<img src="img/尖括号左.png">
div>
<div data-id="star2" style="width: 200px;height: 100px" class="head_end_video"
ondrop="drop2(event)" ondragover="allowDrop(event)">
<video id="star2" draggable="true" style="width: 100%;height: 100%;" src="video/star.mp4"
controls="controls" ondragstart="move(event)">video>
div>
li>
<li>
<div class="head_end_musicname" data-index2="2" onclick="show2(this)">
<p>虫儿飞p>
<img src="img/尖括号左.png">
div>
<div data-id="worm2" style="width: 200px;height: 100px" class="head_end_video"
ondrop="drop2(event)" ondragover="allowDrop(event)">
<video id="worm2" draggable="true" style="width: 100%;height: 100%;" src="video/worm.mp4"
controls="controls" ondragstart="move(event)">video>
div>
li>
ul>
div>
div>
<div class="end_div">
<ul style="display: flex;justify-content: space-around;align-items: center;">
<li>
<p>1p>
<p>.p>
<p>.p>
<p>C+p>
<p class="key">Qp>
<audio data-keynub="81" src="audio/C+.mp3">audio>
li>
<li>
<p>2p>
<p>.p>
<p>.p>
<p>D+p>
<p class="key">Wp>
<audio data-keynub="87" src="audio/D+.mp3">audio>
li>
<li>
<p>3p>
<p>.p>
<p>.p>
<p>E+p>
<p class="key">Ep>
<audio data-keynub="69" src="audio/E+.mp3">audio>
li>
<li>
<p>4p>
<p>.p>
<p>.p>
<p>F+p>
<p class="key">Rp>
<audio data-keynub="82" src="audio/F+.mp3">audio>
li>
<li>
<p>5p>
<p>.p>
<p>.p>
<p>G+p>
<p class="key">Tp>
<audio data-keynub="84" src="audio/G+.mp3">audio>
li>
<li>
<p>6p>
<p>.p>
<p>.p>
<p>A+p>
<p class="key">Yp>
<audio data-keynub="89" src="audio/A+.mp3">audio>
li>
<li>
<p>7p>
<p>.p>
<p>.p>
<p>B+p>
<p class="key">Up>
<audio data-keynub="85" src="audio/B+.mp3">audio>
li>
<li>
<p>1p>
<p>Cp>
<p class="key">Ap>
<audio data-keynub="65" src="audio/C.mp3">audio>
li>
<li>
<p>2p>
<p>Dp>
<p class="key">Sp>
<audio data-keynub="83" src="audio/D.mp3">audio>
li>
<li>
<p>3p>
<p>Ep>
<p class="key">Dp>
<audio data-keynub="68" src="audio/E.mp3">audio>
li>
<li>
<p>4p>
<p>Fp>
<p class="key">Fp>
<audio data-keynub="70" src="audio/F.mp3">audio>
li>
<li>
<p>5p>
<p>Gp>
<p class="key">Gp>
<audio data-keynub="71" src="audio/G.mp3">audio>
li>
<li>
<p>6p>
<p>Ap>
<p class="key">Hp>
<audio data-keynub="72" src="audio/A.mp3">audio>
li>
<li>
<p>7p>
<p>Bp>
<p class="key">Jp>
<audio data-keynub="74" src="audio/B.mp3">audio>
li>
<li>
<p>1p>
<p>.p>
<p>C-p>
<p class="key">Zp>
<audio data-keynub="90" src="audio/C-.mp3">audio>
li>
<li>
<p>2p>
<p>.p>
<p>D-p>
<p class="key">Xp>
<audio data-keynub="88" src="audio/D-.mp3">audio>
li>
<li>
<p>3p>
<p>.p>
<p>E-p>
<p class="key">Cp>
<audio data-keynub="67" src="audio/E-.mp3">audio>
li>
<li>
<p>4p>
<p>.p>
<p>F-p>
<p class="key">Vp>
<audio data-keynub="86" src="audio/F-.mp3">audio>
li>
<li>
<p>5p>
<p>.p>
<p>G-p>
<p class="key">Bp>
<audio data-keynub="66" src="audio/G-.mp3">audio>
li>
<li>
<p>6p>
<p>.p>
<p>A-p>
<p class="key">Np>
<audio data-keynub="78" src="audio/A-.mp3">audio>
li>
<li>
<p>7p>
<p>.p>
<p>B-p>
<p class="key">Mp>
<audio data-keynub="77" src="audio/B-.mp3">audio>
li>
ul>
div>
div>c
body>
html>
css:
body{
margin: 0;
}
.head_left_ul , .head_end_ul , .end_div ul{
padding-inline-start: 0;
list-style: none;
}
.head_left_ul li , .head_end_ul li{
background-color: rgba(128, 128, 128,0.7);
color: white;
width: 200px;
}
.head_music_name p , .head_end_musicname p {
display: inline-block;
margin: 0 0 0 30px;
vertical-align: bottom;
}
.head_music , .head_end_video {
display: none;
}
.head_end_musicname {
display: flex;
align-items: center;
justify-content: flex-end;
}
.head_end_musicname p {
margin: 0 30px 0 0;
}
.end_div {
height: 210px;
}
.end_div ul {
width: 100%;
height: 100%;
margin: 5px 0;
padding: 5px 0;
background-color: rgba(128, 128, 128,0.7);
}
.end_div ul li {
width: 4%;
height: 100%;
background-color: white;
}
.end_div ul li p{
text-align: center;
margin: 0;
}
.key {
font-size: 30px;
font-weight: 500px;
}
js:(运用到了es6命名空间、栈的思想、data-传参、拖动)
let variable = {
bool: true,
pli: '',//不能只写一个pli,必须赋值,即使是空
array: [],
}
//es6的命名空间
function show1(element) {
let index = element.dataset.index;
let b = document.querySelectorAll(".head_music");
let a = b[index];
// 通过data-index来知道点击的是哪一个
this.change(a, element);
}
function change(a, element) {
if (a.style.display === "none" || a.style.display === "") {
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号右.png";
}
}
function move(event) {
event.dataTransfer.setData("Text", event.target.id);
}
function allowDrop(ev) {
ev.preventDefault();
ev.stopPropagation();
}
function drop(ev) {
ev.preventDefault();
ev.stopPropagation();
// 阻止浏览器对拖动的默认处理,但是firefox有点小bug
// 加上ev.stopPropagation();已解决firefox的bug
var data = ev.dataTransfer.getData("Text");
if (variable.bool) {
ev.target.appendChild(document.getElementById(data));
variable.bool = false;
// 添加元素后,设置互斥变量,防止其它再次拖入造成bug
}
}
function drop2(ev) {
ev.preventDefault();
ev.stopPropagation();
var data = ev.dataTransfer.getData("Text");
let data_id = ev.target.dataset.id;
if (!variable.bool && data === data_id) {
// 通过id 和 data-id的对应关系,来确定是否可以移入
ev.target.appendChild(document.getElementById(data));
variable.bool = true;
}
}
// 设置一个全局互斥变量,以防止多次拖动的bug
function show2(element) {
let index2 = element.dataset.index2;
let b = document.querySelectorAll(".head_end_video");
let a = b[index2];
let c = a.parentElement.children[0].children[1];
// c是获取到video父元素中的img
this.change2(a, c);
}
function change2(a, element) {
if (a.style.display === "none" || a.style.display === "") {
// 第一次a.style.display是空值
a.style.display = "inline-block";
element.src = "img/尖括号下.png";
} else {
a.style.display = "none";
element.src = "img/尖括号左.png";
}
}
function playaudio(event) {
let arr = document.querySelectorAll("audio");
if (variable.pli) {//把variable换成this也可以
// 如果有变了颜色的,就改回其颜色
variable.pli.style.setProperty("background-color", "white");
}
for (i = 0; i < variable.array.length; i++) {
// 判断最近5个中有没有按到的和正在按的相同,如果有就暂停并归零
if (variable.array[i] === event.keyCode) {
for (j = 0; j < arr.length; j++) {
if (parseInt(arr[j].dataset.keynub) === event.keyCode) {
arr[j].currentTime = 0;//设置时间为0,并暂停全部
arr[i].pause();
}
}
}
}
for (i = 0; i < arr.length; i++) {
if (parseInt(arr[i].dataset.keynub) === event.keyCode) {
//通过keynub和keyCode的对应关系,判断哪一个播哦
arr[i].play();
// 保存最近按的5个,如果超过就删除前一个在末尾加上新来的
if (variable.array.length < 6) {
variable.array.push(parseInt(arr[i].dataset.keynub));
} else {
variable.array.shift();
variable.array.push(parseInt(arr[i].dataset.keynub));
};
// console.log(variable.array);
variable.pli = arr[i].parentElement;
variable.pli.style.setProperty("background-color", "rgb(128, 128, 128)");
}
}
}