display:talbe table-row table-cell 的区别
1、当设置display:table;时,table的padding设置会失效
2、当设置display:table-row;时,margin和padding设置会失效。
3、当设置display:table-cell;时,margin设置会失效。
为表格设置合并边框模型:
border-collapse:collapse;
text-indent
text-indent 属性能定义一个块元素首行文本内容之前的缩进量
setSelectionRange()HTMLInputElement.setSelectionRange 方法用于设定<input> 或 <textarea> 元素中当前选中文本的起始和结束位置。
HTMLInputElement.select()HTMLInputElement.select() 方法选中一个 <textarea> 元素或者一个带有 text 字段的 <input> 元素里的所有内容。
event.type
只读属性 Event.type 会返回一个字符串, 表示该事件对象的事件类型。
后台管理实战
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台管理列表</title>
<link rel="stylesheet" href="">
<link rel="stylesheet" href="css/icons.min.css" />
<link rel="stylesheet" href="css/common.css" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<div class="list-wrap">
<table class="list-tb">
<caption><h1>腾讯课堂课程管理系统</h1></caption>
<thead>
<tr>
<td colspan="6">
<ul class="nav-list J_nav clearfix">
<li class="nav-item active" data-field="manage">
<a href="javascript:;" class="nav-lk">列表管理</a>
</li>
<li class="nav-item" data-field="trash">
<a href="javascript:;" class="nav-lk">垃圾箱</a>
</li>
<li class="nav-item" data-field="search">
<a href="javascript:;" class="nav-lk">课程搜索</a>
</li>
</ul>
</td>
</tr>
<tr class="J_searchRow search-row">
<td colspan="6" class="search-cell">
<div class="search-wrap">
<span class="fa fa-search"></span>
<input type="text" id="J_searchInput" class="search-input" placeholder="课程搜索" />
</div>
</td>
</tr>
<tr class="field-tt">
<th>ID</th>
<th>课程名称</th>
<th>课时数</th>
<th>任课老师</th>
<th>课程类型</th>
<th>课程操作</th>
</tr>
<tr class="J_tipRow tip-row">
<td colspan="6" class="warning-tip J_warningTip">- 暂无数据 -</td>
</tr>
</thead>
<tbody class="J_courseList"></tbody>
<tfoot>
<tr class="page-btn-row J_pageBtnRow">
<td colspan="6">
<ul class="page-btn-list J_pageBtnList clearfix"></ul>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- 渲染课程列表 -->
<script type="text/html" id="J_listItemTpl">
<tr>
<td>{{id}}</td>
<td class="course-name-cell">
<!-- span框与修改的输入框 -->
<span class="course-name">{{course}}</span>
<input type="text" data-id="{{id}}" class="course-name-input" value="{{course}}" />
</td>
<td>{{hour}}小时</td>
<td>{{teacher}}老师</td>
<td>{{field}}</td>
<td><button data-id="{{id}}" class="list-btn {{type}}">{{typeText}}</button></td>
</tr>
</script>
<!-- 渲染页码列表 -->
<script type="text/html" id="J_pageBtnItemTpl">
<li class="btn-item {{isCur}}">
<a href="javascript:;" class="page-btn">{{pageNum}}</a>
</li>
</script>
<script src="js/utils.js"></script>
<script src="js/index.js"></script>
</body>
</html>
.list-wrap {
width: 1000px;
margin: 100px auto;
}
.list-tb {
width: 100%;
border: 1px solid #ccc;
border-collapse: collapse;
}
.list-tb caption {
height: 60px;
}
.list-tb tr {
height: 44px;
}
.list-tb td,
.list-tb th {
position: relative;
border-bottom: 1px solid #ccc;
text-align: center;
}
.list-tb .field-tt {
background-color: #eee;
}
.list-tb td .nav-item {
float: left;
width: 130px;
height: 30px;
margin: auto 15px;
background-color: #ddd;
text-align: center;
line-height: 30px;
}
.list-tb td .nav-item .nav-lk {
display: block;
height: 100%;
color: #999;
}
.list-tb td .nav-item.active .nav-lk {
color: #fff;
background-color: #000;
}
/* 课程搜索框默认隐藏 */
.list-tb .search-row {
display: none;
}
.list-tb .search-row.show {
display: table-row;
}
.list-tb .search-cell .search-wrap {
position: relative;
width: 300px;
height: 30px;
}
.list-tb .search-cell .search-wrap .fa {
position: absolute;
left: 25px;
top: 5px;
}
.list-tb .search-cell .search-input {
width: 100%;
height: 100%;
margin-left: 15px;
border: 1px solid #ddd;
font-size: 16px;
text-indent: 30px;
}
/* 暂无数据默认隐藏 */
.list-tb .tip-row.hide {
display: none;
}
.list-tb .warning-tip {
color: #999;
}
.list-tb .list-btn {
height: 30px;
padding: 0 15px;
color: #fff;
font-size: 14px;
}
.list-tb .list-btn.delete {
background-color: red;
}
.list-tb .list-btn.regain {
background-color: orange;
}
.list-tb .course-name-cell {
text-align: left;
padding-left: 15px;
}
.list-tb .course-name-input {
display: none;
position: absolute;
top: 6px;
left: 15px;
width: 100%;
height: 30px;
border: 1px solid #ddd;
text-indent: 10px;
font-size: 14px;
}
/* 设置行内块的作用是为了跟前面的不换行跟前面的span元素设置为同一行 */
.list-tb .course-name-input.show {
display: inline-block;
}
.list-tb .page-btn-row {
display: none;
}
.list-tb .page-btn-row.show {
display: table-row;
}
.list-tb .page-btn-list {
width: 100%;
margin-left: 15px;
}
.list-tb .btn-item {
float: left;
width: 60px;
height: 100%;
}
.list-tb .btn-item .page-btn {
display: block;
width: 22px;
height: 22px;
background-color: #ddd;
text-align: center;
line-height: 22px;
font-size: 14px;
}
/* 点击时的页码样式 */
.list-tb .btn-item.cur .page-btn {
background-color: #000;
color: #fff;
}
;
(function (doc) {
var oNav = doc.getElementsByClassName('J_nav')[0],
oNavItems = oNav.getElementsByClassName('nav-item'),
oSearchRow = doc.getElementsByClassName('J_searchRow')[0],
oWarningTip = doc.getElementsByClassName('J_tipRow')[0],
oCourseList = doc.getElementsByClassName('J_courseList')[0],
oSearchInput = doc.getElementById('J_searchInput'),
oPageBtnRow = doc.getElementsByClassName('J_pageBtnRow')[0],
oPageBtnList = doc.getElementsByClassName('J_pageBtnList')[0],
oBtnItems = oPageBtnList.getElementsByClassName('btn-item'),
oCourseInputs = oCourseList.getElementsByClassName('course-name-input'),
oCourseSpans = oCourseList.getElementsByClassName('course-name'),
listItemTpl = doc.getElementById('J_listItemTpl').innerHTML,
pageBtnItemTpl = doc.getElementById('J_pageBtnItemTpl').innerHTML,
oNavItemsLen = oNavItems.length,
field = 'manage',
pageNum = 0,
// curId :选中的input的 data-id 属性
// curIdx 选中的input 在列表中的位置 用于定位与显示与input输入框同一位置的span标签 以及更新的信息
curId = 0,
curIdx = -1;
var API = {
getCourseList: 'http://localhost/api_for_study/index.php/List/getCourseListForManage',
getSearchList: 'http://localhost/api_for_study/index.php/List/getSearchListForManage',
doListItem: 'http://localhost/api_for_study/index.php/List/doListItemForManage',
updateCourseName: 'http://localhost/api_for_study/index.php/List/updateCourseNameForManage'
}
var init = function () {
getCourseList(field, pageNum);
bindEvent();
}
function bindEvent() {
oNav.addEventListener('click', navClick, false);
oSearchInput.addEventListener('input', throttle(courseSearch, 1000), false);
oPageBtnList.addEventListener('click', changePage, false);
oCourseList.addEventListener('click', listClick, false);
}
// tab选项卡
function navClick(e) {
var e = e || window.event,
tar = e.target || e.srcElement,
className = tar.className;
// 阻止事件的冒泡与捕获
e.stopPropagation();
if (className === 'nav-lk') {
// 寻找a标签的父元素li标签
var oParent = tar.parentNode,
item;
field = oParent.getAttribute('data-field');
for (var i = 0; i < oNavItemsLen; i++) {
// 循坏遍历tab的每一项
item = oNavItems[i];
// 取消所有tab的样式
item.className = 'nav-item';
}
oParent.className += ' active';
if (field === 'search') {
showSearchInput(true);
showWarningTip(true);
showPageBtnRow(false);
return;
}
getCourseList(field, pageNum);
}
}
function courseSearch(e) {
var e = e || window.event,
val = this.value,
valLen = val.length;
if (valLen > 0) {
getSearchList(val);
} else {
showWarningTip(true);
}
}
// 是否显示搜索输入框
function showSearchInput(show) {
if (show) {
oSearchRow.className += ' show';
} else {
oSearchRow.className = 'J_searchRow search-row';
oSearchInput.value = ''
}
}
// 是否显示数据 默认没数据
function showWarningTip(show) {
if (show) {
oWarningTip.className = 'J_tipRow tip-row';
oCourseList.innerHTML = '';
} else {
oWarningTip.className += ' hide';
}
}
//是否显页码按钮组 默认隐藏
function showPageBtnRow(show) {
if (show) {
oPageBtnRow.className += ' show';
} else {
oPageBtnRow.className = 'page-btn-row J_pageBtnRow';
}
}
function _setDatas(field, data, pageCount, pageNum) {
console.log(pageCount, pageNum);
if (data && data.length > 0) {
// 把模板渲染到指定oCourseList列表
oCourseList.innerHTML = renderList(field, data);
showWarningTip(false);
if (pageCount > 1 && field !== 'search') {
oPageBtnList.innerHTML = renderPageBtns(pageCount, pageNum);
showPageBtnRow(true);
} else {
oPageBtnList.innerHTML = '';
showPageBtnRow(false);
}
// 没有数据则显示暂无数据
} else {
showWarningTip(true);
}
}
// 渲染列表
function renderList(listField, data) {
var list = '';
data.forEach(function (elem) {
list += listItemTpl.replace(/{{(.*?)}}/g, function (node, key) {
return {
id: elem.id,
course: elem.course,
hour: elem.hour,
teacher: elem.teacher,
field: elem.field,
type: listField == 'trash' ? 'regain' : 'delete',
typeText: listField == 'trash' ? '恢复' : "删除"
} [key];
});
});
return list;
}
function renderPageBtns(pageCount, pageNum) {
var list = '';
for (var i = 0; i < pageCount; i++) {
list += pageBtnItemTpl.replace(/{{(.*?)}}/g, function (node, key) {
return {
pageNum: i + 1,
isCur: i == pageNum && 'cur'
} [key];
});
}
return list;
}
//更改页面
function changePage(e) {
var e = e || window.event,
tar = e.target || e.srcElement,
className = tar.className;
e.stopPropagation();
if (className === 'page-btn') {
var oParent = tar.parentNode,
oBtnItemsLen = oBtnItems.length,
item;
pageNum = [].indexOf.call(oBtnItems, oParent);
console.log(oBtnItems, oParent, pageNum);
// 遍历所有分页按钮还原成默认样式
for (var i = 0; i < oBtnItemsLen; i++) {
item = oBtnItems[i];
item.className = 'btn-item';
}
// 给点击的按钮添加样式
oParent.className += ' cur';
getCourseList(field, pageNum);
}
}
function listClick(e) {
var e = e || window.event,
tar = e.target || e.srcElement,
className = tar.className,
itemId = tar.getAttribute('data-id');
e.stopPropagation();
switch (className) {
case 'list-btn delete':
var c = confirm('确认删除');
c && doListItem('remove', pageNum, itemId);
break;
case 'list-btn regain':
var c = confirm('确认恢复');
c && doListItem('regain', pageNum, itemId);
break;
case 'course-name':
showInput(tar);
break;
default:
break;
}
}
// 请求课程列表
// 传参请求页数 与点击的tab项目
function getCourseList(field, pageNum) {
showSearchInput(false);
xhr.ajax({
url: API.getCourseList,
type: 'POST',
dataType: 'JSON',
data: {
field: field,
pageNum: pageNum
},
success: function (data) {
var res = data.res,
pageCount = data.pages;
// 点击的具体项目名 具体的数据列表 总页数 与默认显示的页码
_setDatas(field, res, pageCount, pageNum);
},
error: function () {
alert('列表获取失败,请重试!');
}
});
}
function getSearchList(keyword) {
xhr.ajax({
url: API.getSearchList,
type: 'POST',
dataType: 'JSON',
data: {
keyword: keyword
},
success: function (data) {
var res = data.res;
_setDatas('manage', res);
},
error: function () {
alert('搜索操作失败,请重试!');
}
})
}
// 删除或恢复数据 重新请求列表
function doListItem(type, pageNum, itemId) {
xhr.ajax({
url: API.doListItem,
type: 'POST',
dataType: 'JSON',
data: {
type: type,
pageNum: pageNum,
itemId: itemId
},
success: function (data) {
var res = data.res,
pageCount = data.pages;
_setDatas(field, res, pageCount, pageNum);
},
error: function () {
alert('操作列表失败,请重试!');
}
})
}
function submitNewCourseName(curId, curIdx) {
// 单击前确认隐藏所有input输入框 以及更新事件
hideAllInputs();
var newVal = oCourseInputs[curIdx].value,
thisCourseSpan = oCourseSpans[curIdx];
console.log(newVal, thisCourseSpan.innerHTML);
if (newVal !== thisCourseSpan.innerHTML) {
xhr.ajax({
url: API.updateCourseName,
type: 'POST',
dataType: 'JSON',
data: {
itemId: curId,
newVal: newVal
},
success: function (data) {
// 如果成功则将输入框的值替换span标签的值
if (data === 'success') {
thisCourseSpan.innerHTML = newVal;
} else {
alert('更改课程名称失败,请重试');
}
curId = 0;
curIdx = -1;
},
error: function () {
alert('更改课程名称失败,请重试');
}
});
}
}
function updateCourseName(e) {
var e = e || window.event,
eventType = e.type;
// 如果是按键事件
if (eventType === 'keyup') {
var keyCode = e.keyCode;
// 单击了回车键
if (keyCode === 13) {
submitNewCourseName(curId, curIdx);
}
return;
}
// 否则是其他事件例如单击click事件
submitNewCourseName(curId, curIdx);
}
function showInput(target) {
hideAllInputs();
var oParent = target.parentNode,
thisInput = oParent.getElementsByClassName('course-name-input')[0],
thisInputLen = thisInput.value.length;
curId = thisInput.getAttribute('data-id');
// 查找点击的input在列表中对应的oCourseInputs中的位置
curIdx = [].indexOf.call(oCourseInputs, thisInput);
console.log(curId, curIdx);
thisInput.className += ' show';
// 将当前输入框设置焦点
thisInput.focus();
// 全选输入框输入的内容
thisInput.setSelectionRange(0, thisInputLen);
// 每次单击输入框时设置点击任何地方或是按回车则更新输入框内容
document.addEventListener('click', updateCourseName, false);
document.addEventListener('keyup', updateCourseName, false);
}
function hideAllInputs() {
var inputsLen = oCourseInputs.length,
item;
for (var i = 0; i < inputsLen; i++) {
item = oCourseInputs[i];
item.className = 'course-name-input';
// 取消所有input输入框的焦点
item.blur();
}
// 每次单击输入框之前 移除点击任何地方或是按任意按键则更新输入框内容的事件
document.removeEventListener('click', updateCourseName, false);
document.removeEventListener('keyup', updateCourseName, false);
}
init();
})(document);
