自动向下滚动到下一个列表组项目并在移动视图的中央显示内容(反应) [英] Automatically scroll down to next listgroup item and display the content in center in mobile view (React)
问题描述
1)我正在尝试自动滚动到列表组中的下一项.例如,如果用户回答第一个问题,它将自动滚动到第二个问题.(反应),然后在onSubmit上滚动到第一个未回答的问题
2)当用户在移动设备视图中查看此列表时,"YES"或"NO"单选按钮应显示在中间,并且"SUBMIT AND CLEAR BUTTON(BOOTSTRAP)"
3)如何知道从下拉菜单中选择了哪个项目并将其显示在控制台中.
有很多方法可以实现.一种方法是添加一个通过香草js"滚动到表单中某个项目的方法,然后在 onSubmut
方法的两个 onInputChanged
中使用该方法./p>
您可以在组件中将此函数定义为:
//通过列表项索引将列表滚动到列表项scrollToItemByIndex =(索引)=>{//查找列表项元素(按索引),然后滚动包装器元素const scrollItem = document.querySelector(`[scrollIndex ="$ {(index)}"]`))const scrollWrapper = document.querySelector(`[scrollWrapper ="scrollWrapper"]`)if(scrollItem& scrollWrapper){//如果在DOM中找到列表项,则获取顶部偏移量const itemRect = scrollItem.offsetTop//[更新]const wrapperRect = scrollWrapper.offsetTop////[更新]//将包装器滚动到要滚动到的列表项的偏移量scrollWrapper.scrollTo(0,itemRect-wrapperRect)}}
然后您的 onInputChange
函数可以进行如下更新:
onInputChange =({target})=>{const {cards} = this.state;const {options} = this.state;const nexState = cards.map((card,index)=> {如果(card.cardName!== target.name)返回卡;const options = card.options.map(opt => {constchecked = opt.radioName === target.value;返回 {...选择,已选择:选中}})//[ADD]当输入更改(即已设置某些内容)时,滚动到下一个项目this.scrollToItemByIndex(index +1)const style = options.every(option =>!option.selected)吗?'danger':'info'返回 {...卡片,风格,选项}});this.setState({卡:nexState})}
此外,您的 onSubmit
将更新为滚动到无效的任何表单项:
onSubmit =()=>{this.state.cards.forEach((card,index)=> {var invalid = card.options.every(option =>!option.selected)如果(无效){card.style ='危险'//[ADD]该项目输入无效,因此请滚动至该项目this.scrollToItemByIndex(index)}别的 {card.style ='信息'}});...}
最后,您需要使用以下内容更新组件的render方法,以确保上述查询选择器可以正常运行:
< ul class ="nav nav-pills nav-stacked anyClass" scrollWrapper ="scrollWrapper">
和:
{cards.map((card,idx)=>(< ListGroup bsStyle ="custom" scrollIndex = {idx}>...</ListGroup>)}
[更新]可以在这里找到完整的工作示例: https://stackblitz.com/edit/react-z7nhgd?file=index.js
希望这会有所帮助!
1) I am trying to Auto scroll to the next item in listgroup. For example if user answer the first question it should auto scroll to the second question. (React) and onSubmit it should scroll to the first not answered question
2) When user view this list in mobile view the YES or NO Radio button should display in center and also SUBMIT AND CLEAR BUTTON (BOOTSTRAP)
3) How to know which item is selected from the drop down and display it in console.
There are a number of ways this can be achieved. One way would be to add a method that scrolls to an item in your form, via "vanilla js", and then use that in both your onInputChanged
on onSubmut
methods.
You could defined this function in your component as:
// Scrolls the list to a list item by list item index
scrollToItemByIndex = (index) => {
// Find the list item element (by index), and scroll wrapper element
const scrollItem = document.querySelector(`[scrollIndex="${ (index) }"]`)
const scrollWrapper = document.querySelector(`[scrollWrapper="scrollWrapper"]`)
if(scrollItem && scrollWrapper) {
// If list item found in DOM, get the top offset
const itemRect = scrollItem.offsetTop // [UPDATED]
const wrapperRect = scrollWrapper.offsetTop // [UPDATED]
// Scroll the wrapper to the offset of the list item we're scrolling to
scrollWrapper.scrollTo(0, itemRect - wrapperRect)
}
}
You onInputChange
function could then be updated as follows:
onInputChange = ({ target }) => {
const { cards } = this.state;
const { options } = this.state;
const nexState = cards.map((card, index) => {
if (card.cardName !== target.name) return card;
const options = card.options.map(opt => {
const checked = opt.radioName === target.value;
return {
...opt,
selected: checked
}
})
// [ADD] When input changes (ie something is set), scroll to next item
this.scrollToItemByIndex( index + 1 )
const style = options.every(option => !option.selected) ? 'danger' : 'info'
return {
...card,
style,
options
}
});
this.setState({ cards: nexState })
}
Also, your onSubmit
would be updated to scroll to any form items that are not valid:
onSubmit = () => {
this.state.cards.forEach((card, index) => {
var invalid = card.options.every(option => !option.selected)
if (invalid) {
card.style = 'danger'
// [ADD] this item has invalid input, so scroll to it
this.scrollToItemByIndex(index)
}
else {
card.style = 'info'
}
});
...
}
Finally, you'd need to update your component's render method with the following, to ensure that the query selectors above function correctly:
<ul class="nav nav-pills nav-stacked anyClass" scrollWrapper="scrollWrapper">
and:
{cards.map((card, idx) => (<ListGroup bsStyle="custom" scrollIndex={idx}>
...
</ ListGroup >)}
[UPDATED] A full working sample can be found here: https://stackblitz.com/edit/react-z7nhgd?file=index.js
Hope this helps!
这篇关于自动向下滚动到下一个列表组项目并在移动视图的中央显示内容(反应)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!