1.文字滾動
<html>
<head>
<title>我的第一個頁面</title>
</head>
<body>
<marquee behavior="scroll" direction="up" height="30" style="overflow:hidden;" scrollamount="1" width="300" onMouseOver="stop()" onMouseOut="start()">
雷電黃色預警!<br />
大雨黃色預警!<br />
</marquee>
</body>
</html>
direction:方向
up:上 down:下 left:左 right:右
scrollamount:滾動速度-----------------scroll:滾動 amount:數值
width:寬度 height:高度
onmouseover:當鼠標移上去
onmouseout:當鼠標離開
stop():停止
start():開始
behavior:
scroll 循環滾動
alternate 來回滾動
slide 滾動一次停止
一.有關于內置對象的作用域
主要說明2個對象,request,session
1、request 對象
request 對象是 javax.servlet.httpServletRequest類型的對象。 該對象代表了客戶端的請求信息,主要用于接受通過HTTP協議傳送到服務器的數據。(包括頭信息、系統信息、請求方式以及請求參數等)。
request只在2個頁面之間傳遞,每一次新的請求都會新建一個request對象,也就是說可能會request對象不一致導致空指針異常。
2、session 對象
session 對象是由服務器自動創建的與用戶請求相關的對象。服務器為每個用戶都生成一個session對象,用于保存該用戶的信息,跟蹤用戶的操作狀態。session對象內部使用Map類來保存數據,因此保存數據的格式為 “Key/value”。 session對象的value可以使復雜的對象類型,而不僅僅局限于字符串類型。
session對象在整個會話只有一個,也就是說session對象的數據會一直保留直到主動進行數據更改。
二.表單提交
在index.jsp中使用form進行數據的提交,action的目標是check.jsp,method是post
三.驗證跳轉
當form提交信息后交給check.jsp驗證,使用getParameter來得到form的信息,并使用setAttribute保存。在check.jsp中判斷賬號密碼是否正確后,使用
<jsp:forward page=".jsp"></jsp:forward>
1
進行跳轉,.jsp是想要跳轉的頁面路徑。
四.詳細代碼
index.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陸</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="check.jsp" method="post">
請輸入用戶名:
<input type = "text" name = "username"><br/>
請輸入密碼:
<input type = "password" name = "passwd"><br/>
<input type="submit" name="submit" value="登錄">
</form>
</body>
</html>
check.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>驗證</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getParameter("username");
String passwd = (String)request.getParameter("passwd");
request.setAttribute("username", username);
request.setAttribute("passwd", passwd);
if(username.equals("admin")&&passwd.equals("123")){
%>
<jsp:forward page="succeed.jsp"></jsp:forward>
<%}else{ %>
<jsp:forward page="failed.jsp"></jsp:forward>
<%} %>
</body>
</html>
succeed.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陸成功</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getAttribute("username");
String passwd = (String)request.getAttribute("passwd");
%>
<%=username %>登陸成功
</body>
</html>
failed.jsp
<%@ page language="java" import="java.util." pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陸失敗</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
String username = (String)request.getAttribute("username");
String passwd = (String)request.getAttribute("passwd");
%>
<%=username %>登陸失敗
</body>
</html>
五.注意事項
在jsp中使用form提交表單不能直接進行跳轉,否則操作不慎就容易出現空指針異常,建議交由單獨的跳轉頁面處理
下面這段代碼是實現簡單的導航效果:
在這里插入代碼片<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin:0px;
padding:0px;
list-style:none;
}
.nav{
width:700px;
margin:100px auto;
}
.nav ul li{
float:left;
margin-right:5px;
}
.nav ul li a{
width:100px;
height:30px;
color:#fff;
display:block;
line-height:30px;
margin-right:5px;
text-decoration:none;
background:red;
text-align:center;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.nav ul li a:hover{
background:yellow;
color:blue;
text-decoration:underline;
}
</style>
</head>
<body>
<div class="nav">
<ul class="clearfix">
<li><a href="#">導航</a></li>
<li><a href="#">導航</a></li>
<li><a href="#">導航</a></li>
<li><a href="#">導航</a></li>
<li><a href="#">導航</a></li>
</ul>
</div>
</body>
</html>
實現效果如圖:
容易犯錯的地方:剛開始我把display:block;屬性寫在最前面,結果一直出不來,后來發現display屬性應該放在height和width屬性后面
我還學到一個知識點:關于父元素塌陷問題:
在文檔流中,父元素的高度默認是被子元素撐開的,也就是說父元素多高,子元素就多高
但是為子元素設置浮動以后,子元素就會完全脫離文檔流,此時將會導致子元素無法撐起父元素的高度,導致父元素的高度塌陷
由于父元素的高速塌陷了,則父元素下所有的元素都會向上移動,這樣會導致頁面布局混亂
所以我們在開發中一定要避免出席那高度塌陷的問題,這時候我們可以將父元素的高度寫死,這樣可避免塌陷的問題出現,但是一當高度寫死,父元素的高度將不能自動適應子元素的高度,所以這種方式是不推薦使用的
1
解決的方案:
根據W3C標準,在頁面中元素有一個隱含的屬性叫做Block Formatting Context
方案一:*(設置zoom為1和overflow為hidden)
當開啟元素的BFC后,元素會有以下特性:
父元素的垂直外邊距不會和子元素重疊
開啟BFC的元素不會被浮動元素所覆蓋
開啟BFC的元素可以包含浮動的子元素
那如何開啟元素的BFC呢?
設置元素浮動
設置元素的絕對定位
設置元素為inline-block(但是設置inline-block可以解決問題,但是會導致寬度丟失,所以不推薦使用這種方式)
將元素的overflow設置為一個非visible的值(推薦方式:將overflow:hidden這個是副作用最小的開啟BFC方式,所以可以這么說,以后若是再塌陷,就給父元素加上overflow:hidden屬性)
但需要注意的是:
在IE6以及以下的瀏覽器中并不支持BFC,所以使用這種方式并不能兼容IE6,在IE6中雖然沒有BFC,但有另一個隱藏屬性叫做hasLayout該屬性作用和和BFC類似。但在IE6瀏覽器可以通過開hasLayout來解決問題
開啟方式很多,我們可以直接用一種副作用最小的直接將元素的zoom設置為1,比如父元素是box1,我們可以在父元素中加上zoom:1;
在這里解釋一下zoom表示放大的意思,后邊跟著一個數值,寫幾就可以將元素放大幾倍,所以zoom:1表示不放大元素,但是可以通過該樣式可以開啟hasLayout.
但需要注意的是zoom屬性放IE6可以,別的瀏覽器比如Chrome就不行
****所以重頭戲來了:若我們想要兼容所有瀏覽器?
1.引入
三種引用方式
第一種 npm安裝
項目根目錄命令行執行
npm install uni-simple-router
1
第二種 插件市場(使用HBuilderX導入插件)
第三種 ZIP下載 解壓
2.項目中引入
import Vue from 'vue'
import {RouterMount} from 'uni-simple-router';
import Router from './router'
Vue.use(Router)
//...后續代碼
引入之后就開始我們的正式使用。
第一步先在項目的根目錄下創建一個router文件夾。
格式為:
router
|---modules
|---index.js
|---index.js
router中的modules文件夾是用來放路由表模板的。modules中的index.js內容為
const files = require.context('.', false, /.js$/)
const modules = []
files.keys().forEach(key => {
if (key === './index.js') return
const item = files(key).default
modules.push(...item)
})
export default modules
這個文件用來把同目錄下的js文件讀取并整合所有路由。
在這里創建的js文件代碼示例:
const home = [
{
//注意:path必須跟pages.json中的地址對應,最前面別忘了加'/'哦
path: '/pages/home/index',
aliasPath:'/', //對于h5端你必須在首頁加上aliasPath并設置為/
name: 'index',
meta: {
title: '首頁',
},
},
{
path: '/pages/home/list',
name: 'list',
meta: {
title: '列表',
},
},
]
export default home
第二步配置router下的index.js
import modules from './modules'
import Vue from 'vue'
//這里僅示范npm安裝方式的引入,其它方式引入請看最上面【安裝】部分
import Router from 'uni-simple-router'
Vue.use(Router)
//初始化
const router = new Router({
routes: [...modules]//路由表
});
//全局路由前置守衛
router.beforeEach((to, from, next) => {
next()
})
// 全局路由后置守衛
router.afterEach((to, from) => {
})
export default router;
第三步 就是配置main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import { RouterMount } from 'uni-simple-router'
App.mpType = 'app'
const app = new Vue({
...App
})
//v1.3.5起 H5端 你應該去除原有的app.$mount();使用路由自帶的渲染方式
// #ifdef H5
RouterMount(app,'#app');
// #endif
// #ifndef H5
app.$mount(); //為了兼容小程序及app端必須這樣寫才有效果
// #endif
這樣你的路由就配置好了。
如果不想繁瑣的配置modules下的文件,可以用webpack自動構建路由表
安裝
npm install uni-read-pages
1
配置 vue.config.js (可能需要手動創建)
const TransformPages = require('uni-read-pages')
const tfPages = new TransformPages({
//如果你需要獲取更多參數,那么請配置參數!
includes:['path','name','meta']
})
module.exports = {
configureWebpack: {
plugins: [
new tfPages.webpack.DefinePlugin({
ROUTES: JSON.stringify(tfPages.routes)
})
]
}
}
然后去pages.json里面更改配置,加入所需要的內容
最后配置路由表
import Vue from 'vue'
//這里僅示范npm安裝方式的引入,其它方式引入請看最上面【安裝】部分
import Router from 'uni-simple-router'
Vue.use(Router)
//初始化
const router = new Router({
routes:ROUTES //路由表
});
//全局路由前置守衛
router.beforeEach((to, from, next) => {
next()
})
// 全局路由后置守衛
router.afterEach((to, from) => {
})
export default router;
Echarts餅圖之數據展示
1、組件簡介
ECharts,一個使用 JavaScript 實現的開源可視化庫,可以流暢的運行在 PC 和移動設備上,兼容當前絕大部分瀏覽器(IE8/9/10/11,Chrome,Firefox,Safari等),底層依賴矢量圖形庫 ZRender,提供直觀,交互豐富,可高度個性化定制的數據可視化圖表。
官網鏈接:Echarts官網
W3C教程:W3C–Echarts教程
2、前端代碼實現
首先,下載庫,并引入到項目文件;
話不多說,直接上代碼。
/* 封裝的組件 HTML代碼
<div class="echart-wrap-box">
<div class="echart-content"></div>
</div>
*/
let echarts = require("echarts/echarts.min");
defaults: {
option: {
echartsObj: {},
tooltip: {//提示框浮層內容。
trigger: 'item',//數據項圖形觸發,主要在散點圖,餅圖等無類目軸的圖表中使用。
formatter: " : {c}萬人"http://提示框浮層內容格式器,{a}(系列名稱),(數據項名稱),{c}(數值), uicem00(百分比)
},
//如果系列沒有設置顏色,則會依次循環從默認列表中取顏色作為系列顏色。
color: ["#369DFD", "#32C8CA", "#49C872", "#F6CE36", "#EE607A", "#935CE3", "#3436C7", "#3E4D86"],
legend: {//圖例組件。
orient: 'vertical',//圖例列表的布局朝向:垂直的
x: '80%',//圖例組件離容器左側的距離。
y: '60%',//圖例組件離容器上側的距離。
// width: 100,
textStyle: {},//圖例文字的樣式
// left: 'right',//圖例組件離容器左側的距離。
top: 'center',//圖例組件離容器上側的距離。
data: [],//右側圖例小組件信息數據
},
series: [{//餅圖信息
name: '',
type: 'pie',//餅狀圖
radius: 140,//餅圖的半徑。
center: ['50%', '50%'],
minAngle: 5, //最小的扇區角度(0 ~ 360),用于防止某個值過小導致扇區太小影響交互
label: {//展示文本設置
normal: {
show: true,
formatter: " : {c}萬人",//視覺引導線內容格式器,{a}(系列名稱),(數據項名稱),{c}(數值), aey0ckg(百分比)
},
emphasis: { //文本樣式
show: true, //展示
textStyle: { //文本樣式
fontSize: '16',
fontWeight: '600',
}
}
},
labelLine: {//視覺引導線設置
normal: {
show: true
}
},
data: [],//餅狀圖信息數據,value(數量)和 name為默認數據;
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}],
},
onInit(event) {
vm = event.vmodel;
let data;//假設這里通過ajax獲取到了需要展示的數據;
if (data.length == 0) {
return
}
data = data.sort((a, b) => { return b.number - a.number });//數據根據數量number從大到小排序
if (data.length > 7) {//從大到小的第八個新增粉絲數量的年份 開始統一歸為 其他年份新增粉絲數量
let arr = data.slice(7);
let num = 0, rate = 0;
for (let i = 0; i < arr.length; i++) {//第七個之后累數量和比率
num += Number(arr[i].number);
rate += Number(arr[i].rate);
};
let objOtherYear = {
value: num,
name: '其他年份__nana新增粉絲數量',
rate: rate
};
let arr2 = data.slice(0, 7);
arr2.push(objOtherYear);
data = arr2;
data = data.sort((a, b) => { return b.number - a.number });//數據根據數量number從大到小排序
}
this.option.series[0].data = [];
this.option.legend.data = [];
for (let i = 0; i < data.length; i++) {
let seriesData = {
value: 0,
name: '',
rate: ''
};
seriesData.value = data[i].number;
seriesData.name = data[i].year;
seriesData.rate = data[i].rate;
this.option.series[0].data.push(seriesData);//給餅圖賦值數據
let legendData = {
name: '',
icon: 'circle',//強制設置圖形為:圓形
textStyle: {
color: '#000'
}
}
legendData.name = data[i].year;
this.option.legend.data.push(legendData);//給圖例組件賦值數據
}
},
callFun: avalon.noop,//點擊餅狀圖后的回調
isClickEchartsOUt: avalon.noop,//是否為餅圖外的點擊,父組件進行判斷后傳過來
onReady(event) {
this.echartsObj = echarts.init(event.target.children[0]);//初始化
this.echartsObj.setOption(this.option);
$(window).resize(() => {
this.echartsObj.resize();
});
let dataIndex;//保存選中扇區的序號
let _this = this;
this.$watch('isClickEchartsOUt', () => {
if (this.isClickEchartsOUt) {//如果不是餅狀圖扇區的點擊,則取消選中;
_this.echartsObj.dispatchAction({
type: 'pieUnSelect',//取消選中指定的餅圖扇形。
// 可選,系列 index,可以是一個數組指定多個系列
seriesIndex: 0,
// 可選,數據的 index
dataIndex: dataIndex,
})
}
});
// 處理點擊餅圖內部的事件
this.echartsObj.on('click', function (params) {
if (params.dataIndex != dataIndex) {//如果不是前一次選中的扇區,則取消選中
_this.echartsObj.dispatchAction({
type: 'pieUnSelect',//取消選中指定的餅圖扇形。
// 可選,系列 index,可以是一個數組指定多個系列
seriesIndex: 0,
// 可選,數據的 index
dataIndex: dataIndex,
})
}
dataIndex = params.dataIndex;
_this.echartsObj.dispatchAction({
type: 'pieSelect',//選中指定的餅圖扇形。
// 可選,系列 index,可以是一個數組指定多個系列
seriesIndex: 0,
// 數據的 index,如果不指定也可以通過 name 屬性根據名稱指定數據
dataIndex: dataIndex,
})
vm.callFun(params);//回調,傳點擊獲取到的數據給父組件
});
},
onDispose() {}
}
在我們的日常開發工作中,文本溢出截斷省略是很常見的一種需考慮的業務場景細節??瓷先?“稀松平?!?,但在實現上卻有不同的區分,是單行截斷還是多行截斷?多行的截斷判斷是基于行數還是基于高度?這些問題之下,都有哪些實現方案?他們之間的差異性和場景適應性又是如何?
一般來說,在做這樣文字截斷效果時我們更多是希望:
兼容性好,對各大主流瀏覽器有好的支持
響應式截斷,根據不同寬度做出調整
文本超出范圍才顯示省略號,否則不顯示省略號
省略號位置顯示剛好
基于上述的準則,下面我們通過編碼實踐,給出一些答案。
單行文本溢出省略
核心 CSS 語句
overflow: hidden;(文字長度超出限定寬度,則隱藏超出的內容)
white-space: nowrap;(設置文字在一行顯示,不能換行)
text-overflow: ellipsis;(規定當文本溢出時,顯示省略符號來代表被修剪的文本)
優點
兼容性好,對各大主流瀏覽器有好的支持
響應式截斷,根據不同寬度做出調整
文本溢出范圍才顯示省略號,否則不顯示省略號
省略號位置顯示剛好
短板
只支持單行文本截斷,并不支持多行
適用場景
適用于單行文本溢出顯示省略號的情況
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
.demo {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
多行文本溢出省略(-webkit-line-clamp)
核心 CSS 語句
overflow: hidden;(文本溢出限定的寬度就隱藏內容)
-webkit-line-clamp: 2;(用來限制在一個塊元素顯示的文本的行數, 2 表示最多顯示 2 行。 為了實現該效果,它需要組合其他的WebKit屬性)
display: -webkit-box;(和 -webkit-line-clamp: 2;結合使用,將對象作為彈性伸縮盒子模型顯示 )
-webkit-box-orient: vertical;(和 -webkit-line-clamp: 2;結合使用 ,設置或檢索伸縮盒對象的子元素的排列方式 )
text-overflow: ellipsis;(多行文本的情況下,用省略號“…”隱藏溢出范圍的文本)
優點
響應式截斷,根據不同寬度做出調整
文本溢出范圍才顯示省略號,否則不顯示省略號
瀏覽器原生實現,所以省略號位置顯示剛好
短板
兼容性一般: -webkit-line-clamp 屬性只有 WebKit 內核的瀏覽器才支持
適用場景
多適用于移動端頁面,因為移動設備瀏覽器更多是基于 WebKit 內核
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
.demo {
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
多行文本溢出省略(偽元素 + 定位)
核心 CSS 語句
position: relative; (為偽元素絕對定位)
overflow: hidden; (文本溢出限定的寬度就隱藏內容)
position: absolute;(給省略號絕對定位)
line-height: 18px; (結合元素高度,高度固定的情況下,設定行高, 控制顯示行數)
height: 36px; (設定當前元素高度)
::after {} (設置省略號樣式)
word-break: break-all; (如果文本中有英文,可以使一個單詞能夠在換行時進行拆分)
優點
兼容性好,對各大主流瀏覽器有好的支持
響應式截斷,根據不同寬度做出調整
短板
無法識別文字的長短,無論文本是否溢出范圍,一直顯示省略號
省略號顯示可能不會剛剛好,有時會遮住一半文字,跟文字沒有貼合的很緊密
適用場景
文字內容較多,確定文字內容一定會超過容器的
Demo
<div class="demo">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
1
2
3
.demo {
position: relative;
line-height: 18px;
height: 36px;
overflow: hidden;
word-break: break-all;
}
.demo::after {
content:"...";
font-weight:bold;
position:absolute;
bottom:0;
right:0;
padding:0 20px 1px 45px;
/ 為了展示效果更好 /
background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}
多行文本溢出省略(Float)
核心 CSS 語句
line-height: 20px;(結合元素高度,高度固定的情況下,設定行高, 控制顯示行數)
overflow: hidden;(文本溢出限定的寬度就隱藏內容)
float: right/left;(利用元素浮動的特性實現)
position: relative;(根據自身位置移動省略號位置, 實現文本溢出顯示省略號效果)
word-break: break-all;(如果文本中有英文,可以使一個單詞能夠在換行時進行拆分)
優點
兼容性好,對各大主流瀏覽器有好的支持
響應式截斷,根據不同寬度做出調整
文本溢出范圍才顯示省略號,否則不顯示省略號
短板
省略號顯示可能不會剛剛好,有時會遮住一半文字,跟文字沒有貼合的很緊密
適用場景
文字內容較多,確定文字內容一定會超過容器的
Demo
<div class="demo">
<div class="text">
床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光床前明月光
</div>
</div>
.demo {
height: 40px;
line-height: 20px;
overflow: hidden;
}
.demo .text {
float: right;
margin-left: -5px;
width: 100%;
word-break: break-all;
}
.demo::before {
float: left;
width: 5px;
content: "";
height: 40px;
}
.demo::after {
float: right;
content: "...";
height: 20px;
line-height: 20px;
padding-right: 5px;
text-align: right;
width: 3em;
margin-left: -3em;
position: relative;
left: 100%;
top: -20px;
padding-right: 5px;
/ 為了展示效果更好 /
background: -webkit-gradient(
linear,
left top,
right top,
from(rgba(255, 255, 255, 0)),
to(white),
color-stop(50%, white)
);
background: -moz-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: -o-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: -ms-linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
background: linear-gradient(
to right,
rgba(255, 255, 255, 0),
white 50%,
white
);
}
原理
keyCode 對于keypress 事件,該屬性聲明了被敲擊的鍵生成的 Unicode 字符碼。對于 keydown 和 keyup 事件,它指定了被敲擊的鍵的虛擬鍵盤碼。虛擬鍵盤碼可能和使用的鍵盤的布局相關。 因此我們可以根據keycode返回的字符碼來判斷用戶所按下的鍵,下面就是一個用于測試上下左右按鍵的js代碼,經過我的測試之后,返回37 38 39 40;
window.onload = function(){ var box = document.getElementById("box"); document.onkeydown = function(event){ event = event || window.event; console.log(event.keyCode); } }; 3
3.方塊的移動實際上就是坐標的改變,因此需要offsetLeft 和offsetTop 來獲得當前方塊的坐標,然后將坐標進行一定的更改,就可以實現移動的效果了,下面給出代碼
window.onload = function() { document.onkeydown = function(event) { event = event || window.event; //設置移動速度 var speed = 10; //當ctrl和方向按鍵同時按下時,提升移動速度 if(event.ctrlKey) { speed = 50; } //獲取div var box01 = document.getElementById("box01"); switch(event.keyCode) { /*keyCode返回按下按鍵的編碼 * 37 向左 * 38向上 * 39向右 * 40向下 */ case 37: box01.style.left = box01.offsetLeft - speed + "px"; break; case 39: box01.style.left = box01.offsetLeft + speed + "px"; break; case 38: box01.style.top = box01.offsetTop - speed + "px"; break; case 40: box01.style.top = box01.offsetTop + speed + "px"; break; } }; };
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #box01 { width: 100px; height: 100px; background-color: #008000; position: absolute; } </style> <script type="text/javascript"> window.onload = function() { //獲取div var box01 = document.getElementById("box01"); //設置移動速度 var speed = 10; //設置移動的方向 var dir = 0; setInterval(function() { switch(dir) { /*keyCode返回按下按鍵的編碼 * 37 向左 * 38向上 * 39向右 * 40向下 */ case 37: box01.style.left = box01.offsetLeft - speed + "px"; break; case 39: box01.style.left = box01.offsetLeft + speed + "px"; break; case 38: box01.style.top = box01.offsetTop - speed + "px"; break; case 40: box01.style.top = box01.offsetTop + speed + "px"; break; } }, 50) document.onkeydown = function(event) { event = event || window.event; //當ctrl和方向按鍵同時按下時,提升移動速度 if(event.ctrlKey) { speed = 50; } else { speed = 10; } //使dir等于keycode的值 dir = event.keyCode; //當鼠標松開時,停止移動 ---如果不寫這一個會造成無法停止移動的效果 document.onkeyup = function() { dir = 0; }; }; }; </script> </head> <body> <div id="box01"></div> </body>
</html>
————————————————
版權聲明:本文為CSDN博主「loving-cat」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42878211/article/details/104558443
vuex的基礎
1,狀態管理(共享)
緩存數據==>內存, 只要刷新頁面,數據就丟了
訂單,詳情等,,,不適用vuex緩存數據
用于
非父子通信的問題
緩存后端數據,提高用戶體驗
注意:
vuex只能有一個store,
為了防止多人修改,我們切割成子store, 再合并成唯一一個大的store對象
模塊寫法
import Vue from 'vue' import Vuex from 'vuex' import cinema from './module/cinemaModule' import tabbar from './module/tabbarshowModule' Vue.use(Vuex) const store = new Vuex.Store({ state: { }, // "全局"狀態 mutations:{ },//唯一修改狀態的地方 //異步處理 actions:{ }, // 對上面的“全局狀態”進行數據處理, 類似于vue中的計算屬性 getters:{ }, modules:{ cinema, tabbar } }) export default store
const module = { namespaced:true, //命名空間 state :{ cinemaList:[] }, actions:{ store.commit("setCinemaList",res.data.data.cinemas) //支持傳參 }, mutations:{ setCinemaList(state,data){ console.log("setCinemaList",data) state.cinemaList = data } }, getters:{ topDataList(state){ //state形參s, vuex自動調用時候,傳來值 return state.cinemaList.slice(0,5) } } } export default module
import createPersistedState from "vuex-persistedstate"; //在index.js頁面加入這個插件 // 加入下面的代碼 const store = new Vuex.Store({ plugins: [createPersistedState({ reducer(val){ return { user: val.user } } })]
————————————————
版權聲明:本文為CSDN博主「m0_46436313」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/m0_46436313/article/details/104572076
中介者對象踐行了最少知識原則,指一個對象盡可能少的了解別的對象,從而盡量減少對象間耦合程度。這樣各個對象只需關注自身實現邏輯,對象間的交互關系交由中介者對象來實現和維護。
需求背景:
手機購買頁面,在購買流程中,可以選擇手機的顏色及輸入購買數量,同時頁面有兩個展示區域,分別向用戶展示剛選擇好的顏色和數量。還有一個按鈕動態顯示下一步的操作,我們需要查詢該顏色手機對應的庫存,如果庫存數量少于這次購買的數量,按鈕將被禁用并顯示庫存不足,反之按鈕可以點擊并顯示放入購物車。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購買商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請選擇</option> <option value="red">紅色</option> <option value="blue">藍色</option> </select> 輸入購買數量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您輸入了數量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請選擇手機顏色和購買數量</button> </body> <script> // 最初級的寫法 var colorSelect = document.getElementById('colorSelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'); var goods = { 'red': 3, 'blue': 6 } colorSelect.onchange = function(){ var color = this.value, number = numberInput.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數量是否為正整數 nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } if(number > stock){ //當前選擇數量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } numberInput.oninput = function(){ var color = colorSelect.value, number = this.value, stock = goods[color] colorInfo.innerHTML = color; if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數量是否為正整數 nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } if(number > stock){ //當前選擇數量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } </script> </html>
在上個示例中,對象間聯系高度耦合,只是兩個輸入框還好,但如果有多個的話,相互聯系就非常復雜了,此時就要考慮用到中介者模式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>中介者模式 購買商品</title> </head> <body> 選擇顏色: <select id="colorSelect"> <option value="">請選擇</option> <option value="red">紅色</option> <option value="blue">藍色</option> </select> 選擇內存: <select id="memorySelect"> <option value="">請選擇</option> <option value="32G">32G</option> <option value="16G">16G</option> </select> 輸入購買數量: <input type="text" id="numberInput"> 您選擇了顏色:<div id="colorInfo"></div><br> 您選擇了內存:<div id="memoryInfo"></div><br> 您輸入了數量:<div id="numberInfo"></div><br> <button id="nextBtn" disabled>請選擇手機顏色、內存和購買數量</button> </body> <script> var goods = { 'red|32G': 3, 'red|16G': 0, 'blue|32G': 1, 'blue|16G': 6 } //引入中介者 var mediator = (function(){ var colorSelect = document.getElementById('colorSelect'), memorySelect = document.getElementById('memorySelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), memoryInfo = document.getElementById('memoryInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'); return { changed: function(obj){ var color = colorSelect.value, memory = memorySelect.value, number = numberInput.value, stock = goods[color + '|' + memory]; if(obj == colorSelect){ //如果改變的是選擇顏色下拉框 colorInfo.innerHTML = color; }else if(obj == memorySelect){ memoryInfo.innerHTML = memory; }else if(obj == numberInput){ numberInfo.innerHTML = number; } if(!color){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機顏色'; return; } if(!memory){ nextBtn.disabled = true; nextBtn.innerHTML = '請選擇手機內存'; return; } if(!number){ nextBtn.disabled = true; nextBtn.innerHTML = '請填寫手機數量'; return; } if( ( (number-0) | 0 ) !== number-0 ){ //用戶輸入的購買數量是否為正整數 nextBtn.disabled = true; nextBtn.innerHTML = '請輸入正確的購買數量'; return; } if(number > stock){ //當前選擇數量大于庫存量 nextBtn.disabled = true; nextBtn.innerHTML = '庫存不足'; return; } nextBtn.disabled = false; nextBtn.innerHTML = '放入購物車'; } } })() colorSelect.onchange = function(){ mediator.changed(this) } memorySelect.onchange = function(){ mediator.changed(this) } numberInput.oninput = function(){ mediator.changed(this) } //以后如果想要再增加選項,如手機CPU之類的,只需在中介者對象里加上相應配置即可。 </script> </html>在實際開發中,還是要注意選擇利弊,中介者對象因為包含對象間交互的復雜性,所以維護成本可能也會較高。在實際開發中,最優目的還是要快速完成項目交付,而非過度設計和堆砌模式。有時對象間的耦合也是有必要的,只有當對象間復雜耦合確實已經導致調用與維護難以為繼,才考慮用中介者模式。
————————————————
版權聲明:本文為CSDN博主「一期一會」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_34832846/article/details/85989945
彈性布局(Flex)
隨著移動互聯網的發展,對于網頁布局來說要求越來越高,而傳統的布局方案對于實現特殊布局非常不方便,比如垂直居中。
2009年,W3C 提出了一種新的方案----Flex 布局,可以簡便、完整、響應式地實現各種頁面布局。目前,它已經得到了所有瀏覽器的支持,這意味著,現在就能很安全地使用這項功能。
下面是一些彈性布局的基本語法:
兩部分:
1. 語法是添加到父容器上的 display : flex;(彈性盒子的標志哦?。。。? flex-direction: row; 布局的排列方向 (主軸排列方向) row 默認值,顯示為行。方向為當前文檔水平流方向,默認情況下是從左往右。 row-reverse 顯示為行。但方向和row屬性值是反的 column 顯示為列 column-reverse 顯示為列。但方向和column屬性值是反的 flex-wrap : nowrap; 是否進行換行處理。 nowrap; 默認值,不換行處理 wrap; 換行處理 wrap-reverse; 反向換行 flex-flow : flex-direction flex-wrap 復合寫法 (是有順序的)。 justify-content ; 屬性決定了主軸方向上子項的對齊和分布方式。 flex-start : 子項都去起始位置對齊。 flex-end : 子項都去結束位置對齊。 center : 子項都去中心位置對齊。 space-between : 表現為兩端對齊。多余的空白間距在元素中間區域分配,兩邊沒寬。 space-around : 邊緣兩側的空白只有中間空白寬度一半即每個塊都有左右間距。 space-evenly :每個flex子項兩側空白間距完全相等。 align-items : 每一行中的子元素上下對齊方式。 stretch;默認值,flex子項拉伸 flex-start;容器頂部對齊 center;容器居中對齊 flex-end;容器底部對齊 align-content : 跟justify-content相反的操作。側軸的對齊方式。(最少需要兩行才能看出效果,因為他是多行的一個上下對齊方式) 默認:多行下,有幾行就會把容器劃分為幾部分,默認就是stretch拉伸的。 值跟justify-content取值是相同的。 2. 語法是添加到子容器上的? order : 排序(值越大越后) 0:默認值 eg:1234 1:放在后面 eg:1342 -2:放在前面 eg:2134 flex-grow : 擴展 ( 想看到擴展的效果,必須有空隙 ) 0 : 默認值 , 不去擴展 0.5:占空隙的一半 1 : 去擴展 , 會把空白區域全部沾滿 ( 注:子元素會按照設置的比例值來分配空隙,如果比例值總和小于1,那么會有空隙,如果比例值總和大于等于1,那么就沒有空隙。) flex-shrink : 收縮 正常默認值是1 0表示不收縮,.5收縮小一些,2收縮大一些。(大小是跟正??s放1進行比較的) flex-basis : 跟flex-shrink/flex-grow很像。 flex-shrink/flex-grow是設置一個比例值,flex-basis是設置一個具體值。 flex : 一種復合寫法 flex-grow flex-shrink flex-basis flex:1; flex : 1 1 0 flex:0; flex : 0 1 0 algin-self: 跟align-items操作很像,區別就是只是針對某一個子項。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{margin: 0;padding: 0;} ul{list-style: none;} a{text-decoration: none;} img{display: block;} .box1{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;justify-content: center;align-items: center;} .box1 div{width: 30px;height: 30px;border-radius:50%;background: black;} .box2{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;align-items: center;justify-content: space-between;} .box2 div{width: 30px;height: 30px;border-radius:50%;background: black;margin: 10px;} .box2 div:nth-of-type(1){align-self: flex-start;} .box2 div:nth-of-type(2){align-self: flex-end;} .box3{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;align-items: center;justify-content: space-between;} .box3 div{width: 30px;height: 30px;border-radius:50%;background: black;margin: 10px;} .box3 div:nth-of-type(1){align-self: flex-start;} .box3 div:nth-of-type(3){align-self: flex-end;} .box4{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box4 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box4 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} .box5{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box5 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box5 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} .box6{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box6 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box6 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} #box{width: 400px;height: 400px;margin: 20px auto;border: 1px springgreen solid; perspective: 500px;perspective-origin: right top;} #box .main{position: relative;width: 150px;height: 150px;margin: 125px; transform-style: preserve-3d;transition: 4s;transform-origin: center center -50px;} #box .main .box1{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;} #box .main .box2{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;left: 150px;transform-origin:left; transform:rotateY(90deg);} #box .main .box3{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;left: -150px;transform-origin:right; transform:rotateY(-90deg);} #box .main .box4{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;top: -150px;transform-origin:bottom; transform:rotateX(90deg);} #box .main .box5{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;top: 150px;transform-origin:top; transform:rotateX(-90deg);} #box .main .box6{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;transform:translateZ(-150px) rotateY(180deg);} #box:hover .main{transform:rotateY(360deg);} </style> </head> <body> <div id="box"> <div class="main"> <div class="box1"> <div></div> </div> <div class="box2"> <div></div> <div></div> </div> <div class="box3"> <div></div> <div></div> <div></div> </div> <div class="box4"> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> </div> <div class="box5"> <div> <li></li> <li></li> </div> <div> <li></li> </div> <div> <li></li> <li></li> </div> </div> <div class="box6"> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> </div> </div> </div> </body> </html>注:默認情況下,在彈性盒子中的子元素的左右排列的。 注: 水平是主軸的時候:默認情況下,當寬高不寫的時候,寬度由內容決定,高度由父容器決定。 垂直是主軸的時候:默認情況下,當寬高不寫的時候,寬度由父容器決定,高度由內容決定。 注:當子項的總寬度大于父容器的時候,會自動收縮的(彈性的優先級是大于自身固定大小的) 注:當子項的內容已經達到了父容器最小寬高的時候,就會出現溢出的現象。 注:彈性布局中用的頻率比較多的語法: display : flex; flex-direction; justify-content; align-items; flex; 注:彈性布局的優勢是做一維布局,網格布局的優勢是做二維布局。
下面是彈性布局骰子案例代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> *{margin: 0;padding: 0;} ul{list-style: none;} a{text-decoration: none;} img{display: block;} .box1{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;justify-content: center;align-items: center;} .box1 div{width: 30px;height: 30px;border-radius:50%;background: black;} .box2{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;align-items: center;justify-content: space-between;} .box2 div{width: 30px;height: 30px;border-radius:50%;background: black;margin: 10px;} .box2 div:nth-of-type(1){align-self: flex-start;} .box2 div:nth-of-type(2){align-self: flex-end;} .box3{width: 150px;height: 150px;display: flex;border: 1px black solid;margin: 20px auto;border-radius: 10px;align-items: center;justify-content: space-between;} .box3 div{width: 30px;height: 30px;border-radius:50%;background: black;margin: 10px;} .box3 div:nth-of-type(1){align-self: flex-start;} .box3 div:nth-of-type(3){align-self: flex-end;} .box4{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box4 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box4 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} .box5{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box5 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box5 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} .box6{width: 150px;height: 150px;border: 1px black solid;margin: 20px auto;border-radius: 10px;display: flex;flex-direction: column;} .box6 div{height: 50%;display: flex;flex-direction: row;justify-content: space-around;align-items: center;} .box6 div li{display: block; width: 30px;height: 30px;border-radius:50%;background: black;} #box{width: 400px;height: 400px;margin: 20px auto;border: 1px springgreen solid; perspective: 500px;perspective-origin: right top;} #box .main{position: relative;width: 150px;height: 150px;margin: 125px; transform-style: preserve-3d;transition: 4s;transform-origin: center center -50px;} #box .main .box1{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;} #box .main .box2{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;left: 150px;transform-origin:left; transform:rotateY(90deg);} #box .main .box3{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;left: -150px;transform-origin:right; transform:rotateY(-90deg);} #box .main .box4{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;top: -150px;transform-origin:bottom; transform:rotateX(90deg);} #box .main .box5{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;top: 150px;transform-origin:top; transform:rotateX(-90deg);} #box .main .box6{position: absolute;background:limegreen;left: 0;top: 0; width: 150px;height: 150px;transform:translateZ(-150px) rotateY(180deg);} #box:hover .main{transform:rotateY(360deg);} </style> </head> <body> <div id="box"> <div class="main"> <div class="box1"> <div></div> </div> <div class="box2"> <div></div> <div></div> </div> <div class="box3"> <div></div> <div></div> <div></div> </div> <div class="box4"> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> </div> <div class="box5"> <div> <li></li> <li></li> </div> <div> <li></li> </div> <div> <li></li> <li></li> </div> </div> <div class="box6"> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> <div> <li></li> <li></li> </div> </div> </div> </div> </body> </html>實際效果:
![]()
————————————————
版權聲明:本文為CSDN博主「GLINLIND」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/GLINLIND/article/details/104572530
藍藍設計的小編 http://www.syprn.cn