-
Notifications
You must be signed in to change notification settings - Fork 659
移动端事件优化 #2775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
移动端事件优化 #2775
Changes from all commits
bbd606e
5784fc7
9961ead
b1a4bcc
4bf2377
c96e5ad
65789e2
c919f51
3252e66
0fa38d4
a5283eb
2e4daba
4a383a5
43bbaa3
4f690b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| '@antv/l7-test-utils': minor | ||
| '@antv/l7-component': minor | ||
| '@antv/l7-renderer': minor | ||
| '@antv/l7-layers': minor | ||
| '@antv/l7-source': minor | ||
| '@antv/l7-scene': minor | ||
| '@antv/l7-three': minor | ||
| '@antv/l7-utils': minor | ||
| '@antv/l7-core': minor | ||
| '@antv/l7-maps': minor | ||
| '@antv/l7-map': minor | ||
| '@antv/l7': minor | ||
| --- | ||
|
|
||
| 移动端事件 |
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| import { LayerPopup, PolygonLayer } from '@antv/l7'; | ||
| import type { TestCase } from '../../types'; | ||
| import { CaseScene } from '../../utils'; | ||
|
|
||
| export const fillChina: TestCase = async (options) => { | ||
| const scene = await CaseScene({ | ||
| ...options, | ||
| mapConfig: { | ||
| center: [-96, 37.8], | ||
| zoom: 3, | ||
| }, | ||
| }); | ||
|
|
||
| const url1 = | ||
| 'https://mdn.alipayobjects.com/antforest/afts/file/A*vaL-R4SU18IAAAAAgCAAAAgAerd2AQ/original_2025-11-14.json'; | ||
| // const url2 = 'https://geojson.cn/api/china/1.6.2/china.json' | ||
| const result = await fetch(url1); | ||
| const data = await result.json(); | ||
| const fillData = data.features.filter((feature: any) => { | ||
| // 过滤掉线数据 | ||
| if (feature.properties.name === '境界线') { | ||
| return false; | ||
| } | ||
| return true; | ||
| }); | ||
| // 未定国界线数据 | ||
| const UndelimitedBoundary = data.features.filter((feature: any) => { | ||
| // 过滤掉线数据 | ||
| if (feature.properties.gb === '003') { | ||
| return true; | ||
| } | ||
| return false; | ||
| }); | ||
|
|
||
| const boundary = data.features.filter((feature: any) => { | ||
| // 过滤掉线数据 | ||
| if (feature.properties.gb !== '003') { | ||
| return true; | ||
| } | ||
| return false; | ||
| }); | ||
|
|
||
| const color = [ | ||
| '#a50026', | ||
| '#d73027', | ||
| '#f46d43', | ||
| '#fdae61', | ||
| '#fee090', | ||
| '#ffffbf', | ||
| '#e0f3f8', | ||
| '#abd9e9', | ||
| '#74add1', | ||
| '#4575b4', | ||
| '#313695', | ||
|
Comment on lines
+43
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| ]; | ||
| // 行政区划填充色 | ||
| const fillLayer = new PolygonLayer({ | ||
| autoFit: true, | ||
| }) | ||
| .source({ | ||
| type: 'FeatureCollection', | ||
| features: fillData, | ||
| }) | ||
| .color('#d6dff6') | ||
| .shape('fill') | ||
| .active({ | ||
| color: '#5483ef', | ||
| }) | ||
| .style({ | ||
| opacity: 0.5, | ||
| }); | ||
| const boundaryLayer = new PolygonLayer({ | ||
| autoFit: true, | ||
| }) | ||
| .source({ | ||
| type: 'FeatureCollection', | ||
| features: boundary, | ||
| }) | ||
| .color('#5483ef') | ||
| .shape('line') | ||
| .size(0.5) | ||
| .style({ | ||
| opacity: 1, | ||
| }); | ||
|
|
||
| // 未定国际虚线表示 | ||
| const layer = new PolygonLayer({ | ||
| autoFit: true, | ||
| }) | ||
| .source({ | ||
| type: 'FeatureCollection', | ||
| features: UndelimitedBoundary, | ||
| }) | ||
| .color('red') | ||
| .shape('line') | ||
| .size(1) | ||
| .style({ | ||
| opacity: 1, | ||
| lineType: 'dash', | ||
| dashArray: [5, 5], | ||
| }); | ||
|
|
||
| const layerPopup = new LayerPopup({ | ||
| trigger: 'click', | ||
| items: [ | ||
| { | ||
| layer: fillLayer, | ||
| fields: [ | ||
| { | ||
| field: 'name', | ||
| formatField: () => '名称', | ||
| }, | ||
| { | ||
| field: 'gb', | ||
| formatField: () => '编号', | ||
| formatValue: (val) => val, | ||
| }, | ||
| ], | ||
| }, | ||
| ], | ||
| }); | ||
|
|
||
| scene.addLayer(fillLayer); | ||
|
|
||
| scene.addLayer(boundaryLayer); | ||
|
|
||
| scene.addLayer(layer); | ||
|
|
||
| scene.addPopup(layerPopup); | ||
|
|
||
| return scene; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import type { ILayer, IPopupOption, L7Container } from '@antv/l7-core'; | ||
| import { DOM, lodashUtil } from '@antv/l7-utils'; | ||
| import { DOM, isPC, lodashUtil } from '@antv/l7-utils'; | ||
| import Popup from './popup'; | ||
|
|
||
| type ElementType = DOM.ElementType; | ||
|
|
@@ -21,7 +21,7 @@ export type LayerPopupConfigItem = { | |
| export interface ILayerPopupOption extends IPopupOption { | ||
| config?: LayerPopupConfigItem[]; | ||
| items?: LayerPopupConfigItem[]; | ||
| trigger: 'hover' | 'click'; | ||
| trigger: 'hover' | 'click' | 'touchend' | 'touchstart'; | ||
| } | ||
|
|
||
| type LayerMapInfo = { | ||
|
|
@@ -58,6 +58,19 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| return config ?? items ?? []; | ||
| } | ||
|
|
||
| /** | ||
| * 根据环境获取实际的触发事件 | ||
| * 当 trigger 为 'click' 时,移动端使用 'touchend',PC 端使用 'click' | ||
| * @protected | ||
| */ | ||
| protected getActualTriggerEvent() { | ||
| const { trigger } = this.popupOption; | ||
| if (trigger === 'click') { | ||
| return isPC() ? 'click' : 'touchend'; | ||
| } | ||
| return trigger; | ||
| } | ||
|
|
||
| public addTo(scene: L7Container) { | ||
| super.addTo(scene); | ||
| this.bindLayerEvent(); | ||
|
|
@@ -88,7 +101,7 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| } | ||
|
|
||
| protected getDefault(option: Partial<ILayerPopupOption>): ILayerPopupOption { | ||
| const isHoverTrigger = option.trigger !== 'click'; | ||
| const isHoverTrigger = option.trigger === 'hover'; | ||
| return { | ||
| ...super.getDefault(option), | ||
| trigger: 'hover', | ||
|
|
@@ -111,6 +124,8 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| */ | ||
| protected bindLayerEvent() { | ||
| const { trigger, closeOnClick } = this.popupOption; | ||
| const actualTrigger = this.getActualTriggerEvent(); | ||
|
|
||
| this.layerConfigItems.forEach((configItem) => { | ||
| const layer = this.getLayerByConfig(configItem); | ||
| if (!layer) { | ||
|
|
@@ -131,11 +146,11 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| } else { | ||
| const onLayerClick = this.onLayerClick.bind(this, layer); | ||
| layerInfo.onClick = onLayerClick; | ||
| layer?.on('click', onLayerClick); | ||
| layer?.on(actualTrigger, onLayerClick); | ||
|
|
||
| const mapContainer = this.mapsService?.getMapContainer(); | ||
| if (mapContainer && closeOnClick) { | ||
| mapContainer.addEventListener('click', this.onSceneClick); | ||
| mapContainer.addEventListener(actualTrigger, this.onSceneClick); | ||
| } | ||
| } | ||
| const source = layer?.getSource?.(); | ||
|
|
@@ -152,6 +167,8 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| * @protected | ||
| */ | ||
| protected unbindLayerEvent() { | ||
| const actualTrigger = this.getActualTriggerEvent(); | ||
|
|
||
| this.layerConfigItems.forEach((configItem) => { | ||
| const layer = this.getLayerByConfig(configItem); | ||
| const layerInfo = layer && this.layerConfigMap.get(layer); | ||
|
|
@@ -166,14 +183,14 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| layer.off('mouseout', onMouseOut); | ||
| } | ||
| if (onClick) { | ||
| layer.off('click', onClick); | ||
| layer.off(actualTrigger, onClick); | ||
| } | ||
| if (onSourceUpdate) { | ||
| layer?.getSource()?.off('update', onSourceUpdate); | ||
| } | ||
| const mapContainer = this.mapsService?.getMapContainer(); | ||
| if (mapContainer) { | ||
| mapContainer.removeEventListener('click', this.onSceneClick); | ||
| mapContainer.removeEventListener(actualTrigger, this.onSceneClick); | ||
| } | ||
| }); | ||
| } | ||
|
|
@@ -191,8 +208,7 @@ export default class LayerPopup extends Popup<ILayerPopupOption> { | |
| } | ||
| } | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| protected onLayerMouseOut(layer: ILayer, e: any) { | ||
| protected onLayerMouseOut(layer: ILayer) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| this.setDisplayFeatureInfo(undefined); | ||
| if (this.isShow) { | ||
| this.hide(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ import { ExampleTopicMenu } from '@antv/dumi-theme-antv/dist/pages/Examples/comp | |
| import { Footer } from '@antv/dumi-theme-antv/dist/slots/Footer'; | ||
| import { Header } from '@antv/dumi-theme-antv/dist/slots/Header'; | ||
| import NavigatorBanner from '@antv/dumi-theme-antv/dist/slots/Header/Products/NavigatorBanner'; | ||
| import { SEO } from '@antv/dumi-theme-antv/dist/slots/SEO'; | ||
| // import { SEO } from '@antv/dumi-theme-antv/dist/slots/SEO'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| import { usePrevAndNext } from '@antv/dumi-theme-antv/dist/slots/hooks'; | ||
| import type { ExampleTopic } from '@antv/dumi-theme-antv/dist/types'; | ||
| import { Layout as AntLayout, BackTop } from 'antd'; | ||
|
|
@@ -84,7 +84,6 @@ const Example = () => { | |
| }, []); | ||
| return ( | ||
| <> | ||
| <SEO title={title[locale.id]} /> | ||
| <Header isHomePage={false} /> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <AntLayout hasSider className={styles.layout}> | ||
| <ExampleTopicMenu exampleTopics={exampleTopics} /> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ import readingTime from 'reading-time'; | |
| import URI from 'uri-parse'; | ||
|
|
||
| import { ContentTable } from '@antv/dumi-theme-antv/dist/slots/ContentTable'; | ||
| import { SEO } from '@antv/dumi-theme-antv/dist/slots/SEO'; | ||
| // import { SEO } from '@antv/dumi-theme-antv/dist/slots/SEO'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| import GithubButtonBar from '../GithubButtonBar'; | ||
|
|
||
| import { NavigatorBanner } from '@antv/dumi-theme-antv/dist/slots/ManualContent/NavigatorBanner'; | ||
|
|
@@ -265,7 +265,6 @@ export const ManualContent: React.FC<ManualContent> = ({ children }) => { | |
|
|
||
| return ( | ||
| <> | ||
| <SEO title={linkoTitle[window.location.pathname]} lang={locale.id} /> | ||
| <Layout style={{ background: '#fff' }} hasSider className={styles.layout}> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <Affix | ||
| offsetTop={0} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这段过滤逻辑在
fillData、UndelimitedBoundary和boundary的创建中重复出现。建议将此通用过滤逻辑提取到一个辅助函数中,以提高代码的可重用性和可维护性。