React Click/Mouse 事件处理 [react-sortable-hoc, material-ui, react-virtualized]
React Click/Mouse Event Handling [react-sortable-hoc, material-ui, react-virtualized]
我有下面的例子
Stackblitz Live Working Example
如果您按下红色垃圾箱图标上的删除按钮,它不会触发我的 onClick
事件处理程序(而是立即开始排序)。
如果您按下按钮的删除按钮背景(垃圾箱图标周围的圆圈),它会触发按钮 onClick
处理程序并执行相应操作。
我试过设置不同的 onClick(包括 xxxxCapture
版本和 e.preventDefault()
)但没有成功。
问题
因此我有两个问题:
- 有没有一种好方法可以找出树中首先处理点击的位置?
- 如何使我的按钮
onClick
在背景中以及 icon
本身保持一致?
代码
对于无法打开 Stackblitz 的人,代码是:
import React from 'react';
import { Button, IconButton, Tooltip, Typography } from "@material-ui/core";
import { Add, DeleteForever } from "@material-ui/icons";
import { AutoSizer, Column, Index, Table, TableCellProps, TableProps, TableRowProps, WindowScroller, defaultTableRowRenderer } from "react-virtualized";
import { SortableContainer, SortableElement, SortEnd, SortEndHandler, SortEvent } from "react-sortable-hoc";
import 'react-virtualized/styles.css';
const SortableTable = SortableContainer<TableProps>((props: TableProps) => (
<Table {...props} />
));
const SortableRow = SortableElement<TableRowProps>(
(props: TableRowProps) => defaultTableRowRenderer(props) as any
);
const sortableRowRenderer = (props: TableRowProps) => {
return <SortableRow {...props} />;
};
interface IRow {
value: string;
}
class Grid extends React.Component<any, { items: IRow[] }> {
remove(rowData: any): any {
const items = this.state.items;
if (!items) {
return;
}
const index = items.indexOf(rowData);
const newItems = [...items.slice(0, index), ...items.slice(index + 1)];
this.setState({ items: newItems });
}
constructor(props: any) {
super(props);
this.state = {
items: this.getDefaultItems()
};
}
private getDefaultItems = () => {
return [
{ value: "one" },
{ value: "two" },
{ value: "three" },
{ value: "four" },
{ value: "five" }
]
}
private rowRenderer = (props: TableRowProps) => {
return defaultTableRowRenderer(props);
};
public render() {
return (
<div>
<WindowScroller>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer disableHeight={true}>
{size => (
<SortableTable
headerHeight={38}
autoHeight={true}
height={height}
rowCount={this.state.items.length}
scrollTop={scrollTop}
rowGetter={this.getItem}
rowHeight={37}
width={size.width}
rowRenderer={sortableRowRenderer}
>
<Column label={"value"} dataKey={"value"} width={160} />
<Column
dataKey={"buttons"}
cellRenderer={this.buttonsCellRenderer}
width={48}
minWidth={48}
maxWidth={48}
/>
</SortableTable>
)}
</AutoSizer>
)}
</WindowScroller>
<Button onClick={this.reset}>Reset</Button>
</div>
);
}
private reset = () => {
this.setState({ items: this.getDefaultItems() });
}
private buttonsCellRenderer = (props: TableCellProps) => {
const remove = (event: any) => {
console.log("remove");
console.log(event);
this.remove(props.rowData);
};
const removeWithPrevent = (event: any) => {
console.log("removeWithPrevent");
console.log(event);
this.remove(props.rowData);
};
return (
<Tooltip title="Delete Line Item" enterDelay={500}>
<IconButton onClick={remove}>
<DeleteForever fontSize="small" color="error" onClick={remove} />
</IconButton>
</Tooltip>
);
};
private getItem = (info: Index) => {
const rows = this.state.items;
const row = rows[info.index];
return row;
};
}
export default Grid;
我正在开发同类应用程序,当我单击单元格上的某些内容并使它们可排序时,我想执行一些操作。它可以通过两种方式实现
- 在 SortableContainer HOC 中添加延迟属性 pressDelay 属性。 docs
假设 pressDelay=500。这将做的是,如果你按住你的点击 500 毫秒,该行将变得可排序,否则只是正常的点击事件 fire.in 我认为这会很好
2.add 行首的句柄,只需拖动句柄即可排序。为此,您需要实施 customTableRowRenderer。只需从此处复制代码 rowRenderer 并从 sortable hoc 导入句柄,然后更改 return 函数
import { SortableHandle } from 'react-sortable-hoc';
const DragHandle = SortableHandle(() => columns[0]);
return (
<div
{...a11yProps}
className={className}
key={key}
role='row'
style={style}>
<DragHandle />
{columns.slice(1, columns.length)}
</div>
);
不要忘记将句柄添加为第一列。
我有下面的例子
Stackblitz Live Working Example
如果您按下红色垃圾箱图标上的删除按钮,它不会触发我的 onClick
事件处理程序(而是立即开始排序)。
如果您按下按钮的删除按钮背景(垃圾箱图标周围的圆圈),它会触发按钮 onClick
处理程序并执行相应操作。
我试过设置不同的 onClick(包括 xxxxCapture
版本和 e.preventDefault()
)但没有成功。
问题
因此我有两个问题:
- 有没有一种好方法可以找出树中首先处理点击的位置?
- 如何使我的按钮
onClick
在背景中以及icon
本身保持一致?
代码
对于无法打开 Stackblitz 的人,代码是:
import React from 'react';
import { Button, IconButton, Tooltip, Typography } from "@material-ui/core";
import { Add, DeleteForever } from "@material-ui/icons";
import { AutoSizer, Column, Index, Table, TableCellProps, TableProps, TableRowProps, WindowScroller, defaultTableRowRenderer } from "react-virtualized";
import { SortableContainer, SortableElement, SortEnd, SortEndHandler, SortEvent } from "react-sortable-hoc";
import 'react-virtualized/styles.css';
const SortableTable = SortableContainer<TableProps>((props: TableProps) => (
<Table {...props} />
));
const SortableRow = SortableElement<TableRowProps>(
(props: TableRowProps) => defaultTableRowRenderer(props) as any
);
const sortableRowRenderer = (props: TableRowProps) => {
return <SortableRow {...props} />;
};
interface IRow {
value: string;
}
class Grid extends React.Component<any, { items: IRow[] }> {
remove(rowData: any): any {
const items = this.state.items;
if (!items) {
return;
}
const index = items.indexOf(rowData);
const newItems = [...items.slice(0, index), ...items.slice(index + 1)];
this.setState({ items: newItems });
}
constructor(props: any) {
super(props);
this.state = {
items: this.getDefaultItems()
};
}
private getDefaultItems = () => {
return [
{ value: "one" },
{ value: "two" },
{ value: "three" },
{ value: "four" },
{ value: "five" }
]
}
private rowRenderer = (props: TableRowProps) => {
return defaultTableRowRenderer(props);
};
public render() {
return (
<div>
<WindowScroller>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer disableHeight={true}>
{size => (
<SortableTable
headerHeight={38}
autoHeight={true}
height={height}
rowCount={this.state.items.length}
scrollTop={scrollTop}
rowGetter={this.getItem}
rowHeight={37}
width={size.width}
rowRenderer={sortableRowRenderer}
>
<Column label={"value"} dataKey={"value"} width={160} />
<Column
dataKey={"buttons"}
cellRenderer={this.buttonsCellRenderer}
width={48}
minWidth={48}
maxWidth={48}
/>
</SortableTable>
)}
</AutoSizer>
)}
</WindowScroller>
<Button onClick={this.reset}>Reset</Button>
</div>
);
}
private reset = () => {
this.setState({ items: this.getDefaultItems() });
}
private buttonsCellRenderer = (props: TableCellProps) => {
const remove = (event: any) => {
console.log("remove");
console.log(event);
this.remove(props.rowData);
};
const removeWithPrevent = (event: any) => {
console.log("removeWithPrevent");
console.log(event);
this.remove(props.rowData);
};
return (
<Tooltip title="Delete Line Item" enterDelay={500}>
<IconButton onClick={remove}>
<DeleteForever fontSize="small" color="error" onClick={remove} />
</IconButton>
</Tooltip>
);
};
private getItem = (info: Index) => {
const rows = this.state.items;
const row = rows[info.index];
return row;
};
}
export default Grid;
我正在开发同类应用程序,当我单击单元格上的某些内容并使它们可排序时,我想执行一些操作。它可以通过两种方式实现
- 在 SortableContainer HOC 中添加延迟属性 pressDelay 属性。 docs 假设 pressDelay=500。这将做的是,如果你按住你的点击 500 毫秒,该行将变得可排序,否则只是正常的点击事件 fire.in 我认为这会很好
2.add 行首的句柄,只需拖动句柄即可排序。为此,您需要实施 customTableRowRenderer。只需从此处复制代码 rowRenderer 并从 sortable hoc 导入句柄,然后更改 return 函数
import { SortableHandle } from 'react-sortable-hoc';
const DragHandle = SortableHandle(() => columns[0]);
return (
<div
{...a11yProps}
className={className}
key={key}
role='row'
style={style}>
<DragHandle />
{columns.slice(1, columns.length)}
</div>
);
不要忘记将句柄添加为第一列。