按键事件
onkeydown 按键被按下
onkeyup 按键松开
onkeypress 按下并松开
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
function show(e) {
//e为事件对象,在事件对象里面会有属性
var code = e.keyCode; //当按下某个键时,通过事件对象(这个键)e,再获取键码e.keycde
if (code == 119) {
console.log("前进")
} else if (code == 97) {
console.log("往左")
}else if (code ==13) {
var content=document.getElementById("s").value;
console.log("搜索:"+content)//当按键码为13时控制台监控输入的内容
} else {
console.log("其他")
}
//alert("按下并松开了"+code);
}
</script>
</head>
<body>
<!-- event 事件对象,由浏览器创建 -->
<input type="text" id="s" value="" onkeypress="show(event)" />
</body>
</html>
鼠标事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
width: 200px;
height: 200px;
background: red;
}
</style>
</head>
<body>
<!-- this 表示绑定了该事件的元素对象 此处的this为div-->
<div id="d1" onmousedown="anxia(event,this)" onmouseup="songkai(this)" onmouseover="yishang(this)" onmouseout="yichu(this)" onmousemove="show()">
</div>
</body>
</html>
<script type="text/javascript">
function anxia(e,obj) {
//var obj= document.getElementById("d1");
obj.style.background = "yellow";
//可以根据事件对象里面的属性,来获取用户按得是鼠标的哪个键 0 1 2
var code=e.button;
alert(code);
if(code==0){
}else if(code==1){
}else{
}
}
function songkai(obj) {
obj.style.background = "pink";
}
function yishang(obj) {
obj.style.background = "blue";
}
function yichu(obj) {
obj.style.background = "green";
}
var i=1;
function show(){
console.log(i++);
}
</script>
表单事件
检查输入格式是否规范
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- onsubmit 表单提交事件
return tijiao() :返回true 表单项中的内容就会提交给后台。
return tijiao() :返回false 表单项中的内容不会提交后台。
-->
<form action="#" method="get" onsubmit="return tijiao()">
//监控输入框的内容 触发checkUsername()的事件 满足正则就在span中显示正确否则显示错误
<input type="text" name="username" id="uname" value="" oninput="checkUsername()"/>
<span id="usp"></span>
<br>
<input type="submit" value="提交" />
</form>
</body>
</html>
<script type="text/javascript">
function tijiao() {
alert("表单提交");
return true;
}
function checkUsername() {
var v = document.getElementById("uname").value;
// 注意加上^ 和 $
var regx = /^[a-z]{6,16}$/i;
var f = regx.test(v);
var sp = document.getElementById("usp");
if (f) {
sp.innerHTML = "<span style='color: green;'>规则正确</span>"
} else {
sp.innerHTML = "<span style='color:orangered;'>规则错误</span>"
}
//console.log("一输入我就触发");
}
</script>
其他事件
此处需要注意的是顺序问题 button在script下面 会出错
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
//onload 页面加载完成的事件
window.onload = function() {
var btn = document.getElementsByTagName("button")[0];
alert(btn);
}
</script>
</head>
<body>
<button type="button">一个按钮</button>
</body>
</html>
<!-- <script type="text/javascript">
//onload 页面加载完成的事件
var btn = document.getElementsByTagName("button")[0];
alert(btn);
</script> -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input type="text" id="" value="asdfasdfasdfsf" onselect="test()" />
<select name="shuiguo" onchange="show()">
<option value="">选择水果</option>
<option value="pg">苹果</option>
<option value="pt">葡萄</option>
<option value="xj">香蕉</option>
<option value="tz">桃子</option>
</select>
<input type="radio" name="sex" id="" value="1" onchange="show1()"/>男
<input type="radio" name="sex" id="" value="0" onchange="show2()"/>女
<input type="checkbox" name="hobby" id="" value="yy" onchange="show3()"/>音乐
</body>
</html>
<script type="text/javascript">
function show(){
alert("你选择了一项下拉项")
}
function show1(){
alert("你选择了一项")
}
function show2(){
alert("你选择了一项")
}
function show3(){
alert("你选择了一项复选框")
}
function test(){
alert("选中了文本")
}
</script>
事件对象的属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#wai{
margin-top: 100px;
height: 200px;
width: 200px;
background: yellow;
}
</style>
</head>
<body>
<!-- event 事件对象。 -->
<button type="button" id="btn" onclick="show(event,this)">一个按钮</button>
<div id="wai" onclick="test(event)">
<button type="button">里面的按钮</button>
</div>
</body>
</html>
<script type="text/javascript">
function show(e,obj) {
//事件对象中的属性:type 获取事件类型
//currentTarget 返回其事件监听器触发该事件的元素。
//target 返回触发此事件的元素(事件的目标节点)。
//alert(e.type);
//document.getElementById("btn").style.background="red";
//obj.style.background="red";
//从事件对象中能够获取绑定了事件的元素对象。
//e.target.style.background="red";
e.currentTarget.style.background="red";
}
function test(e){
// 事件对象中 两个属性的区别: target 和 currentTarget
//target 获取的是触发了该事件的元素。
//currentTarget 获取的是绑定了该事件的元素对象。
var obj=e.currentTarget; //div绑定 button没有绑定
alert(obj);
}
</script>
事件冒泡
div嵌套时,onclick事件会从内到外执行
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#one{
width: 300px;
height: 300px;
background: yellow;
}
#two{
width: 200px;
height: 200px;
background: red;
}
#three{
width: 100px;
height: 100px;
background:green;
}
</style>
</head>
<body>
<div id="one" onclick="show1(event)">
1
<div id="two" onclick="show2(event)">
2
<div id="three" onclick="show3(event)">3</div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
function show1(e){
//stopPropagation() 阻止事件的冒泡行为
e.stopPropagation();
alert(11111)
}
function show2(e){
e.stopPropagation();
alert(22222)
}
function show3(e){
e.stopPropagation();
alert(3333)
}
</script>
阻止元素默认行为
例如a标签会在点击之后跳转页面,如何阻止跳转行为呢?
事件对象中,有方法可以阻止元素的默认行为:e.preventDefault();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- a 标签有个默认行为就是 跳转页面 -->
<a href="http://www.baidu.com">进入百度</a>
<!-- a 我们只想让a标签可以点击,但是不跳页面 -->
<a href="#">进入百度</a>
<!-- a 我们只想让a标签可以点击,但是不跳页面 -->
<a href="javascript:void(0)">进入百度</a>
<!-- a 我们只想让a标签可以点击,可以调用一个函数,但是不跳页面 -->
<a href="javascript:void(show())">进入百度</a>
<!-- 通过事件对象 来阻止元素默认跳转页面的行为 -->
<a href="http://www.baidu.com" onclick="show2(event)">进入百度</a>
<form action="123.html" method="post" onsubmit="tijiao(event)">
<input type="text" id="" name="username" value="" />
<input type="submit" value="提交"/>
</form>
</body>
</html>
<script type="text/javascript">
function show() {
alert("谈了");
}
function show2(e) {
//事件对象中,有方法可以阻止元素的默认行为
//preventDefault()阻止元素的默认行为
e.preventDefault();
alert("谈了222");
}
function tijiao(e){
e.preventDefault(); //阻止表单同步提交的行为
alert("提交表单,我要异步提交");
}
</script>
节点的操作(忽略文本和注释)
parentElement 获取当前元素的父元素对象(不会获取到空文本,或者注释)
firstElementChild 获取父元素的第一个标签对象(不会获取到空文本,或者注释)
lastElementChild 获取父亲元素的最后一个标签对象(不会获取到空文本,或者注释)
previousElementSibling; 获取上一个兄弟元素对象(不会获取到空文本,或者注释)
nextElementSibling 获取下一个兄弟元素对象(不会获取到空文本,或者注释)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!--注释 -->
<div id="">
<div id="">
<button type="button">一个按钮</button>
</div>
</div>
<h1>asdfasdf</h1>
</body>
<script type="text/javascript">
var obj=document.body.firstElementChild.firstElementChild.firstElementChild;
alert(obj);
var h=document.body.firstElementChild.nextElementSibling;
alert(h);
h.style.color="red";
</script>
</html>
省市三级联动
选择一个省份就有对应的城市,事件应绑定在省份下拉标签处。
思路:
- onchange事件绑定下拉标签,select标签中onchange事件只要用户选择的选项一发生改变,selectedIndex 就返回下拉列表中被选项目的索引号,使得后台知道用户选择的省份 ;
- 省份所对应的城市使用二维数组来存储,根据下拉列表中被选项目的索引号来获取省份对应的城市;
- 建立省份与城市的联动时,先清空城市的下拉列表,获取用户选择的下拉项编号,通过编号取出这个省份所对应的所有的城市的数组。遍历城市的数组,把他展示到第二个下拉框里面去。
城市与区域的联动同理。需要注意的是下拉列表中的被选项目的索引号每一次都是从1、2、3开始,因此当选择第一个省份后选择的城市索引号与选择第二个省份后选择的城市索引号相同,如果这两个省份的所有城市的区域都写在同一个数组中,只会重复遍历下拉列表索引号1、2、3,而不会向后遍历数组。解决方案是将各个省份的城市区域写成一个数组,再进行判断省份的索引号,根据省份的索引号不同,就遍历不同的区域数组。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<select name="s" onchange="selectSheng()" id="sf">
<option value="">--请选择省份--</option>
<option value="">陕西</option>
<option value="">河南</option>
</select>
<select name="c" id="city" onchange="selectCity()">
<option value=''>--请选择城市--</option>
</select>
<select name="a" id="area">
<option value=''>--请选择区--</option>
</select>
</body>
</html>
<script type="text/javascript">
//0.绑定下拉事件
//1,得知道用户选择了哪个省份
var sheng = document.getElementById("sf");
var city = document.getElementById("city");
var area=document.getElementById('area');
//省份所对应的城市,怎么来设计这个数据。
var arr = [
[],
['西安', '咸阳', '宝鸡'],
['郑州', '安阳', '开封']
];
//城市对应的区域 数据
var arr1 = [
[],
['长安区', '碑林区', '雁塔区', '莲湖区'],
['秦都区', '杨凌区', '渭城区', '三原县'],
['渭滨区', '金台区', '陈仓区', '凤翔县'],
];
var arr2 = [
[],
['中原区', '二七区', '管城回族区', '金水区'],
['文峰区', '北关区', '殷都区', '龙安区'],
['龙亭区', '顺河回族区', '鼓楼区', '禹王台区', '祥符区']
];
function selectSheng() {
//选择的时候,先清空城市下拉列表的旧元素
city.innerHTML="<option value=''>--请选择城市--</option>";
//city.length=1;
//alert("选择了省份");
//selectedIndex 设置或返回下拉列表中被选项目的索引号。
// alert(sheng.selectedIndex);
//获取用户选择的下拉项编号。
var index = sheng.selectedIndex;
//通过编号取出这个省份,所对应的所有的城市的数组。
var citys = arr[index];
//遍历城市的数组,把他展示到第二个下拉框里面去。
for (let i = 0; i < citys.length; i++) {
//创建option标签
var option = document.createElement("option");
//给option标签之间设置文本。
//option.innerText=citys[i];
//创建文本节点
var text = document.createTextNode(citys[i]);
//给父元素添加子元素。
option.appendChild(text);
//给select标签添加子元素
city.appendChild(option);
}
}
//1.作业:做一个省市区 三级联动
function selectCity(){
//判断选择的省份是那个
var index = sheng.selectedIndex;
//选择的时候,先清空区域下拉列表的旧元素
area.length=1;
//判断选定的城市是那个
var indexx=city.selectedIndex;
//先确定选择的省份index,然后根据indexx确定城市,再遍历城市包含的区镇,
if(index==1){
var quArr = arr1[indexx];
for (var i = 0; i < quArr.length; i++) {
var option = document.createElement("option");
var quName = document.createTextNode(quArr[i]);
option.appendChild(quName);
area.appendChild(option);
}
}else if(index==2){
quArr=arr2[indexx];
for (var i = 0; i < quArr.length; i++) {
var option = document.createElement("option");
var quName = document.createTextNode(quArr[i]);
option.appendChild(quName);
area.appendChild(option);
}
}
}
</script>
轮播图
思想:id为show的div盒子放一张照片,在show的div中包含id为content的div的放入四张照片(四个div)用于轮播,因此content的盒子大小是show这个盒子的四倍,show在超出的部分使用overflow:hidden
,content的盒子中使用循环定时器不断改变margin-left(左边距离)的值就可以进行轮播。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#show {
width: 230px;
height: 320px;
border: 1px solid black;
overflow: hidden;
}
#content {
width: 920px;
height: 320px;
transition: margin-left 1s;
}
#d1 {
width: 230px;
height: 320px;
background-image: url(img/main02_centent_01.png);
float: left;
}
#d2 {
width: 230px;
height: 320px;
background-image: url(img/main02_centent_02.png);
float: left;
}
#d3 {
width: 230px;
height: 320px;
background-image: url(img/main02_centent_03.png);
float: left;
}
#d4 {
width: 230px;
height: 320px;
background-image: url(img/main02_centent_04.png);
float: left;
}
#dots {
position: absolute;
width: 230px;
margin-top: 300px;
margin-left: auto;
/* border: 1px black solid; */
display: flex;
justify-content:center;
}
.dot {
width: 14px;
height: 14px;
border: 1px black solid;
border-radius: 7px;
float: left;
margin-left: 10px;
font-size: 10px;
color: white;
background: grey;
text-align: center;
}
.dot:hover{
cursor: pointer;
}
</style>
</head>
<body>
<div id="show" onmouseover="stop()" onmouseout="start()" >
<div id="dots" >
<div id="dot1" class="dot" onclick="turnPicture1()" >1</div>
<div id="dot2" class="dot" onclick="turnPicture2()" >2</div>
<div id="dot3" class="dot" onclick="turnPicture3()" >3</div>
<div id="dot4" class="dot" onclick="turnPicture4()" >4</div>
</div>
<div id="content">
<div id="d1">
</div>
<div id="d2">
</div>
<div id="d3">
</div>
<div id="d4">
</div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
var content = document.getElementById("content");
//获取所有的小圆点
var dots=document.getElementsByClassName("dot");
//一进来我们让第一个小圆点选中。
dots[0].style.background="red";
var count = 0;
var timeID=0;
function scroll() {
count++;
if (count >= 4) {
count = 0;
}
//把之前变过的颜色,在设置为灰色
clearColor();
//滚到哪一张,把他对应的指示器背景颜色设置为红色
dots[count].style.background="red";
content.style.marginLeft = (-1 * count * 230) + "px";
}
//scroll();
//循环定时器
timeID=setInterval(scroll, 2000);
//鼠标移上停止滚动
function stop(){
//清除定时器
clearInterval(timeID);
}
//鼠标移出恢复滚动
function start(){
timeID=setInterval(scroll, 2000);
}
//轮播时,让小圆点颜色,和图片对应上。
function clearColor(){
for(let i=0;i<dots.length;i++){
dots[i].style.background="grey";
}
}
//作业:给每个小圆点,添加点击事件,点哪个小圆点,就跳到他所对应的图片
function turnPicture1(){
clearColor();
dots[0].style.background="red";
content.style.marginLeft = (-1 *0 * 230) + "px";
}
function turnPicture2(){
clearColor();
dots[1].style.background="red";
content.style.marginLeft = (-1 *1 * 230) + "px";
}
function turnPicture3(){
clearColor();
dots[2].style.background="red";
content.style.marginLeft = (-1 *2 * 230) + "px";
}
function turnPicture4(){
clearColor();
dots[3].style.background="red";
content.style.marginLeft = (-1 *3 * 230) + "px";
}
</script>
简易计算器
1.我们数字和小数点归为一类
2.把操作符规范为一类
3.其他按键,单独设置id
4.获取用户点击的数字,展示到显示框上 ,动态给数字的td标签添加点击事件
5.定义 三个变量 来存储第一个数,第二个数 以及运算符
6.归零:存储数字的三个变量全部清空,显示框的value为0
7. 退格:数字的追加都在numvalue1中存储,使用substring(0,numvalue1.length-1)来切断显示即可
8. 点击运算符事件:思想:为了能够保留上一次运算的结果可以进行下一次的计算,当点击运算符时 num2保留num1的值,num1为空(不追加)去接收下一次的新数字;用户连续点击数字的时候使用num1追加保存此时num2为空。
获取所有运算符对象,给运算符动态绑定点击事件,数字的保存都在value1中,但是当用户点击第一个数字,然后点击完运算符时:第二个数有值(说明数字传递完成)就去计算;第二个数为空把第一个数给到第二数,把第一个数清空,让他可以接收下一次的输入;保存用户点击的运算符
9.小数点也归为数字,只能存在一个的解决
判断点击的是否为小数点 :
是 ,num1就累加,再次判断num1还有没有点,没有点正常的拼接;展示框展示value1的值
否, 点击点也正常的拼接,展示框展示value1的值
- 无效零的解决:输出显示乘1自动去0机制:字符串转换为数字
点击数字 ,显示框显示的时候就会乘1之后显示
-
浮点精度问题的解决:tofix 保留并四舍五入 再乘1去0
-
连乘或乘加显示为0解决:原因:运算结束一次后清空value1,结果为value2,此时再点击乘号满足value2不为空的条件会直接计算结果为0因此显示框由上一次的结果变为0,因此需要加入判断
numValue1!=''
时再去计算结果; -
展示结果的思想:case匹配用户输入的运算符去进行相应的计算,注意第一个数是value2,第二个数是value1,去进行运算;最后将结果保留在value2中,清空value1(如果要继续使用结果用于去接收下一个新的数字)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
tr {
text-align: center;
font-size: 30px;
}
input {
height: 70px;
width: 600px;
font-size: 40px;
}
td:hover {
background: greenyellow;
cursor: pointer;
}
</style>
</head>
<body>
<center>
<!-- disabled="disabled" 禁用输入 -->
<input type="text" id="showData" value="0" disabled="disabled" />
<table border="1" cellspacing="0" width="600px" height="400px">
<tr>
<td id="clearData">C</td>
<td id="del">退格</td>
<td>%</td>
<td class="ysf">/</td>
</tr>
<tr>
<td class="num">7</td>
<td class="num">8</td>
<td class="num">9</td>
<td class="ysf">*</td>
</tr>
<tr>
<td class="num">4</td>
<td class="num">5</td>
<td class="num">6</td>
<td class="ysf">-</td>
</tr>
<tr>
<td class="num">1</td>
<td class="num">2</td>
<td class="num">3</td>
<td class="ysf">+</td>
</tr>
<tr>
<td colspan="2" class="num">0</td>
<td class="num">.</td>
<td id="result">=</td>
</tr>
</table>
</center>
</body>
</html>
<script type="text/javascript">
//1.我们数字和小数点归为一类
//2.把操作符规范为一类
//3.其他按键,单独设置id
//4.获取用户点击的数字,展示到显示框上
//5.定义 三个变量 来存储第一个数,第二个数 以及运算符
var numValue1 = '';
var numValue2 = '';
var opr = '';
//获取显示框
var showValue = document.getElementById("showData");
//获取所有的数字
var nums = document.getElementsByClassName("num");
//遍历数组,循环添加点击事件
for (let i = 0; i < nums.length; i++) {
nums[i].onclick = function() {
if(this.innerText=="."){
//alert("你在点小数点");
if(numValue1.indexOf(".")==-1&&numValue1.length>=1){
//alert("点了");
//获取用户点击的数字,展示出来
//this 表示你当前点击的那个元素对象
numValue1 += this.innerText;
showValue.value = numValue1;
}
}else{
//this 表示你当前点击的那个元素对象
numValue1 += this.innerText;
showValue.value = numValue1;
}
}
}
//给运算符绑定点击事件
var ysfs = document.getElementsByClassName("ysf")
for (let i = 0; i < ysfs.length; i++) {
ysfs[i].onclick = function() {
//当用点击完第一个数字,然后点击运算符,那么我们这么做
//我们把第一个数给到第二数,把第一个数清空,让他可以接收下一次的输入
if(numValue2==''){
numValue2 = numValue1;
numValue1 = '';
}else{
//运算结束一次后清空value1,结果为value2,此时再点击乘号满足value2不为空的条件会直接计算结果为0因此显示框由上一次的结果变为0,因此需要加入判断numValue1!=''时再去计算结果;
//当运算结束一次后value2为结果值,value1为空,此时再点击乘号,显示框显示上一次运算的结果,点击新数字赋给value1,此时value1与value2均不为空,计算结果并显示。
//第一次计算时:点击value1显示value1,点击+号,此时value2为空,传递数字,再次点击新数字赋给value1,显示框显示新数字,点击等于号,此时value1与value2均不为空,计算结果并显示。
if(numValue1!=''){
showFun(); //运算出上一次结果
}
}
//保存运算符
opr = this.innerText;
}
}
//归零
document.getElementById("clearData").onclick = function() {
//归零
numValue1 = '';
numValue2 = '';
opr = '';
showValue.value = '0';
}
//退格
document.getElementById("del").onclick = function() {
if (numValue1.length > 1) {
numValue1 = numValue1.substring(0, numValue1.length - 1);
showValue.value = numValue1;
}
// else if(numValue1.length==1){
// numValue1 ='0'
// showValue.value = numValue1;
}
}
//点击等号计算结果
document.getElementById("result").onclick = function() {
if (numValue1!=''&&numValue2=='') {
showValue.value =numValue1;
}else if(numValue2!=''&&numValue1==''){showValue.value =numValue2;}
else{showFun();}
}
//运算:
function showFun() {
var one = Number(numValue2);
var two = Number(numValue1);
var r = null;
switch (opr) {
case '+':
r = one + two;
break;
case '-':
r = one - two;
break;
case '*':
r = one * two;
break;
case '/':
if(two==0){
alert("初始不能为0");
numValue1 = '';
numValue2 = '';
opr = '';
r='0';
return;
}else{
r = one / two;
}
break;
}
//把结果给num2 进行四则连续计算时可以保留,再次清空value1,用于当点击运算符后点击新数字就存储
numValue2=r;
numValue1=''
showValue.value =new Number(r).toFixed(5)*1; //展示框展示结果
}
//作业:四则运算
//小数点的处理,只允许出现一个小数点。
//首尾无效0的去除
//1.2*3=3.5999999999999999999
</script>