声明:本文是以题目的形式运用js知识点解决问题来提升对js知识点的理解
格式为 题目;方法;原因;缺点(如果方法有缺点的话);实现代码;

文章目录

  • 基础篇
    • 1.分支结构
    • 2.循环
    • 3.函数
    • 4.递归
    • 5.数组
    • 6.字符
    • 7.随机数
    • 8.BOM&DOM
    • 9.正则

基础篇

1.分支结构

1.判断一个字符串是不是纯数字(字符串中不包含小数即以下方法都不能判断含小数的字符串)

方法一:字符转数字的严格模式+if()的隐式类型转换
原因:严格模式下非数字为NaN,NaN在if()的隐式类型转换中为false
缺点:无法判断全是0的数字(因为if()的隐式类型转换中0为false,但实际上0也是数字)

var str1 = "001";
// 方式一:无法判断全是0的数字
if( Number(str1) ){alert("是纯数字");
}else{alert("不是纯数字");
}

方法二:isNaN()+if()的隐式类型转换+if()的隐式类型转换
原因:isNaN()会自动将字符串转换成数值并判断数值是否为NaN

if( isNaN(str1) ){alert("不是纯数字");
}else{alert("是纯数字");
}

方法三:算术运算符的隐士类型转换(除+外)+if()的隐式类型转换
原因:-, *, /, %会将两边的数据作为数值型数据计算,当-,*,/,%两边的数据无法转成数字时,会转成NaN,NaN参与任何运算都是非法的
缺点:无法判断全是0的数字(因为if()的隐式类型转换中0为false,但实际上0也是数字)

if( str1 - 0 ){alert("是纯数字");
}else{alert("不是纯数字");
}

方法四:字符转数字的非严格模式+if()的隐式类型转换
原因:如果是非纯数字的话,数值在转后会造成数值丢失

if( parseInt(str1) == str1 ){alert("是纯数字");
}else{alert("不是纯数字");
}

2.判断一个字符是不是空字符

方法一:if()的隐式类型转换
原因:在if()的隐式类型转换中,字符非空为true

var str2 = " ";
if(str2){alert("不为空字符");//空格也是字符
}else{alert("是空字符");
}

方法二:字符串内容为空的情况下根据字符串为空的属性或者是类型
原因:字符串为空,其值为undefined,同时undefined(类型undefined)的值与null(类型object)相等

if(str==null || str==undefined || str===""){console.log("是空字符");
}else{console.log("不是空字符");
}

方法三:字符串内容不为空的情况下根据字符串的属性和是字符串的长度
原因:字符串内容不为空其属性为string,长度大于0

if(typeof str == "string" && str.length>0){console.log("不是空字符");
}else{console.log("是空字符");
}

3.根据输入的月份和当前天数计算是平年的第几天
方法:switch的case穿透
原因:不加break就会引起case穿透,可以利用case穿透做出累加的效果

<script>// 月份var mouth = 12;// 天数var day = 31;// 平年的第多少天var data = 0;switch(mouth){case 12:{data += 30;}case 11:{data += 31;}case 10:{data += 30;}case 9:{data += 31;}case 8:{data += 31;}case 7:{data += 30;}case 6:{data += 31;}case 5:{data += 30;}case 4:{data += 31;}case 3:{data += 28; }case 2:{data += 31;}case 1:{data += day;break;      }default:{alert("输入月份错误");break;}}console.log(data);</script>

2.循环

1.打印以下图案

     ***************************************************************

方法:for循环嵌套
原因:第一层for循环控制行,第二层for循环控制列;这个图案分为三个部分,左边是空格,右边是*号1和*号2

for(var i=0;i<7;i++){// 空格部分for(var j=7;j>i;j--){document.write("&nbsp;");}// *号区域1,正常排列,但被空格部分挤往右边,就会看着是往右靠了for(var j=0;j<=i;j++){document.write("*");}// *号区域2for(var j=0;j<=i+1;j++){document.write("*");}// 换行document.write("<br>");
}

2.有一个棋盘,有64个方格,在第一个方格里面放1粒芝麻重量是0.00001kg,第二个里面放2粒,第三个里面放4,第四个里面放8,棋盘上放的所有芝麻的重量
方法:for循环嵌套
原因:第一层for循环控制方格,第二层for循环控制方格里面放的芝麻数量

var sum = 0;
for(var i=0;i<64;i++){var a = 1;//每当下面的for执行结束,sum加完之后重置a变量for(var j=0;j<i;j++){a = a * 2;}// console.log(a);sum += a;
}
console.log(sum * 0.00001);

3.函数

1.编写函数,实现任意个任意数字的和
方法:用arguments接收数据,再通过索引遍历处理
原因:arguments用来保存当前函数的所有的实参(不受形参的数量影响)

var sum=0;
function add(){for(var i=0;i<arguments.length;i++){sum+=arguments[i];}return sum;
}
console.log(add(1,1,1,1,1));

2.编写一个函数,计算两个数字的和/差/积/商 /余,要求:使用传参的方式
方法:switch分情况处理
原因:因为传入的算术运算符不同要进行的操作也不同,根据传入的算术运算符决定要怎么运算

function compute(n1, n2, sy) {switch (sy) {case "+": {return console.log(n1 + n2);}case "-": {return console.log(n1 - n2);}case "*": {return console.log(n1 * n2);}case "/": {return console.log(n1 / n2);}case "%": {return console.log(n1 % n2);}default: {alert("运算符输入错误");}}
}
compute(1, 2, "+");
compute(1, 2, "-");
compute(1, 2, "*");
compute(1, 2, "/");
compute(1, 2, "%");

3.编写一个函数,计算任意两个数字之间所能组成的两位数的奇数,数字必须是个位数比如: 计算0,3之间能组成的奇数个是01、21、03、13、23、31
方法:循环遍历然后判断
原因:先确定两个数字之间的范围,再用字符串拼接这些范围内的数字,遍历这些数字,符合条件的输出

function compute(n1, n2) {if(n1>n2){var temp=0;temp=n1;n1=n2;n2=temp;}for (var i = 0; i <= n2; i++) {for (var j = 0; j <= n2; j++) {//判断奇偶,不要重复的,这里包含了字符,if()的隐式类型转换if (("" + i + j) % 2 && i !== j) {console.log("" + i + j);}}}
}
compute(3, 0);

4.递归

1.计算n的阶乘
方法:递归
原因:阶乘的计算是一个重复的过程,是有规律可寻的,fn(n) = n * fn(n-1)

function fn(n){if(n === 1){return 1;}else{return n * fn(n-1);}
}
console.log(fn(10));

2.有一对幼兔,幼兔1个月后长成小兔,小兔1个月后长成成兔并生下一对幼兔,问8个月后有多少对兔子,幼兔、小兔、成兔对数分别是多少?
方法:循环或递归,此处用递归解决总数量
原因:当月成兔和幼兔的数量一样,成兔是上个月的小兔+上个月的成兔,幼兔是上个月的成兔+上个月的小兔,小兔是上个月的幼兔,可以抽象成fn(n) = fn(n-1) + fn(n-2),此时有两个条件fn(1) = 1;fn(2) = 1;

function fn(n){if(n === 1 || n === 2){return 1;}return fn(n-1) + fn(n-2);
}
console.log(fn(8));

3.编写一个函数,输入n为偶数时,调用函数求1/2+1/4+…+1/n,当输入n为奇数时,调用函数求1+1/3+…+1/n
方法一:递归
原因:先分两种情况,偶数和奇数.偶数:fn(6)=1/6+1/4+1/2可化为fn(n)=1/n+fn(n-2),此时有一个特殊情况即n=2时值为1/2,同理可得奇数

function fn(n) {if (n === 1) {return 1;} else if (n === 2) {return 1 / 2;}// 奇偶运算的都一样,可以用一个式子返回return 1 / n + fn(n - 2);
}
console.log(fn(4));

方法二:循环
原因:与上述原理相同

function fn(n) {var sum = 0;// 奇数if (n % 2) {// i的初始值和i += 2 区分奇偶for (var i = 1; i <= n; i += 2) {sum = sum + 1 / i;}} else {for (var i = 2; i <= n; i += 2) {sum = sum + 1 / i;}}return sum;
}
console.log(fn(4));

5.数组

本质操作:索引+长度

1.通过循环制造一个5 x 5的二维数组,这个数组中的数据是hello
方法:二维数组双层循环
原因:在循环外创建一个数组用来装通过外循环创建的数组来实现二维数组,数据填充在二维数组里,然后再新增到一维数组里

var arr1 = new Array();
for (var i = 0; i < 5; i++) {var arr2 = new Array();for (var j = 0; j < 5; j++) {arr2[j] = "hello";}arr1[i] = arr2;
}
console.log(arr1);

2.编写函数has(arr , n) 判断数组中是否存在n这个元素,返回布尔类型
方法:循环遍历+判断(注意返回值return会结束当前执行语句)
原因:先将数组的每一个数据循环遍历出来再与n比较,如果存在就返回true,不存在就返回false(注意return会结束当前语句,如果在循环里面return false则会结束当前循环)

function has(arr, data) {for (let i = 0; i < arr.length; i++) {if (arr[i] === data) {return true;}//不能else然后return false,这样做的话会结束当前执行语句也就是结束循环语句}return false;
}
var arr = [0, 1, 2, 3, 60];
console.log(has(arr, 60));

3.编写函数norepeat(arr) 将数组的重复元素去掉,并返回新的数组
方法:循环遍历+判断
原因:先新建一个数组,循环遍历原数组,如果原数组的数据在新数组中不存在,则最后新增到新数组

function norepeat(arr) {var arrNew = new Array();// 循环遍历原数组for (var i = 0; i < arr.length; i++) {// 判断原数组的数据在新数组中是否存在if (!(has(arrNew, arr[i]))) {// 最后新增数据放在新数组里// arrNew.push(arr[i]);arrNew[length++]=arr[i];}}return arrNew;
}
var arr = [1, 1, 1, 2, 3, 3, 4];
console.log(arr);
console.log(norepeat(arr));

4.有一个从小到大排好序的数组。现输入一个数,要求按原来的规律将它插入数组中
方法:循环遍历+判断+赋值覆盖
原因:将数组中的每一个元素与要插入的数比较,找到比要插入的数大的数的位置,从末尾开始往后一个赋值直到要插入的位置,最后将要插入的值赋值在到要插入的位置

function fn(arr, data) {// 寻找要插入的位置for (var i = 0; i < arr.length; i++) {if (arr[i] > data) {break;}}// 从要插入的位置往后赋值进行覆盖,i为要插入的位置for (var j = arr.length - 1; j >= i; j--) {arr[j + 1] = arr[j];}// 数据插入指定的位置arr[i] = data;
}
var arr = [1, 3, 4];
console.log(arr);
fn(arr, 2);
console.log(arr);

6.字符

1.敏感词过滤
方法:先有一个敏感词库,再处理接收到的字符
原因:通过遍历字符将字符中的所有敏感词替换成我们想要替换的字符

(function () {"use strict"
var worldsList = ["西巴", "啊啊", "坏人"];
var str = "真的西巴,不是啊啊啊,坏人一个西巴啊啊坏人";
console.log(str);
// 循环遍历这个字符中的所有数据
for (var i = 0; i < str.length; i++) {// forEach遍历这个数组中的数据worldsList.forEach(function (val) {str = str.replace(val, "**");})
}
console.log(str);
// 完整的敏感词过滤需要用到正则表达式来完善
// 见9.2正则
})();

2.统计每个字符(aabccd)出现的次数,结果显示{a:2, b:1, c:2, d:1},去掉重复的字符,使结果显示abcd
方法:用对象存储数据
原因:新建一个对象,遍历原数据把对象中不存在的字符放入对象中同时值设为1,如果存在字符重复的就让它本身+1,因为用的是对象这种数据类型,其键是没有重复的,所有将其键取出来就能实现去重的效果

(function () {"use strict"var str = "aabccd";var obj = {};console.log(str);for (var i = 0; i < str.length; i++) {// 字符转Boolean// 字符:非空为true// undefined,null,NaN,都是false// 如果obj这个对象中没有str中的数据则为undefinedif (obj[str[i]]) {// 存在,就增加1,表示又出现了一次obj[str[i]]++;} else {// 不存在,设置这个属性,同时值为1,表示第一次出现// js中对象的新增属性和数据可以直接通过赋值来增加obj[str[i]] = 1;}}console.log(obj);// 新建一个字符让其键拼接起来var obj2 = "";// 遍历对象拿到其键for (var j in obj) {obj2 += j;}console.log(obj2);
})();

7.随机数

1.生成随机的十六进制的颜色值
方法:随机数转十六进制
原因:做的时候存在当随机到小于16的数字时,转成16进制不为两位数,即15为f,但是要的结果为0f

(function () {"use strict"// 限定min-max范围的随机数function random(min, max) {return Math.round((Math.random()) * (max - min) + min);}// 方法1:考虑随机数的值var str = "";for (var i = 0; i < 3; i++) {var n = random(0, 255);if (n < 16) {n = "0" + n.toString(16);}str += n.toString(16);}console.log("#" + str);// 方法2:考虑随机数的转成16进制后的长度function createZero(data) {return data.length < 2 ? "0" + data : data;}function randomColor() {var r = random(0, 255).toString(16);var g = random(0, 255).toString(16);var b = random(0, 255).toString(16);return "#" + createZero(r) + createZero(g) + createZero(b);}console.log(randomColor());
})();

2.生成四位随机数字字母混合的验证码
方法:随机数作为ASCII码转成为数字或字母
原因:ASCII的范围97 ~ 122(a ~ z), 65 ~ 90 ( A ~ z ),48 ~ 57 ( 0 ~ 9 ),随机出包含数字和字母的一个字符库,再从这个字符库里面随机选出四个数

(function () {"use strict"// 限定min-max范围的随机数function random(min, max) {return Math.round((Math.random()) * (max - min) + min);}// 随机一个大于4位的且每种字符出现次数一致的随机字符库var str = "";for (var i = 0; i < 30; i++) {str += String.fromCharCode(random(97, 122));str += String.fromCharCode(random(65, 90));str += String.fromCharCode(random(48, 57));}console.log(str);// 从上面的随机字符库中,随机取4位var result = "";for (var j = 0; j < 4; j++) {// 每一次从str库中随机取出一个数拼接到新字符中result += str[random(0, str.length - 1)];}console.log(result);
})();

8.BOM&DOM

1.仿进度条
方法:计时器控制元素
原因: 先获取要操作的元素,然后用计时器让其宽增加,直到小于每一次增加的宽度,再强制将其宽度变成与父元素的宽度相同

html

<div class="box"><div class="working"></div></div>

css

.box {display: flex;width: 200px;height: 200px;margin: 0px auto;border: 1px solid black;justify-content: center;flex-direction: column;
}
.working {width: 0px;height: 10px;background-color: cadetblue;
}

js

// getElementsByClassName与ID获取的不一样,打印getElementsByClassName得到的是一个HTMLCollection,要用getElementsByClassName("working")[0]的形式。
// var working = document.getElementsByClassName("working")[0];var working = document.querySelector(".working");// 非行内只读
// getComputedStyle(working).width = parseInt(getComputedStyle(working).width) + 10 + "px";// console.log(working.style.width);
// 行内可设置
// working.style.width=parseInt(getComputedStyle(working).width) + 10 + "px";
// console.log(working.style.width);// 声明计时器
var t;
// 进度条目标宽度
var traget = 200;
// 每次增加的像素,也能理解为进度条的速度
var speed = 3;// 点击函数
document.onclick = function () {// 清除计时器,防止再次点击的时候又开启新的计时器clearInterval(t);// 开启计时器t = setInterval(doing, 30);
}// 进度条函数
function doing() {// 当前宽度var now = parseInt(getStyle(working, "width"));// 剩下的宽度小于每一次增加的宽度的时候就清除计时器并将目标宽度赋值给行内样式if (traget - now < speed) {clearInterval(t);working.style.width = traget + "px";} else {working.style.width = now + speed + "px";}
}// 兼容ie非行内样式获取
// 参数1:传入的选择器
// 参数2:要获取的样式
function getStyle(selector, someStyle) {return selector.currentStyle ? selector.currentStyle[someStyle] : getComputedStyle(selector)[someStyle];
}

2.仿选项卡
方法:点击事件+this绑定
原因:先获取导航和内容标签,再对其进行关联,因为不知道用户要点击哪一个,所以需要索引遍历到用户选中的区域再继续操作

html

<div class="box"><nav><ul><li style="background-color: brown;">1</li><li>2</li></ul></nav><div class="content"><div class="content-msg"><p>内容1</p></div><div class="content-msg" style="display: none;background-color: cadetblue;"><p>内容2</p></div></div></div>

css

* {margin: 0px;padding: 0px;
}.box {overflow: hidden;width: 500px;height: 500px;border: 1px solid black;margin: 0px auto;
}nav {width: 100%;height: 100px;background-color: #ccc;
}nav ul {display: flex;width: 100%;height: 100%;list-style: none;justify-content: space-around;
}nav ul>li {width: 100%;height: 100%;text-align: center;line-height: 100px;border: 1px solid black;box-sizing: border-box;color: white;
}.content {width: 100%;height: 400px;
}.content-msg {width: 100%;height: 400px;background-color: rgb(172, 206, 158);border: 1px solid black;
}

js

// 效果:默认选中1,内容1,切换到2的时候选中的背景颜色要变到2,1的背景颜色变成没有选中,内容也要变成2
var liList = document.querySelectorAll("nav ul>li");
var msgList = document.querySelectorAll(".content-msg");// 给选择器绑定自定义num属性,用来作为索引,当当前对象改变时其索引不改变
for (var i = 0; i < liList.length; i++) {liList[i].num = i;
}// 上一次点击的索引,默认值赋0
var pre = 0;// 遍历选中的元素
for (var i = 0; i < liList.length; i++) {liList[i].onclick = function () {// 当前选中的元素// console.log(this)// 点击时上一个变成默认样式liList[pre].style.background="none";// 当前选中元素变红this指向liList[i]this.style.background = "brown";// 点击时上一个内容变成隐藏msgList[pre].style.display="none";// 当前选中元素显示this指向msgList[i]msgList[this.num].style.display = "block";// 把当前点击的设置为上一个点击的pre=this.num;}
}

3.校验密码强度(只考虑组成类型)
方法:字符串遍历比较
原因:获取输入框中的内容,然后逐位判断,如果有数字/字符串/特殊字符其中一个则为弱,并将结果输出到页面,有两个为中,都要为强

html

<input type="text" id="txt"><span></span>

js

var msg = document.getElementById("txt");
var result = document.querySelector("span");// 如何获取到输入框中的内容
msg.oninput = function () {// console.log(msg.value);// 定义初始变量为0,如果出现一种则为1,这个变量不能是全局变量,如果是全局变量则修改值的时候变量不为初始值var a = 0;var b = 0;var c = 0;for (var i = 0; i < msg.value.length; i++) {// 这里逐位判断字符串用了隐式类型转换,所以能直接判断,比较字母是比较的是ASCII码if (msg.value[i] >= 0 && msg.value[i] <= 9) {// console.log("数字");a = 1;}if ((msg.value[i] >= 'a' && msg.value[i] <= 'z') || (msg.value[i] >= 'A' && msg.value[i] <= 'Z')) {// console.log("字母");b = 1;}if (!((msg.value[i] >= 0 && msg.value[i] <= 9) || (msg.value[i] >= 'a' && msg.value[i] <= 'z') || (msg.value[i] >= 'A' && msg.value[i] <= 'Z'))) {// console.log("特殊字符");c = 1;}}switch (a + b + c) {case 1: {result.innerHTML = "弱";break;}case 2: {result.innerHTML = "中";break;}case 3: {result.innerHTML = "强";break;}default: {result.innerHTML = "";}}}

4.仿聊天框
方法:点击事件,键盘事件
原因:可以通过点击按钮执行函数,也能通过键盘触发函数

html

<div class="box"><div class="msg"></div><div class="form"><textarea id="txt"></textarea><input type="button" id="btn" value="发送"></div>
</div>

css

.box {width: 300px;height: 400px;border: solid 1px black;margin: 0 auto;
}
.box .msg {height: 300px;border-bottom: solid 1px black;overflow: auto;
}
.msg div {padding: 6px;border-radius: 6px;margin: 6px;max-width: 200px;clear: both;
}
.msg div:nth-child(2n) {background: #99f;float: left;
}
.msg div:nth-child(2n-1) {background: #6f6;float: right
}

js

// 获取要插入的区域
var msg = document.querySelector(".msg");
// 获取发送按钮
var btn = document.querySelector("#btn");// 点击时发送
btn.onclick = function () {sent();
}// 键盘回车时发送
document.onkeydown = function (key) {// 获取事件对象兼容var key = key || window.event;// 获取事件对象键码兼容var keycode = key.keyCode || key.witch;// 只用回车发送,不加组合键就有第一次发送后第二次发送空字符的bug,因为回车执行了发送函数,再回车if (keycode == 13 && key.ctrlKey) {sent();}}// 发送消息的方法
function sent() {// 获取文本域var text = document.querySelector("#txt");// 文本域内容为空就结束这个函数if (text.value === "") {return;}// 新创建一个元素,将文本内容放在里面再插入到msg里var data = document.createElement("div");data.innerHTML = text.value;msg.appendChild(data);// 最后清空元素text.value = "";// 显示当前对话框,出现滚动条时可视区域始终为显示框底部即滚动条滚动的距离为页面总高度msg.scrollTop = msg.scrollHeight;
}

5.自定义下拉列表
方法:点击事件,鼠标移动事件,自定义对象索引
原因:点击显示框出现下拉列表,选则下拉列表的元素后下拉列表隐藏,把选中的元素填入到显示框

html

<div class="box"><span></span><ul class="list"><li>北京</li><li>上海</li><li>广州</li><li>深圳</li><li>杭州</li></ul>
</div>

css

.box {width: 300px;height: 40px;line-height: 40px;margin: 0 auto;text-indent: 4px;
}
.box span {display: block;width: 300px;height: 40px;border: solid 1px black;cursor: pointer
}
.box ul {margin: 0;padding: 0;list-style: none;border: solid 1px black;border-top: none;width: 300px;text-indent: 8px;display: none;
}
.box ul li.hover {background: #66f;color: #fff
}

js

var ospan = document.querySelector(".box span");
var oul = document.querySelector(".list");
var ali = oul.children;// 记录下拉菜单的显示状态:0表示要显示,1表示要隐藏
var flag = 0;
// 默认选中的索引
var index = 0;
// 设置默认项
setDefault();function setDefault() {// 根据索引,设置要显示的内容ospan.innerHTML = ali[index].innerHTML;// 及选中的状态var em = document.createElement("em");em.innerHTML = "√";ali[index].appendChild(em);
}for (var i = 0; i < ali.length; i++) {// 提前给每个li添加索引// 方便修改每次选中ali[i].index = i;// 鼠标进入,显示样式ali[i].onmouseover = function () {this.className = "hover";}// 鼠标离开,隐藏样式ali[i].onmouseout = function () {this.className = "";}// 点击ali[i].onclick = function () {// 先取消默认选中ali[index].lastElementChild.remove();// 修改默认索引,为点击的元素的索引// this.index的index为ali[i].index = i中的indexindex = this.index;// 修改默认项setDefault()// 隐藏下拉菜单oul.style.display = "none";// 同时更新下拉菜单的状态flag = 0;}
}ospan.onclick = function (eve) {var e = eve || window.event;// 阻止span的事件冒泡stopBubble(e);// 判断状态,决定下拉菜单的显示或隐藏,同时更新状态if (flag === 0) {oul.style.display = "block";flag = 1;} else {oul.style.display = "none";flag = 0;}
}// 点击空白隐藏,有事件冒泡的影响
document.onclick = function () {oul.style.display = "none";flag = 0;
}// 阻止冒泡的兼容
function stopBubble(e) {if (e.stopPropagation) {e.stopPropagation()} else {e.cancelBubble = true;}
}

6.阻止用户复制页面上的文字
方法:禁用默认事件
原因:默认事件是默认存在的,禁用默认事件就只能触发自己写的事件

html

<p>wefwef</p>

js

// 阻止用户复制页面上的文字
// 复制的方式有:
// 选中:
//     1.快捷键复制;
//     2.右键复制
//     3.左键拖拽复制
// 不能选中:
// 控制台复制// 阻止默认事件的兼容
function stopeDefault(e) {if (e.preventDefault) {e.preventDefault();} else {e.returnValue = false;}
}// 禁用ctrl+c(键码67)快捷键
document.onkeydown = function (eve) {// 事件对象的兼容var e = eve || window.event;// 键码的兼容var code = e.keyCode || which;if (code == 67 && e.ctrlKey) {stopeDefault(e);console.log("不能通过ctrl+c复制");}// 禁用控制台if(code==123){stopeDefault(e);console.log("不能通过控制台复制");}}// 禁用右键
document.oncontextmenu = function (eve) {var e = eve || window.event;stopeDefault(e);
}// 禁用拖拽
document.onmousemove = function (eve) {var e = eve || window.event;stopeDefault(e);
}

7.跟着鼠标移动的元素
方法:鼠标移动事件+获取坐标
原因:一般的思路是将鼠标的坐标值给第一个元素的left和top,再从后面遍历

html

<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>

css

div {position: absolute;width: 20px;height: 20px;text-align: center;color: white;line-height: 20px;background-color: cadetblue;left: 0px;top: 0px;
}

js

// 一连串跟随鼠标移动的元素
var oMove = document.querySelectorAll("div");// 鼠标移动的时候通过遍历来让其出现
document.onmousemove = function (eve) {var e = eve || window.event;// 第一个要获取鼠标的页面坐标oMove[0].style.left = e.pageX + "px";oMove[0].style.top = e.pageY + "px";// 从最后开始,当前的位置值为上一个的位置值for (var i = oMove.length - 1; i > 0; i--) {oMove[i].style.left = oMove[i - 1].offsetLeft + "px";oMove[i].style.top = oMove[i - 1].offsetTop + "px";}
}

8.元素拖拽
方法:鼠标事件和网页窗口尺寸
原因:鼠标按下的时候就是拖拽

html

<div></div>

css

div {position: absolute;width: 100px;height: 100px;background-color: cornflowerblue;left: 0px;top: 0px;
}

js

// 拖拽效果
var oMove = document.querySelector("div");// 获取页面宽高,防止移动超过页面右下
var maxW = document.documentElement.clientWidth;
var maxH = document.documentElement.clientHeight;// 鼠标按下的同时移动就是拖拽
oMove.onmousedown = function (eve) {div = eve || window.event;// 移动的时候获取鼠标的位置再给元素document.onmousemove = function (eve) {var indexDiv = eve || window.event;// 元素移动的数值应该是相对于页面的坐标-鼠标与选中元素之间的距离var l = indexDiv.pageX - div.offsetX;var r = indexDiv.pageY - div.offsetY;// 处理左上超出范围的问题if (l <= 0) {l = 0;}if (r <= 0) {r = 0;}// 处理右下超出范围的问题,offsetWidth是选中块的宽高if (l > maxW - oMove.offsetWidth) {l = maxW - oMove.offsetWidth;}if (r > maxH - oMove.offsetHeight) {r = maxH - oMove.offsetHeight;}oMove.style.left = l + "px";oMove.style.top = r + "px";}// 鼠标抬起必须清除鼠标移动// 这里对象为document是为了超出指定区域外也能结束鼠标移动document.onmouseup = function () {document.onmousemove = null;document.onmouseup = null;}}

9.随着鼠标移动的提示框
方法:鼠标移动事件+坐标
原因:显示框与鼠标的距离,在结构中插入一个空元素,借助这个空元素对上下节点进行操作

html

<div class="box"><div class="news"><h2>新闻1的标题</h2><span></span><p>这是新闻1 的内容区域</p></div><div class="news"><h2>新闻2的标题</h2><span></span><p>这是新闻2的内容</p></div>
</div>

css

.box {width: 500px;border: solid 1px black;margin: 0 auto;
}
.box .news {height: 80px;margin: 10px 0;background: #ccc;position: relative;
}
.news h2 {margin: 0;line-height: 80px;
}
.news p {position: absolute;margin: 0;width: 300px;background: #efefef;left: 0;top: 0;z-index: 1;display: none;
}
.news span {width: 500px;height: 80px;position: absolute;left: 0;top: 0;z-index: 2;
}

js

var ah2 = document.querySelector(".box").querySelectorAll("span");for (var i = 0; i < ah2.length; i++) {ah2[i].onmouseover = function () {this.nextElementSibling.style.display = "block";}ah2[i].onmouseout = function () {this.nextElementSibling.style.display = "none";}ah2[i].onmousemove = function (eve) {var e = eve || window.event;// 这个也能用// this.nextElementSibling.style.left = e.offsetX + "px";// this.nextElementSibling.style.top = e.offsetY + "px";this.nextElementSibling.style.left = e.pageX - this.parentNode.offsetLeft + "px";this.nextElementSibling.style.top = e.pageY - this.parentNode.offsetTop + "px";}
}

9.正则

1.表单验证
方法:用正则对各种数据进行格式的校验
原因:通过正则能够筛选出符合规则的数据

html

<div class="box">用户名:<input type="text" id="userName"><span></span>密码:<input type="text" id="passWord1"><span></span>重复密码:<input type="text" id="passWord2"><span></span>手机号:<input type="text" id="tel"><span></span>邮箱:<input type="text" id="email"><span></span><input type="submit" id="submit"><span></span>
</div>

css

.box {display: flex;width: 500px;height: 500px;border: 1px solid black;margin: 0 auto;flex-direction: column;justify-content: space-evenly;
}
span {color: red;
}

js

// 1. 用户名 用户名仅支持中文、 字母、 数字、“ - ”“_” 的组合, 4 - 20 个字符
// 2. 密码的规则 数字字母特殊字符, 一种类型, 弱。 两种类型为中, 三种类型为强
// 3. 重复密码 跟第一次输入 密码一致
// 4. 手机号的验证 第一位必须为1, 后面再加10位数字
// 5. 邮箱 数字大小写字母_ - 3 到12位 @ 数字字母 2 到9位.字母2到5位
// 6. 提交按钮的时候, 判断所有输入数据是否符合。 符合跳转, 否, 不跳// 判断每个输入框是否输入正确的初始值
var btn1 = 0;
var btn2 = 0;
var btn3 = 0;
var btn4 = 0;
var btn5 = 0;// 用户名
var userName = document.getElementById("userName");
var span1 = userName.nextElementSibling;
var regName = /^[\u2E80-\u9FFF\w-]{4,20}$/;
userName.oninput = function () {if (regName.test(this.value)) {span1.innerHTML = "√";btn1 = 1;} else {span1.innerHTML = "×";btn1 = 0;}
}// 密码
var passWord1 = document.getElementById("passWord1");
var span2 = passWord1.nextElementSibling;
var regpassWord1A = /[0-9]/; // 数字
var regpassWord1B = /[a-z]/; // 字母
var regpassWord1C = /\W|_/; // 特殊字符
passWord1.oninput = function () {var A = 0;var B = 0;var C = 0;if (regpassWord1A.test(this.value)) {A = 1;}if (regpassWord1B.test(this.value)) {B = 1;}if (regpassWord1C.test(this.value)) {C = 1;}switch (A + B + C) {case 1: {span2.innerHTML = "差";btn2 = 1;break;}case 2: {span2.innerHTML = "中";btn2 = 1;break;}case 3: {span2.innerHTML = "强";btn2 = 1;break;}default: {span2.innerHTML = "";btn2 = 0;break;}}// 输入密码和重复密码后又修改密码if (passWord2.value !== "") {if (this.value !== passWord2.value) {passWord2.nextElementSibling.innerHTML = "×";btn3 = 0;} else {passWord2.nextElementSibling.innerHTML = "√";btn3 = 1;}}
}// 重复密码
var passWord2 = document.getElementById("passWord2");
// 验证输入的重复密码是否与原密码相同
passWord2.oninput = function () {if (this.value === passWord1.value) {passWord2.nextElementSibling.innerHTML = "√";btn3 = 1;} else {passWord2.nextElementSibling.innerHTML = "×";btn3 = 0;}if (this.value === "") {passWord2.nextElementSibling.innerHTML = "请输入密码";}
}// 手机号
var tel = document.getElementById("tel");
var regTel = /^1\d{10}$/;tel.oninput = function () {if (regTel.test(tel.value)) {tel.nextElementSibling.innerHTML = "√";btn4 = 1;} else {tel.nextElementSibling.innerHTML = "×";btn4 = 0;}
}// 邮箱
var email = document.getElementById("email");
var regEmail = /^\w{3,12}@[\da-zA-z]{2,9}\.[a-zA-Z]{2,5}$/;email.oninput = function () {if (regEmail.test(email.value)) {email.nextElementSibling.innerHTML = "√";btn5 = 1;} else {email.nextElementSibling.innerHTML = "×";btn5 = 0;}
}// 提交按钮
// 但每一个输入框输入正确的时候标记1,默认标记0,当标记值为5时候触发跳转
var bottom = document.getElementById("submit");bottom.onclick = function () {var result = btn1 + btn2 + btn3 + btn4 + btn5;// 提交时定位用户名输入规范if (btn1 === 0) {span1.innerHTML = "请按照规范输入";}// 提交时定位密码输入规范if (btn2 === 0) {span2.innerHTML = "请按照规范输入";}// 提交时定位重复密码输入规范if (btn3 === 0) {passWord2.nextElementSibling.innerHTML = "请按照规范输入";}// 提交时定位手机号输入规范if (btn4 === 0) {tel.nextElementSibling.innerHTML = "请按照规范输入";}// 提交时定位邮箱输入规范if (btn5 === 0) {email.nextElementSibling.innerHTML = "请按照规范输入";}// 全部输入规范if (result === 5) {bottom.nextElementSibling.innerHTML = "√";} else {bottom.nextElementSibling.innerHTML = "×";}}

2.敏感词过滤
方法:new方式创建正则
原因:通过敏感词库遍历原数据达到完全过滤的效果

// 用正则通过内容检索将替换敏感词库中的内容替换成自定义内容var badList = ["西巴", "死杂种", "滚蛋"];var str = "你个死杂种去死吧,西巴啊你,滚蛋吧西巴西巴aaa死杂种西巴";// let reg = /西巴/g;
// var result = str.replace(reg, "**");
// console.log(result);// 正则的new创建方式可以表示变量
// new的RegExp的第一个参数是变量,第二个参数是修饰符
for (let i = 0; i < badList.length; i++) {// 使用()表示一个值let reg = new RegExp("(" + badList[i] + ")+", "g");// 每一次替换都是在原基础上替换str = str.replace(reg, "**");console.log(str);
}
console.log(str);

持续更新中(2021/09/06)

JavaScript基础题目(附答案)相关推荐

  1. 慕课乐学python编程题_中国大学MOOC的APP(慕课)2020Python编程基础题目及答案

    中国大学MOOC的APP(慕课)2020Python编程基础题目及答案 更多相关问题 以下哪种细胞类型不是病毒性结膜炎的细胞学特点() 企业在处理非均匀需求过程中,通过那种策略来调整能力满足市场需求的 ...

  2. 计算机office基础知识的试题,office计算机基础知识(附答案).doc

    office计算机基础知识(附答案).doc 试题训练1)根据汉字国标GB2312-80的规定,二级次常用汉字个数是? ? A) 3000个? ? B)7445个? ? C)3008个? ? D)37 ...

  3. python大学编程考试题及答案_大学慕课2020年Python编程基础题目及答案

    大学慕课2020年Python编程基础题目及答案 更多相关问题 [判断题]任意两个关系都能进行交运算. A. 正确 B. 错误 [多选题]科学的对待死亡的态度包括 A. 珍惜生命,正视死亡 B. 树立 ...

  4. 计算机归属应用软件的有,2017大学计算机应用基础试题附答案

    2017大学计算机应用基础试题附答案 计算机应用技术专业培养,能够用所学专业知识解决专业相关实际问题,培养适应计算机技术在企事业单位中发展.应用需要的人才.下面是小编整理的关于计算机应用基础试题附答案 ...

  5. 计算机基础知识一级考试题库,office一级考试选择题计算机基础知识(附答案)

    office一级考试选择题计算机基础知识(附答案) 全真试题训练 1)根据汉字国标GB2312-80的规定,二级次常用汉字个数是 A) 3000个 B)7445个 C)3008个 D)3755个 2) ...

  6. php面试题汇总一(基础篇附答案)

    一份不错的php面试题,附答案,有准备换工作的同学可以参考一下. 1:使用五种以上方式获取一个文件的扩展名 要求:dir/upload.image.jpg,找出 .jpg 或者 jpg , 必须使用P ...

  7. 计算机应用基础选择题100道,300道计算机应用基础试题(附答案)

    计算机应用基础试题及答案 (注: 200道选择,100道填空) 一.选择题: 1. 在计算机应用中,"计算机辅助设计"的英文缩写为___________. A. CAD B. CA ...

  8. 中央电大网考计算机基础试题,电大网考300道计算机应用基础试题(附答案)

    计算机应用基础试题及答案 (注: 200道选择,100道填空) 一.选择题: 1. 在计算机应用中,"计算机辅助设计"的英文缩写为___________. A. CAD B. CA ...

  9. 【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案

    三.JavaScript部分 1.谈谈你对Ajax的理解?(概念.特点.作用) AJAX全称为"Asynchronous JavaScript And XML"(异步JavaScr ...

最新文章

  1. IIS出现server application error,请问怎么解决?
  2. iOS功能-统计平均下班时间
  3. IOS-React-Native:No bundle URL present
  4. Visual Studio 2008 快捷键大全
  5. public 函数_Chapter18:友元函数和友元类
  6. 64位系统安装ODBC驱动的方法
  7. php字符串转换mysql_在PHP中将字符串转换为MySQL时间戳格式
  8. An internal error occurred during: Launching ****
  9. hdu - 4647 - Another Graph Game
  10. matlab势场动态栅格路径规划,融栅格法和人工势场法的机器人三维路径规划
  11. 计算机五笔教案ppt,计算机应用基础课件(五笔字型课件).ppt
  12. sd卡数据恢复源码android,SD卡数据恢复非常简单,想学的看过来!
  13. Redis大Key优化
  14. 造轮子之后台管理模板
  15. 笔记本 触摸板无法使用 解决办法
  16. java之Map集合总结
  17. 12. 橡皮擦技术博客写作课,第一版收尾篇,写作也要懂点心理学
  18. 网络编程-线程,守护线程,线程互斥锁-26
  19. Vue3 composition-apisetup 生命周期
  20. 新手必须掌握的20个摄影构图法 转

热门文章

  1. 创建一个mysql组
  2. 精美Bootstrap二手物品交易市场模板Html
  3. Mysql_基本操作命令
  4. GBT 19668 (1-6)整套
  5. lowlevel_init 函数分析
  6. Java实现 LeetCode 754 到达终点数字(暴力+反向)
  7. 贪心算法解决找零钱问题
  8. 在hexo的butterfly主题中开启看板娘配置
  9. 如何使用Selenium自动化测试工具获取动态图片验证码?
  10. CSRF——跨站请求伪造攻击