Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
[feature] 实现了top和bottom 固定的基础代码
Browse files Browse the repository at this point in the history
  • Loading branch information
elvismile committed Nov 24, 2022
1 parent fde563e commit a3417d0
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 10 deletions.
1 change: 1 addition & 0 deletions doc/TDesign.Docs.Shared/Layouts/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<TMenuItem Link="components/space">Space 间距</TMenuItem>
</TMenuItemGroup>
<TMenuItemGroup Title="导航">
<TMenuItem Link="components/affix">Affix 固钉</TMenuItem>
<TMenuItem Link="components/breadcrumb">Breadcrum 面包屑</TMenuItem>
<TMenuItem Link="components/menu">Menu 导航菜单</TMenuItem>
<TMenuItem Link="components/step">Steps 步骤条</TMenuItem>
Expand Down
32 changes: 32 additions & 0 deletions doc/TDesign.Docs.Shared/Pages/Components/AffixPage.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@page "/components/affix"
<PageHeader Title="Affix 固钉">
在指定的范围内,将元素固定不动。
</PageHeader>
<HighlightAlert />
<Example Title="基础固钉">
<Description>@Code.Create("适用于页面结构简单的场景,默认容器是 `body`。")</Description>
<RunContent>
<div id="div-box" style="overflow-y:auto;height:200px;">
<p>内容</p>
<TAffix Container="div-box" OffsetTop="50">
<TButton>按 钮</TButton>
</TAffix>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p>
<p>内容</p><p>内容</p>
<p>内容</p><p>内容</p>
<p>内容</p>


</div>
</RunContent>
</Example>
2 changes: 1 addition & 1 deletion doc/TDesign.Docs.Shared/Pages/Components/SwitchPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
用于两个互斥选项,用来打开或关闭选项的选择控件。
</PageHeader>
<HighlightAlert />
<Example Title="基本开关">
<Example Title="基础开关">
<Description>不带描述,最基础的开关。</Description>
<RunContent>
<TSwitch @bind-Value="BaseValue" />
Expand Down
109 changes: 101 additions & 8 deletions src/TDesign/Components/TAffix.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.JSInterop;

namespace TDesign;

Expand All @@ -19,12 +15,12 @@ public class TAffix : BlazorComponentBase, IHasChildContent
/// <summary>
/// 距离容器顶部达到指定距离后触发固定,默认值0 。
/// </summary>
[Parameter]public int OffsetBottom { get; set; }
[Parameter] public int OffsetBottom { get; set; }

/// <summary>
/// 距离容器底部达到指定距离后触发固定,默认值0 。
/// </summary>
[Parameter]public int OffsetTop { get; set; }
[Parameter] public int OffsetTop { get; set; }

/// <summary>
/// 固钉定位层级,样式默认为 500 。
Expand All @@ -34,6 +30,103 @@ public class TAffix : BlazorComponentBase, IHasChildContent
/// <summary>
/// 指定滚动的容器。滚动容器不是body时,传入滚动容器的id。
/// </summary>
[Parameter]public string Container { get; set; }
[Parameter] public string? Container { get; set; }

private bool _fixed = false;

private string _fixedStyle = string.Empty;

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var objRef = DotNetObjectReference.Create(this);
var popperWrapper = await JS.Value.InvokeAsync<IJSInProcessObjectReference>("import", "./_content/TDesign/tdesign-blazor.js");
await popperWrapper.InvokeVoidAsync("affix.init", Container, objRef);

}
await base.OnAfterRenderAsync(firstRender);
}
private const string CSS_NAME = "t-affix";

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="builder"></param>
protected override void BuildCssClass(ICssClassBuilder builder)
{
if (_fixed)
{
if (!builder.Contains(CSS_NAME))
{
builder.Append(CSS_NAME);
}
}
else
{
if (builder.Contains(CSS_NAME))
{
builder.Remove(CSS_NAME);
}
}
base.BuildCssClass(builder);
}

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="attributes"></param>
protected override void BuildAttributes(IDictionary<string, object> attributes)
{
attributes["style"] = HtmlHelper.CreateStyleBuilder().Append(_fixedStyle, _fixed);
base.BuildAttributes(attributes);
}

/// <summary>
/// js 调用的方法,onscroll事件中调用并回传当前的top和bottom值。
/// </summary>
/// <param name="top"></param>
/// <param name="bottom"></param>
/// <param name="height"></param>
[JSInvokable]
public void OnScrollChanged(int top, int bottom, int height)
{
if (FixedTop())
{
TryFixChange(top >= OffsetTop);
}
else
{
TryFixChange(bottom >= OffsetBottom);
}
}

private bool FixedTop() => OffsetTop > 0;

private void TryFixChange(bool value)
{
if (OffsetTop == 0 && OffsetBottom == 0)
{
return;
}
if (value != _fixed)
{
_fixed = value;
if (_fixed)
{
_fixedStyle = FixedTop() ? $"top:{OffsetTop}px;" : $"bottom:{OffsetBottom}px;";
}
else
{
_fixedStyle = string.Empty;
}
StateHasChanged();
}
}
}

27 changes: 26 additions & 1 deletion src/TDesign/wwwroot/tdesign-blazor.js
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@

/**
* @description 组件 affix 用到的js对象。
*/
let affix = {
/**
* 组件初始化方法,用于给指定的元素绑定onscroll事件。
* @function affix.init
* @param {String} id HTML元素id,如果为空则使用document.body
*/
init: function (id, dotnetRef) {
console.log('[info] affix.init ', id)
let el = id ? document.getElementById(id) : document.body
el.onscroll = function () {
let top = el.scrollTop
let height = el.scrollHeight
let bottom = height - top - el.clientHeight
dotnetRef.invokeMethodAsync("OnScrollChanged", top, bottom, height)
}

},
show: function(top, bottom, height){
console.log(`[info]affix.box top:${top}, bottom:${bottom}, height:${height}`)
},
}

export { affix }

0 comments on commit a3417d0

Please sign in to comment.