动态新增input时scrollIntoView未触发滚动问题排查
问题根因
你的scrollIntoView滚动逻辑写在window load事件回调的顶层,仅会在页面首次加载完成时执行1次,没有绑定到「新增步骤」「新增食材」的按钮点击事件上;同时食材新增的回调函数里完全没有编写滚动相关逻辑,所以每次新增输入框后都不会触发自动滚动。
修复方法
将滚动逻辑分别移到两个新增按钮的点击回调内部,在DOM节点追加完成后,再获取当前最新的最后一个列表项执行滚动操作即可,删除原来写在load事件顶层的无效滚动代码。
修正后的核心JS代码如下:
window.addEventListener("load", function () { console.log('product create JS working') var add_more_fields = document.getElementById("add_more_fields") var remove_fields = document.getElementById("remove_fields") var add_more_fields_ingredients = document.getElementById("add_more_fields_ingredients") var remove_fields_ingredients = document.getElementById("remove_fields_ingredients") var ingredient_list = document.getElementById('ingredient-list') var instruction_list = document.getElementById('instruction-list') var imageInput = document.querySelector('.imageInput') var imagePreview = document.querySelector('.product-preview') var buttonSubmit = document.querySelector('#button-for-submit') imageInput.onchange = evt => { const [file] = imageInput.files if (file) { imagePreview.src = URL.createObjectURL(file) console.log(file.size + " this is the file size in bytes") } } // 新增步骤逻辑 add_more_fields.onclick = function () { var node = document.createElement("li") var newField = document.createElement('input') newField.setAttribute('type', 'text') newField.setAttribute('name', 'directions[]') newField.setAttribute('placeholder', 'Add Instruction') node.appendChild(newField) instruction_list.appendChild(node) // 新增完成后滚动到最新项 let items = instruction_list.querySelectorAll('li') let last = items[items.length - 1] last.scrollIntoView({ behavior: "smooth", block: "center" }) } remove_fields.onclick = function () { var input_tags = instruction_list.getElementsByTagName('li') if (input_tags.length > 1) { instruction_list.removeChild(input_tags[(input_tags.length) - 1]) } } // 新增食材逻辑 add_more_fields_ingredients.onclick = function () { var node = document.createElement("li") var newField = document.createElement('input') newField.setAttribute('type', 'text') newField.setAttribute('name', 'Ingredients[]') newField.setAttribute('placeholder', 'Add Ingredient') node.appendChild(newField) ingredient_list.appendChild(node) // 新增完成后滚动到最新项 let items = ingredient_list.querySelectorAll('li') let last = items[items.length - 1] last.scrollIntoView({ behavior: "smooth", block: "center" }) } remove_fields_ingredients.onclick = function () { var input_tags = ingredient_list.getElementsByTagName('li') if (input_tags.length > 1) { ingredient_list.removeChild(input_tags[(input_tags.length) - 1]) } } })
注意事项
- 必须等
appendChild把新节点插入到列表之后,再获取最后一个元素,否则取到的还是新增前的旧节点 - 两个新增列表(步骤、食材)的滚动逻辑要分别绑定到对应按钮的点击回调里,不要写在事件顶层只执行一次
内容的提问来源于stack exchange,提问作者LearningToProgram
相关产品推荐
相关产品推荐

