6 Jun 18
一、今日面试题(面向对象)
1. 谈谈你对面向对象的理解?
扩展方便;上帝视角,造一些对象(对象是特征与技能的结合体),让他们之间发生反应
2. Python面向对象中的继承有什么特点?
方便代码重用,可以多继承
3. 面向对象深度优先和广度优先是什么?
菱形继承的背景下,查找属性时:
1、经典类:深度优先
在python2中,A为经典类,F->D->B->A->E->C
2、新式类:广度优先
在python3中,A为新式类,F->D->B->E->C-A->object
4. 面向对象中super的作用?
A内super会基于C.mro()继续往后找;子代继承父代的方法
5. 列举面向对象中特殊成员(带双下划线的特殊方法,如:__new__、__init__、__call__等)
__new__ # 创建对象
__init__ # 初始化对象
__call__ # 调用对象
__str__ # print打印一个对象时 __unicode__(python2中)
__repr__ # 输入对象回车找的是__repr__; print先找__str__,没有__str__找__repr__
__doc__ # 查看文档注释
__getattr__
__setattr__
__del__ # 删除对象
6. 静态方法和类方法区别?
@staticmethod 不主动传值,只是一个单纯的函数
@classmethod 类调用时,将类本身作为第一个参数传入
7. 面向对象三大特性:封装、继承、多态
二、作业讲解(新增,删除,取消)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.cover {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.4);
z-index: 9;
}
.modal {
position: absolute;
left:50%;
top: 50%;
height: 300px;
400px;
background-color: white;
z-index: 10;
margin-top: -150px;
margin-left: -200px;
}
.hide {
display: none;
}
</style>
<script src="jquery-3.3.1.min.js"></script>
</head>
<body>
<button id="add">add</button>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>NAME</th>
<th>HOBBY</th>
<th>OPERATION</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Egon</td>
<td>Sing</td>
<td>
<input type="button" value="edit" class="edit">
<input type="button" value="delete" class="delete">
</td>
</tr>
<tr>
<td>2</td>
<td>Alex</td>
<td>Dance</td>
<td>
<input type="button" value="edit" class="edit">
<input type="button" value="delete" class="delete">
</td>
</tr>
<tr>
<td>3</td>
<td>Yuan</td>
<td>Speak</td>
<td>
<input type="button" value="edit" class="edit">
<input type="button" value="delete" class="delete">
</td>
</tr>
</tbody>
</table>
<div class="cover hide"></div>
<div class="modal hide">
<p><input type="text" id="username"></p>
<p><input type="text" id="hobby"></p>
<p>
<button id="submit">submit</button>
<button id="cancel">cancel</button>
</p>
</div>
<script>
// 定义一个隐藏模态框的函数
function hideModel(){
$(".cover,.modal").addClass("hide");
}
$("#add").click(function(){
// 点击新增按钮要做的事儿
// 1. 弹出模态框
$(".cover,.modal").removeClass("hide");
});
$("#submit").click(function(){
// 点击提交按钮要做的事儿
// 1. 取值,取模态框中用户填写的值
let username=$("#username").val();
let hobby=$("#hobby").val();
// 2. 隐藏模态框
hideModel()
// 3. 创建tr标签, 追加td, 要拼接序号和用户填写的信息
let trELe=document.createElement("tr");
let td1=document.createElement("td");
td1.innerText=$("table tr").length;
$(trELe).append(td1);
let td2=document.createElement("td");
td2.innerText=username;
$(trELe).append(td2);
let td3=document.createElement("td");
td3.innerText=hobby;
$(trELe).append(td3);
// clone,不推荐使用clone;如果表中没有数据,没有可clone的对象
// $("table td").last().clone().appendTo(trEle);
let td4=document.createElement("td");
td4.innerHTML =`
<input type="button" value="edit" class="edit">
<input type="button" value="delete" class="delete">
`;
$(trELe).append(td4);
// 4. 追加到table tbody标签的最后
$("tbody").append(trELe);
});
$("#cancel").on("click",function(){
// 点击取消
// 1. 把模态框隐藏
hideModel();
// 2. 把之前填写的清空掉
$("#username,#hobby").val("");
});
// 如果不用委托,会导致新增的数据删除不了;这是因为绑定事件发生在最开始(刷新时),后续用js方法创建的对象的相应属性没有被绑定上该事件
// 事件委托: 事件委托是通过事件冒泡的原理,利用父标签去捕获子标签的事件。
// 事件冒泡:是从触发事件的那个节点一直到document,是自下而上的去触发事件。
$("table").on("click",".delete",function(){
// 删除按钮点击要做的事儿
// 1.更新序号...
// 把当前行后面的所有tr的第一个td的值-1
let $currentTr=$(this).parent().parent();
let $nextAllTr=$currentTr.nextAll();
for (let i=0;i<$nextAllTr.length;i++){
let n=$($nextAllTr[i]).children().first().text();
$($nextAllTr[i]).children().first().text(n-1);
}
// 2. 把当前点击按钮所在的行 删掉
$currentTr.remove();
})
</script>
</body>
</html>
三、今日内容
A. 常用事件
1. hover
应用: 导航条中,鼠标悬浮于购物车时显示购物车内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
}
.nav {
height: 40px;
background-color: #3d3d3d;
100%;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
a {
text-decoration: none;
}
.nav a {
color: #999;
}
.nav a:hover {
color: white;
}
.nav li {
float: left;
height: 40px;
line-height: 40px;
margin-right: 15px;
padding: 0 10px;
}
.nav li:hover {
background-color: black;
}
.father {
position:relative;
}
.son {
height: 100px;
200px;
background-color: blue;
color: white;
position: absolute;
left: 0;
top: 40px;
margin: 0;
display: none;
}
.show {
display: block;
}
</style>
<script src="jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="nav">
<ul>
<li><a href="">login</a></li>
<li><a href="">register</a></li>
<li class="father"><a href="">shopping cart</a>
<p class="son">None~</p>
</li>
</ul>
</div>
<script>
// 鼠标移到.father 上时 让.son 添加一个.show
// hover()接收两个参数,一个为鼠标悬浮的事件,一个为鼠标移除的事件
$(".father").hover(
function(){
$(this).find(".son").addClass("show");
},
function(){
$(this).find(".son").removeClass("show");
}
)
</script>
</body>
</html>
2. keydown和keyup
3. change
应用:批量操作(键盘按住shift,可以批量修改选中行的值)(含each的应用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-3.3.1.min.js"></script>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>name</th>
<th>operation</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox"></td>
<td>Egon</td>
<td>
<select>
<option value="1">operation1</option>
<option value="2">operation2</option>
<option value="3">operation3</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Alex</td>
<td>
<select>
<option value="1">operation1</option>
<option value="2">operation2</option>
<option value="3">operation3</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Yuan</td>
<td>
<select>
<option value="1">operation1</option>
<option value="2">operation2</option>
<option value="3">operation3</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>EvaJ</td>
<td>
<select>
<option value="1">operation1</option>
<option value="2">operation2</option>
<option value="3">operation3</option>
</select>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Gold</td>
<td>
<select>
<option value="1">operation1</option>
<option value="2">operation2</option>
<option value="3">operation3</option>
</select>
</td>
</tr>
</tbody>
</table>
<input type="button" id="b1" value="select all">
<input type="button" id="b2" value="cancel">
<input type="button" id="b3" value="select opposite">
<script>
let flag=false;
// 如何获取用户按下那个按键
// e表示事件本身;shift的keycode是16
$(window).on("keydown",function(e){
console.log(e.keyCode);
if (e.keyCode===16){
flag=true;
}
});
// 绑定一个按键抬起的事件,将flag重置为false,即将批量修改的效果取消
$(window).on("keyup",function(e){
if(e.keyCode===16){
flag=false;
}
});
// 找到select标签 绑定change事件
$("select").on("change",function () {
// 拿到当前select标签的值
let v=$(this).val();
// 判断一下当前行是否被选中
let isCheck=$(this).parent().parent().find("input:checkbox").prop("checked");
// 如果是批量编辑模式,就要找到所有被选中的行,然后将其select置为和我一样的值
// 如果shift被按住且被触发的确实被选中
if (flag && isCheck){
// 用for循环,找到所有被选中的行
// let $allChecked=$("input:checked");
// for (let i=0;i<$allChecked.length;i++){
// $($allChecked[i]).parent().parent().find("select").val(v);
// }
// 也可使用each循环
$("input:checked").each(function () {
$(this).parent().parent().find("select").val(v);
})
}
// 如果不是批量编辑模式,什么都不干
});
$("#b1").click(
function(){
$("table :checkbox").prop("checked",true);
}
);
$("#b2").click(
function(){
$("table :checkbox").prop("checked",false);
}
);
$("#b3").click(
function(){
var $checkboxs=$("table :checkbox")
for (let i=0;i<$checkboxs.length;i++){
current_checkbox=$checkboxs[i]
$(current_checkbox).prop("checked",!$(current_checkbox).prop("checked"))
}
}
)
</script>
</body>
</html>
4. focus和blur
5. input
应用:获取光标,移除光标,输入框内容变化(input)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-3.3.1.min.js"></script>
</head>
<body>
<input type="text" id="i1">
<script>
// 当input框获取焦点时触发
$("#i1").on("focus",function(){
console.log(123);
});
// 当input框失去焦点时触发
$("#i1").on("blur",function(){
console.log($(this).val());
});
// 当input框的值发生变化时触发
$("#i1").on("input",function(){
console.log($(this).val());
})
</script>
</body>
</html>
B. 事件绑定的方式(详见前面例子)
1. .click(function(){...})
2. .on("事件名称", function(){...}) # 1,2效果等同
3. 事件委托
语法:
.on("事件名称", "选择器", function(){...})
特点:
1. 利用事件冒泡的特点
2. 基于一个已经存在的标签给未来的标签添加事件处理函数
C. return false;阻止后续事件的执行
应用:登陆注册示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录注册示例</title>
<style>
.error {
color: red;
}
</style>
</head>
<body>
<form action="">
<p>
<label for="username">用户名</label>
<input type="text" id="username" name="username">
<span class="error"></span>
</p>
<p>
<label for="pwd">密码</label>
<input type="password" id="pwd" name="pwd">
<span class="error"></span>
</p>
<p>
<input type="submit" id="b1" value="登录">
</p>
</form>
<script src="jquery-3.3.1.min.js"></script>
<script>
$("#b1").click(function () {
var flag = true;
$(".error").text("");
var $username = $("#username");
var $pwd = $("#pwd");
// 取input框的值判断长度是否为0
if ($username.val().length === 0){
// 用户名没有输入, 提示
$username.next().text("用户名不能为空!");
flag = false;
}
if ($pwd.val().length === 0){
// 用户名没有输入, 提示
$pwd.next().text("密码不能为空!");
flag = false;
}
return flag; // 阻止后续事件的执行
})
</script>
</body>
</html>
D. 页面加载完成后执行(ready)
当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。这是事件模块中最重要的一个函数,因为它可以极大地提高web应用程序的响应速度。
- 不用ready的话,可以将script放在body的最后面;否则报错
- 可以用ready,并将要执行的代码放入ready里
- 一般,我们会将代码放入ready,并将ready放在body的最后面
ready的两种写法
$(document).ready(function(){
//在这里写你的JS代码...
})
$(function(){
//你在这里写你的代码
}) # 一般不用,要看懂
应用:页面加载完执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>页面加载完执行</title>
</head>
<body>
<div id="d1">div</div>
<script src="jquery-3.3.1.min.js"></script>
<script>
// ready的第一种写法
$(document).ready(function () {
var d1Ele = document.getElementById("d1");
console.log(d1Ele);
console.log(d1Ele.innerText);
});
// ready的第二种写法,一般不用,要看懂
// $(function () {
// var d1Ele = document.getElementById("d1");
// console.log(d1Ele);
// console.log(d1Ele.innerText);
// })
</script>
</body>
</html>
E. jQuery自带的动画效果(一般不用)
// 基本
show([s,[e],[fn]])
hide([s,[e],[fn]])
toggle([s],[e],[fn])
// 滑动
slideDown([s],[e],[fn])
slideUp([s,[e],[fn]])
slideToggle([s],[e],[fn])
// 淡入淡出
fadeIn([s],[e],[fn])
fadeOut([s],[e],[fn])
fadeTo([[s],o,[e],[fn]])
fadeToggle([s,[e],[fn]])
// 自定义(了解即可)
animate(p,[s],[e],[fn])
应用:点赞
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>点赞动画示例</title>
<style>
div {
position: relative;
display: inline-block;
}
div>i {
display: inline-block;
color: red;
position: absolute;
right: -16px;
top: -5px;
opacity: 1;
}
</style>
</head>
<body>
<div id="d1">点赞</div>
<script src="jquery-3.3.1.min.js"></script>
<script>
$("#d1").on("click", function () {
var newI = document.createElement("i");
newI.innerText = "+1";
$(this).append(newI);
$(this).children("i").animate({
opacity: 0
}, 1000)
})
</script>
</body>
</html>
F. each(详见前面示例)
jQuery.each(collection, callback(indexInArray, valueOfElement)):
描述:一个通用的迭代函数,它可以用来无缝迭代对象和数组。数组和类似数组的对象通过一个长度属性(如一个函数的参数对象)来迭代数字索引,从0到length - 1。其他对象通过其属性名进行迭代。
li =[10,20,30,40]
$.each(li,function(i, v){
console.log(i, v);//index是索引,ele是每次循环的具体元素。
})
.each(function(index, Element)):
描述:遍历一个jQuery对象,为每个匹配元素执行一个函数。
.each() 方法用来迭代jQuery对象中的每一个DOM元素。每次回调函数执行时,会传递当前循环次数作为参数(从0开始计数)。由于回调函数是在当前DOM元素为上下文的语境中触发的,所以关键字this 总是指向这个元素。
// 为每一个li标签添加foo
$("li").each(function(){
$(this).addClass("c1");
});
在遍历过程中可以使用return false提前结束each循环。
return只能结束本次循环,不能跳出each循环
G. .data() (具体应用详见明天作业)
$("div").data("k",100); //给所有div标签都保存一个名为k,值为100
$("div").data("k"); //返回第一个div标签中保存的"k"的值
$("div").removeData("k"); //移除元素上存放k对应的数据