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: "{b} : {c}万人"//提示框浮层内容格式器,{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
//如果系列没有设置颜色,则会依次循环从默认列表中取颜色作为系列颜色。
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: "{b} : {c}万人",//视觉引导线内容格式器,{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
},
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收缩大一些。(大小是跟正常缩放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
前言:
做网页项目时想要背景是动态的,推荐两个我觉得比较可以的js动态背景。
随鼠标的移动而移动的线条,具体效果看图:
你焦点在哪,那么那里的线条就会汇聚到你的焦点处。
用法:将js声明到body内即可,我是放置在body底部的
<script type="text/javascript" src="https://cdn.bootcss.com/canvas-nest.js/1.0.1/canvas-nest.min.js"></script>
1
可以鼠标点击产生字的,如图:
用法和第一个类似,不过在这个js文件前得先引入jquery:
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2/dist/jquery.min.js"></script> <script type="text/javascript"> /* 鼠标 */ var a_idx = 0; jQuery(document) .ready( function($) { $("body") .click( function(e) { var a = new Array("@健身", "@学习", "@机车", "@摄影", "@自由", "@考研", "@自律", "@独立", "@厨艺", "@橘子", "@交友", "@爱媳妇", "@爱家人"); var $i = $("<span></span>") .text(a[a_idx]); a_idx = (a_idx + 1) % a.length; var x = e.pageX, y = e.pageY; $i .css({ "z-index" : 999999999999999999999999999999999999999999999999999999999999999999999, "top" : y - 20, "left" : x, "position" : "absolute", "font-weight" : "bold", "color" : "rgb(" + ~~(255 * Math .random()) + "," + ~~(255 * Math .random()) + "," + ~~(255 * Math .random()) + ")" }); $("body").append($i); $i.animate({ "top" : y - 180, "opacity" : 0 }, 1500, function() { $i.remove(); }); }); }); </script>
这里使用的是cdn形式的jquery即不用将jq放入本地文件再引入,直接访问网络上的jq即可,还有就是点击产生的字可以自行修改。
————————————————文章目录
一、HTML的概述
标签的嵌套缩进
如图所示<html>为外层标签,称为父元素,<head>和<body>为内层标签,称为子元素。其中<head>与<body>又互称为兄弟元素
<!DOCTYPE html>
声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。
声明必须是 HTML 文档的第一行,位于 <html> 标签之前。
<!DOCTYPE> 声明没有结束标签。
<!DOCTYPE> 声明对大小写不敏感。
在 HTML 4.01 中有三种 <!DOCTYPE> 声明。在 HTML5 中只有一种:<!doctype html>
我们学习的是HTML5,所以我们不过多对HTML4的声明做过多解释。
如果上述对<!doctype html>的概述不清楚的话,
那记住以下两点即可,1. 不分大小写,2.在HTML的网页<html>标签之前加上<!doctype html>就可以啦。
图示为 HTML DOM树,DOM:Document Object Model(文档对象模型)
2. 标签、属性
一个标签可能有多个属性,属性先后与顺序无关
“=” 为赋值符号
属性与属性之间用空格隔开
附:补充上一节课网站和网页的笔记:
HTML网页的编码为 utf-8
网站可以理解成一个文件夹,而网页就是一个个的文件
网页的文件后缀常见的有:htm、html、jsp、php、asp
网站的文件结构通常包含 images文件夹,css文件夹,js文件夹,
一个简单的网页,的文件目录通常由 images、css、js,作用顾名思义,就是存放相对应的文件资源
附:img标签的详细介绍
<img> 标签有两个必需的属性:src 和 alt。
注释:从技术上来说,图像并不会插入到HTML页面中去,而是通过 src的值(URL) 链接到HTML页面上的,<img>标签的作用是为被引用的图像创建占位符。
<img>标签常用的属性有src、alt、width、height、title
src和alt为 img 标签的必需元素。
话不多说,看图,为你们讲解代码。
看网站的演示图和代码图,想必大家都很清楚了吧。
(为了更直观的看到效果,我写了div和div的样式,1px粗的红色实线边框,这里的代码以后再具体详解)
title和alt 的区别别,体现在 第 11 行和第 14 行,想必大家就能看出来了吧
i. alt 属性是在图片不能正常显示时出现的文本提示。
ii. title 属性是在鼠标在移动到元素上的文本提示。
width和height的作用,用来规定图像的宽度和高度,单位为 像素(px)
src路径,由于我的文件夹结构为 index.html文件和 images 文件夹。
所以 src 的路径为 src="images/图片.后缀",即src="URL"
URL即(Uniform Resource Locator,统一资源定位符,在WWW上,每一信息资源都有统一的且在网上唯一的地址。
简单的理解URL,就是网址,地址
如果图片路径引用错误,都会导致网页中的图片无法正常显示! 如,第 14 行和第 20 行代码。
以上为img标签的常见用法。在我们写网页的时候,建议img写上 src、alt、width、height这四个属性,是否需要 title 具体看网站的功能。
以上就是,第二课、Web前端开发之HTML基础的全部内容了,感谢阅读
————————————————
版权声明:本文为CSDN博主「MineChen」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/MineSu/article/details/104549536
蓝蓝 http://www.lanlanwork.com