javascript - 我的屏幕没有滚动 onClick 可能是什么问题?
问题描述
我试图让我的屏幕移动到我的 React/Ionic 应用程序中新添加的元素位置,但无论我尝试什么,它都无法正常工作。
我尝试过使用 refs。我尝试过使用 scrollTo()、ScrollIntoView - 至少使用 refs 移动了屏幕,我现在正在尝试使用 IonContent Scroll 功能,但它不会让步。
我的目标是当我点击按钮时让我的屏幕滚动到新的练习
这是我的代码
const AddWorkout: React.FC<Props & InjectedFormProps<{}, Props>> = (
props: any
) => {
const { pristine, submitting, handleSubmit } = props;
const dispatch = useDispatch();
const [duration, setDuration] = useState("");
const [openPicker, setOpenPicker] = useState(false);
return (
<>
<IonModal isOpen={props.show} animated backdropDismiss>
<IonHeader>
<IonToolbar>
<IonTitle>Add A New Workout</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent
scrollEvents={true}
onIonScrollStart={_e => {
console.log(_e);
}}
onIonScroll={() => { }}
onIonScrollEnd={() => { }}
>
<form className="edit-modal">
<IonGrid className="ion-no-margin">
<IonRow>
<Field
name="name"
title="Name"
component={ReduxFormInput}
/>
</IonRow>
<IonRow>
<Field
name="date"
title="Date"
type="date"
values={new Date().toISOString()}
component={ReduxFormDateTime}
/>
</IonRow>
<IonRow>
<Field
name="duration"
title="Duration"
duration={duration}
setDuration={setDuration}
openPicker={openPicker}
setOpenPicker={setOpenPicker}
component={ReduxDurationInput}
/>
</IonRow>
<FieldArray name="exercises" component={renderExercises} />
</IonGrid>
</form>
</IonContent>
<IonFooter>
<IonRow>
<IonCol>
<IonButton expand="block" fill="clear" onClick={props.onCancel}>
Cancel
</IonButton>
</IonCol>
<IonCol>
<IonButton
expand="block"
color="success"
type="submit"
onClick={handleSubmit(submitForm)}
disabled={submitting || pristine}
>
Add Workout
</IonButton>
</IonCol>
</IonRow>
</IonFooter>
</IonModal>
</>
);
};
const renderExercises = (props: WrappedFieldArrayProps<{}>) => {
const { fields } = props;
const { error, submitFailed } = props.meta;
const groupIdx: Array<any> = fields.getAll()
const moveExerciseUp = (from: number, to: number) => {
if (from !== 0) {
fields.move(from, to);
}
};
const moveExerciseDown = (from: number, to: number) => {
if (from !== fields.length - 1) {
fields.move(from, to);
}
};
const onMovePosition = (from: number, pos: number) => {
if (pos > 0 && pos <= fields.length) {
let breakOutOfLoop = false
groupIdx.forEach((field, idx) => {
// if one of the items has the correct group number,
// assign the position to move to to that position
if (field.group === pos && !breakOutOfLoop) {
fields.move(from, idx)
breakOutOfLoop = true
}
if (idx + 1 < fields.length && field.group > groupIdx[idx + 1].group) {
fields.swap(idx, idx + 1)
}
})
}
}
// THIS IS WHERE MY CODE IS!!!!!!!!!!!!!!!
const gotoButton = () => {
let y = document.getElementById("exerciseScroll")!.offsetTop;
let content = document.querySelector("ion-content");
content?.scrollToPoint(0, y);
};
return (
<>
<IonRow className="sticky-button">
<IonCol>
<IonButton
type="button"
expand="full"
onClick={() => {
fields.push({ group: fields.length + 1 })
gotoButton()
}}
>
Add Exercise
</IonButton>
</IonCol>
</IonRow>
<IonRow>
<IonCol>
{fields.map((exercise, idx) => {
return (
<div key={idx} className="ion-text-center" style={{ border: "1px solid black", borderRadius: "5px" }}>
<IonRow className="ion-margin-vertical">
<IonCol size="6" className="ion-no-padding ion-margin-vertical ion-text-right">
<h4 style={{ margin: 0 }}>
Exercise Group #
</h4>
</IonCol>
<Field
name={`${exercise}.group`}
component={ReduxFormGroupInput}
position={idx}
parse={(value: string) => parseInt(value, 10)}
normalize={
(value: any, previousValue: any, allValues: any) => {
if (value < 0 || value > fields.length || isNaN(value)) {
return previousValue
}
if (idx > 0 && allValues.exercises[idx - 1].group - 1 < allValues.exercises[idx].group) {
let i = idx + 1;
for (i; i < fields.length; i++) {
if (groupIdx[i].group === groupIdx[idx].group) {
allValues.exercises[i].group--
}
}
}
return allValues.exercises[idx].group
}
}
change={onMovePosition}
className="ion-no-padding ion-float-left ion-text-center"
/>
<IonCol>
<small style={{ color: "gray" }}>(Change the group # to create supersets)</small>
</IonCol>
</IonRow>
<IonRow>
<div style={{ position: "relative", marginRight: 30 }}>
<IonButton
fill="clear"
size="small"
style={{ position: "absolute", top: 10, left: 0 }}
onClick={() => moveExerciseUp(idx, idx - 1)}
>
<IonIcon icon={arrowUp} slot="icon-only" />
</IonButton>
<IonButton
fill="clear"
size="small"
style={{ position: "absolute", bottom: 0, left: 0 }}
onClick={() => moveExerciseDown(idx, idx + 1)}
>
<IonIcon icon={arrowDown} slot="icon-only" />
</IonButton>
</div>
<Field
name={`${exercise}.name`}
title="Exercise Name"
component={ReduxFormInput}
/>
</IonRow>
<IonButton
onClick={() => fields.remove(idx)}
color="danger"
fill="clear"
size="small"
>
REMOVE EXERCISE
</IonButton>
<FieldArray
name={`${exercise}.sets`}
props={null}
component={renderSets}
/>
</div>
);
})}
{submitFailed && error && (
<span style={{ color: "red" }}>{error}</span>
)}
</IonCol>
</IonRow>
<div id="exerciseScroll" />
</>
);
};
解决方案
这是您在 onClick 事件中调用 gotoButton 的方式。它在您的组件完成渲染之前评估 gotoButton。有关此示例,请参见此答案:React onClick function fires on render
为避免这种情况,您可以在 gotoButton 函数中运行 fields.push({ group: fields.length + 1 }) 并像这样传递 gotoButton 'onClick={gotoButton}'。
推荐阅读
- tensorflow - 访问 tf.data.Dataset 的索引以删除和附加数据元素
- docker - 如何 docker pull 到特定的服务器?
- linux - Yocto Project 中是否有任何“项目文件”或“工作区文件”或“解决方案文件”等价物?
- excel - 如何修复无效的下一个控制变量引用
- wordpress - 为什么我无法重新排序我的自定义帖子类型?
- react-snap - react-snap,静态页面加载后重新渲染的困惑?
- javascript - 如何修复 React Native 中的合并项中的“java.lang.String 类型的值 a 无法转换为 JSONObject”错误
- macos - docker:无效的引用格式:存储库名称必须为小写
- arrays - 红宝石数组分开“重复”
- ios - 在 Swift 中将整数映射到字符串