首页 > 解决方案 > 如何将函数应用于包含选定文本的字段,具有多个字段的表单?(原版 JavaScript)

问题描述

在具有多个字段(<input><textarea>)的表单中,我需要用 html 标签(即<b>)包装选定的文本。所以我写了以下代码:

const form = document.forms[0];
const fields = form.querySelectorAll("input, textarea");

form.onsubmit = () => {
  formatText("b");
  return false;
}

const formatText = (key) => {
  fields.forEach(el => {
    var start = el.selectionStart;
    var end = el.selectionEnd;
    var len = el.value.length;
    var sel_txt = el.value.substring(start, end);
    if (sel_txt !== "") {
      el.value = el.value.substring(0, start) + `<${key}>${sel_txt}</${key}>` + el.value.substring(end, len);
    }
  });
}
input,
textarea {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 30px;
  margin-bottom: 20px;
  border: 1px solid black;
  padding: 10px;
}
<form>
  <input name="a[]" type="text" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
  <textarea name="a[]">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</textarea>
  <textarea name="a[]">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</textarea>
  <button type="submit">Submit</button>
</form>

有用。但我认为这不是一个好的解决方案,因为formatText函数会遍历所有表单字段,而我只想将该函数应用于包含选定文本的字段。

在没有任何 id/class 选择器的情况下,我如何在 Vanilla JavaScript 中做到这一点?

换句话说:有没有办法知道包含选定文本的字段是什么?

标签: javascripthtmlforms

解决方案


为了避免在 上运行的循环submit,我倾向于使用一个变量来跟踪哪个元素最近具有焦点。

我建议在范围内的所有表单元素上使用,并更改变量以引用每个事件addEventListener上最近关注的元素。focus

提交表单后,您可以引用selectedField变量以确定要处理的元素。

<script>
    const form = document.forms[0];
    const fields = form.querySelectorAll("input, textarea");
    
    var selectedField = null;

    fields.forEach(field => {
        field.addEventListener('focus', (event) => {
            selectedField = event.target;
        });
    });

    form.onsubmit = () => {
        formatText("b", selectedField);
        return false;
    }

    const formatText = (key, el) => { 
        if(!el) return;
           
        var start = el.selectionStart;
        var end = el.selectionEnd;
        var len = el.value.length;
        var sel_txt = el.value.substring(start, end);
        if (sel_txt !== "") {
            el.value = el.value.substring(0, start) + `<${key}>${sel_txt}</${key}>` + el.value.substring(end, len);
        }
    }
</script>

在实践中,您可能希望将变量保留在全局范围之外。

我不确定这个解决方案比你的解决方案好多少。也许如果您有许多表单字段,它会减少处理工作 - 但您仍然必须遍历所有元素以添加事件侦听器。


推荐阅读