# 图标选择后点亮
<!--angular代码-->
<span *ngFor="let item of itemList">
<img
[src]="idx===selectIndex ? iconSelect : icon"
(click)="()=>{selectIndex=idx}"
/>
</span>
定义变量selectIndex,当其等于原坐标的时候,使用点击时的图标
# tab栏置于底部
/*对于跟组件*/
{
height:100%;
}
/*对于跟组件中,底部tar栏上面的组件,通常是路由*/
{
display:flex;
flex-direction:column;
align-items:stretch;
flex:1;
}
/*布局结束后,底部栏会被撑到最下方*/
# 垂直网格布局
/*容器样式[容器组件]*/
{
padding: 5px 0;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
display: grid;
grid-auto-flow: row;//溢出时新增一行
place-content: stretch;
place-items: center;
overflow-x: hidden;
overflow-y: auto;
}
在组件中设置变量
<!--angular代码-->
<div
class="grid-container"
[ngStyle]="{
'grid-template-rows': templateRows,
'grid-template-columns': templateColumns,
'grid-gap': gridGap
}"
>
<ng-content></ng-content>
</div>
在逻辑中设置
export class VerticalGridComponent implements OnInit {
@Input() itemWidth = '4rem';
@Input() itemHeight = '4rem';
@Input() gridGap = '5px';
constructor() {}
ngOnInit() {}
/* 响应式布局网格,auto-fill 用来在空间足够时尽可能的填充该位置,minmax 是最小和最大的宽度 */
get templateRows() {
return `minmax(auto-fill, ${this.itemHeight})`;
}
/**
* CSS Grid Layout 的模版列表达式
*/
get templateColumns() {
return `repeat(auto-fill, minmax(${this.itemWidth}, 1fr))`;
}
}
调用时,通过该百年itemWidth
的值来决定每行显示几列。例如本例中itemWidth
为10rem
就是两列20rem
就是一列
<app-vertical-grid [itemWidth]="'20rem'" [itemHeight]="'2rem'">
<div></div>
</app-vertical-grid>
# 设置在一个盒子内的上下滚动
通常在一个app中,底部的栏是固定的,但是上面是可滚动的长页面
/*host为整个页面的样式*/
:host {
display: flex;
flex-direction: column;
align-items: stretch;
flex: 1;
overflow-y: hidden;
}
/* 让中间部分可滚动,需要计算高度,页面高度减去头部和尾部 */
/*main为中间内容*/
.main {
flex-grow: 1;
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
overscroll-behavior-y: contain;
height: calc(100% - 3rem);
}
# 卡片
网格布局并不是一个元素只能占一个格子。
例如我们将创建一个左面为图片,右面从上到下分别是简介、标签、价格的卡片。
.container {
/*卡片的容器*/
display: grid;
grid-template-columns: 10rem 1fr;//每一列的尺寸
grid-template-rows: 3rem 1fr 1rem 2rem;//每一排的尺寸
grid-gap: 5px; //格子之间间隔
grid-template-areas://区域划分,‘.’代表无内容
'image title'
'image .'
'image tags'
'image price';
place-content: stretch;//是align-content(垂直格子和间隔如何分布)和justify-content(水平格子和间隔如何分布)的简写
place-items: stretch;//是align-items(内容在格子里垂直如何分布,stretch为内容占满格子)和justify-items(内容在格子里水平如何分布)的简写
}
.product-image {
grid-area: image;
object-fit: contain;
width: 9rem;
height: 9rem;
}
.product-title {
grid-area: title;
}
.product-tags {
grid-area: tags;
}
.product-price {
grid-area: price;
}
# 轮播图
模板为
<!--angular语法-->
<div class="container" [ngStyle]="{ height: sliderHeight }">##控制轮播图片的高度
<div class="image-slider" (scroll)="handleScroll($event)" #imageSlider>##滑动时触发事件
<img
*ngFor="let slider of sliders"
[src]="slider.imgUrl"
[alt]="slider.caption"
/>
</div>
<div class="nav-section">
<span
*ngFor="let _ of sliders; let idx = index"
class="slide-button"
[ngClass]="{ 'slide-button-select': idx === selectedIndex }"
>
</span>
</div>
</div>
样式为
.container {
position: relative;
overflow: hidden;
}
.container .image-slider {
display: flex;
overflow-x: scroll;
scroll-snap-type: x mandatory;/*在x轴添加吸附效果*/
scroll-behavior: smooth;/*使得元素的移动产生移动效果*/
-webkit-overflow-scrolling: touch;/*在手机上可以通过触摸滚动*/
}
.container img {
width: 100%;
height: 100%;
object-fit: cover;
scroll-snap-align: start;/*吸附参考标准*/
}
.nav-section {
position: absolute;
bottom: 0;
width: 100%;
opacity: 0.5;
color: #fff;
background-color: #000;
display: flex;
justify-content: flex-end;
align-items: stretch;
}
.nav-section .slide-button {
display: flex;
width: 10px;
height: 10px;
background-color: #fff;
text-decoration: none;
border-radius: 50%;
margin: 5px;
}
.container .image-slider::-webkit-scrollbar {
display: none;
width: 0 !important;
}
.nav-section .slide-button-select {
background-color: #e02f29;
}
逻辑为
import {
Component,
OnInit,
Input,
ViewChild,
ElementRef,
Renderer2,
AfterViewInit,
OnDestroy,
ChangeDetectionStrategy
} from '@angular/core';
export interface ImageSlider {
id: number;
imgUrl: string;
link: string;
caption: string;
}
@Component({
selector: 'app-image-slider',
templateUrl: './image-slider.component.html',
styleUrls: ['./image-slider.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ImageSliderComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() sliders: ImageSlider[] = [];/*外部传入的图片的相关数据*/
@Input() sliderHeight = '160px';
@Input() intervalBySeconds = 2;
@ViewChild('imageSlider', { static: true })
imgSlider: ElementRef;/*取到名为imgSlider的元素数*/
selectedIndex = 0;
constructor(private rd2: Renderer2) {}
intervalId;
ngOnInit() {}
ngAfterViewInit(): void {
if (this.intervalBySeconds <= 0) {
return;
}
this.intervalId = setInterval(() => {
this.rd2.setProperty(/*添加属性*/
this.imgSlider.nativeElement,/*对应的图片容器元素*/
'scrollLeft',/*向左移动的距离*/
(this.getIndex(++this.selectedIndex) *
this.imgSlider.nativeElement.scrollWidth) /
this.sliders.length/*计算得到现在应向左移动的距离*/
);
}, this.intervalBySeconds * 1000);
}
ngOnDestroy(): void {
clearInterval(this.intervalId);/*解决内存泄漏*/
}
getIndex(idx: number): number {
/*获取现在应该是第几张图*/
return idx >= 0
? idx % this.sliders.length
: this.sliders.length - (Math.abs(idx) % this.sliders.length);
}
handleScroll(ev) {
/*在手动滑动轮播图后,更改this.selectedIndex。如果没有此函数,例如图片在2,手动划到了1,下一次,图片仍然自动划到3*/
const ratio =
ev.target.scrollLeft / (ev.target.scrollWidth / this.sliders.length);
this.selectedIndex = Math.round(ratio);
}
}
# 两栏布局,左栏固定,右栏滚动(常见开放文档页面)
使用fixed布局
.left{
position:fixed;
width:200px;
left:0;
top:0;
}
.right{
position: relative;
marginLift:200px;
}
将左栏黏贴
.left{
/*height: calc(100vh - 90px);//常用来设置高度*/
top: 0;
float:left;
position: sticky;/*将其粘帖在某个地方不动*/
position: -webkit-sticky;
}
.right{
float:left;
}
sticky:
元素根据正常文档流进行定位,然后相对它的*最近滚动祖先(nearest scrolling ancestor)*和 containing block (opens new window) (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于
top
,right
,bottom
, 和left
的值进行偏移。偏移值不会影响任何其他元素的位置。该值总是创建一个新的层叠上下文(stacking context)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的
overflow
是hidden
,scroll
,auto
, 或overlay
时),即便这个祖先不是真的滚动祖先。这个阻止了所有“sticky”行为sticky生效条件:
1、必须指定top、bottom、left、right其中的一个
2、达到设定阔值,top为0时与fixed相同,top大于0时,加成relative属性
fixed与sticky的区别:
sticky定位可以被认为是relative和fixed的混合。粘性定位的元素被视为相对定位,直到它超过指定的阈值,此时它被视为固定的,直到它到达其父母的边界。