问题
I'm using react-bootstrap-table for displaying my data. On mouseOver any of the row, I need to dynamically add two buttons over the last two columns of that particular hovered row. As the above picture.
I've added that functionality by adding classnames and innerHTML onRowMouseOver.
And removing the added innerHtml element based on the added ClassNames onRowMouseOut.
I can add two buttons on hovered row. But when I hover on the added buttons it is flickering continuously.
Here is the code sample:
import React, { Component } from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
const products = [
{
id: 1,
name: "abcdef",
price: 120,
email:"abc@gmail.com",
phone:"9856325632",
submitted:"10/02/18",
responded:"01/09/18",
status:"active"
}, {
id: 2,
name: "abcdef",
price: 120,
email:"abc@gmail.com",
phone:"9856325632",
submitted:"10/02/18",
responded:"01/09/18",
status:"active"
},
{
id: 3,
name: "abcdef",
price: 120,
email:"abc@gmail.com",
phone:"9856325632",
submitted:"10/02/18",
responded:"01/09/18",
status:"active"
},
{
id: 4,
name: "abcdef",
price: 120,
email:"abc@gmail.com",
phone:"9856325632",
submitted:"10/02/18",
responded:"01/09/18",
status:"active"
},
{
id: 5,
name: "abcdef",
price: 120,
email:"abc@gmail.com",
phone:"9856325632",
submitted:"10/02/18",
responded:"01/09/18",
status:"active"
},
];
const total = products.length;
class Tables extends Component {
constructor(props) {
super(props);
this.state = {
text: '',
selectedDate: null,
page: 1,
goToPageNum:1,
disableGoButton:true,
disableGoToInput:false,
size:5,
};
}
onSizePerPageList = (sizePerPage) => {
this.setState({size:sizePerPage},()=> this.hideGTP());
}
expandComponent(row) {
return (
<div className="col-3">
<div className="card bg-warning">
<div className="card-body card-custom d-flex justify-content-around">
<div className="card-text">
<button type="button" class="btn btn-warning" onClick={()=>alert('hello!!!!!!')}>Change Status</button>
</div>
<div className="card-text d-flex align-items-center">
Remove</div>
</div>
</div>
</div>
)
}
render() {
const options = {
page: this.state.page,
onRowMouseOut: function(row, e) {
let rmv = document.querySelector('.position-row');
rmv.classList.remove('position-row')
document.querySelector('.position-child').remove();
},
onRowMouseOver: function(row, e) {
console.log('mouse enter from row ' + row.id);
let ind = row.id-1;
let addClass = document.querySelectorAll('tbody')[0].children[ind];
addClass.classList.add('position-row');
console.log('addClass',addClass);
let spt = document.querySelector('.position-row');
console.log('OVERRR',spt);
var divv = document.createElement("div");
divv.classList.add('position-child');
divv.innerHTML = '<div class="row"><div class="col-6"><button type="button" class="btn btn-warning">Change Status</button></div><div class="col-6"><button type="button" class="btn btn-warning">Delete User</button></div></div>'
spt.parentNode.insertBefore(divv, spt.nextSibling);
}
};
return (
<div className="container py-5">
<BootstrapTable
trClassName="table-row"
bordered={false}
ref='table'
data={products}
options={options}
search={true}
>
<TableHeaderColumn dataField='id' isKey={true}>ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>NAME</TableHeaderColumn>
<TableHeaderColumn dataField='email'>EMAIL</TableHeaderColumn>
<TableHeaderColumn dataField='phone'>PHONE</TableHeaderColumn>
<TableHeaderColumn dataField='submitted'>LOGIN</TableHeaderColumn>
<TableHeaderColumn dataField='responded'>SIGNUP</TableHeaderColumn>
<TableHeaderColumn dataField='status'>STATUS</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Tables;
My problem is: Flickering: when I hover on the added elements, it is continuously flickering(adding and removing the classnames and element). Please guide me to overcome it.
Codedandbox Demo: My Demo Codesandbox Link: https://codesandbox.io/s/p910j5k6x
回答1:
I think the buttons you are adding are blocking the mouse event from staying over the row.
When your mouse is over the row, it will add the div with buttons to the DOM, overlaying the row, This is blocking your mouse from triggering events on the row element. Since your mouse has technically left the row-element it will remove the buttons again.
I think your best bet would be to add the div with the buttons to the row element itself.
回答2:
I fixed it by using the following code:
import React, { Fragment, Component } from "react";
import { BootstrapTable, TableHeaderColumn } from "react-bootstrap-table";
const products = [
{
id: 1,
name: "abcdef",
price: 120,
email: "abc@gmail.com",
phone: "9856325632",
submitted: "10/02/18",
responded: "01/09/18",
status: "active"
},
{
id: 2,
name: "abcdef",
price: 120,
email: "abc@gmail.com",
phone: "9856325632",
submitted: "10/02/18",
responded: "01/09/18",
status: "active"
},
{
id: 3,
name: "abcdef",
price: 120,
email: "abc@gmail.com",
phone: "9856325632",
submitted: "10/02/18",
responded: "01/09/18",
status: "active"
},
{
id: 4,
name: "abcdef",
price: 120,
email: "abc@gmail.com",
phone: "9856325632",
submitted: "10/02/18",
responded: "01/09/18",
status: "active"
},
{
id: 5,
name: "abcdef",
price: 120,
email: "abc@gmail.com",
phone: "9856325632",
submitted: "10/02/18",
responded: "01/09/18",
status: "active"
}
];
const total = products.length;
class Tables extends Component {
constructor(props) {
super(props);
this.state = {
text: "",
selectedDate: null,
page: 1,
goToPageNum: 1,
disableGoButton: true,
disableGoToInput: false,
size: 5
};
}
onSizePerPageList = sizePerPage => {
this.setState({ size: sizePerPage }, () => this.hideGTP());
};
expandComponent(row) {
return (
<div className="col-3">
<div className="card bg-warning">
<div className="card-body card-custom d-flex justify-content-around">
<div className="card-text">
<button
type="button"
class="btn btn-warning"
onClick={() => alert("hello!!!!!!")}
>
Change Status
</button>
</div>
<div className="card-text d-flex align-items-center">Remove</div>
</div>
</div>
</div>
);
}
helloww() {
alert("heyyy its working");
}
render() {
const options = {
page: this.state.page,
onRowMouseOut: function(row, e) {
let ind = row.id - 1;
let element = document.querySelectorAll("tbody")[0].children[ind];
const buttons = element.getElementsByClassName("position-child")[0];
buttons.style.display = "none";
},
onRowMouseOver: function(row, e) {
let ind = row.id - 1;
let addClass = document.querySelectorAll("tbody")[0].children[ind];
let buttons = addClass.getElementsByClassName("position-child")[0];
buttons.style.display = "block";
}
};
const priceFormatter = (cell, row) => {
return (
<Fragment>
{row.status}
<div className="position-child">
<div class="row " onmouseenter="mouseEnter()">
<div class="col-6">
<button type="button" class="btn btn-warning">
Change Status
</button>
</div>
<div class="col-6">
<button
type="button"
class="btn btn-warning"
onClick={e => this.helloww()}
>
Delete User
</button>
</div>
</div>
</div>
</Fragment>
);
};
return (
<div className="container py-5">
<BootstrapTable
trClassName="table-row"
bordered={false}
ref="table"
data={products}
options={options}
search={true}
>
<TableHeaderColumn dataField="id" isKey={true} width="20%">
ID
</TableHeaderColumn>
<TableHeaderColumn dataField="name" width="20%">
NAME
</TableHeaderColumn>
<TableHeaderColumn dataField="email" width="20%">
EMAIL
</TableHeaderColumn>
<TableHeaderColumn dataField="phone" width="20%">
PHONE
</TableHeaderColumn>
<TableHeaderColumn dataField="submitted" width="20%">
LOGIN
</TableHeaderColumn>
<TableHeaderColumn dataField="responded" width="20%">
SIGNUP
</TableHeaderColumn>
<TableHeaderColumn
dataField="status"
dataFormat={priceFormatter}
width="20%"
>
STATUS
</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Tables;
.position-child {
width: 25%;
position: absolute;
right: 131px;
background: red;
margin-top: -30px;
display: none;
}
来源:https://stackoverflow.com/questions/54670729/how-to-restrict-multiple-adding-and-removing-classnames-on-table-row-mouse-event