【问题标题】:How can I insert text via button click at the cursor in the most recent textbox used?如何通过按钮在最近使用的文本框中单击光标插入文本?
【发布时间】:2020-07-28 11:08:50
【问题描述】:

我有一个包含多个文本框和一组按钮的表单。使用下面的 Javascript,我可以单击一个按钮并将文本插入其中一个命名框。

是否可以在单击按钮时将文本插入最新/活动的文本框?

目前我有这个,但它使用的是文本框的特定 ID,而不是最近使用/活动的 ID;

   $( 'input[type=button]' ).on('click', function(){
      var cursorPos = $('#my_text_box').prop('selectionStart');
      var v = $('#my_text_box').val();
      var textBefore = v.substring(0,  cursorPos );
      var textAfter  = v.substring( cursorPos, v.length );
      $('#my_text_box').val( textBefore+ $(this).val() +textAfter );
    });

JSFiddle 上的示例更清晰;

http://jsfiddle.net/bd1xf0sj/1/

这个想法取决于单击按钮时您所在的文本框,而不是使用某个文本框的 ID。想法是可以单击按钮并且可以使用任何文本框。

【问题讨论】:

  • 是什么决定了您案例中的活动字段?
  • 理想情况下是单击按钮时光标所在的文本框

标签: javascript jquery


【解决方案1】:

您可以创建一个变量来存储最新的文本框,并在文本框像这样聚焦时更新它:

let currentInput = $('#text1');
$(document).on('focus', 'textarea', function() {
  currentInput = $(this);
})

然后使用此变量更新文本,就像您使用 #my_text_box 所做的那样:

$( 'input[type=button]' ).on('click', function(){
  let cursorPos = currentInput.prop('selectionStart');
  let v = currentInput.val();
  let textBefore = v.substring(0,  cursorPos );
  let textAfter  = v.substring( cursorPos, v.length );
  currentInput.val( textBefore + $(this).val() + textAfter );
});

Fiddle

更新:在插入文本后保留光标位置的一些修改:

let currentInput = document.getElementById('text1');
$(document).on('focus', 'textarea', function() {
    currentInput = this;
})

$( 'input[type=button]' ).on('click', function(){
  let cursorPos = currentInput.selectionStart;
  let v = currentInput.value;
  let textBefore = v.substring(0,  cursorPos );
  let textAfter  = v.substring( cursorPos, v.length );
  currentInput.value = textBefore + this.value + textAfter;
  
  cursorPos += this.value.length;
  currentInput.focus();
  currentInput.setSelectionRange(cursorPos, cursorPos);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
    <textarea id="text1" cols="40" rows="3"></textarea>
    <textarea id="text2" cols="40" rows="3"></textarea>
    <textarea id="text3" cols="40" rows="3"></textarea>
    <textarea id="text4" cols="40" rows="3"></textarea>
    <br>
    <input type="button" value="one" />
    <input type="button" value="two" />
    <input type="button" value="three" />
</form>

【讨论】:

  • 一个非常聪明的解决方案,您还可以使用特殊的类标记所有元素,这样您就可以在 textarea 中插入,也可以在输入类型文本中插入。
  • 如果您可以将修改直接插入到堆栈溢出答案中会不会很棒?这将对读者有益
  • @GM 我已经添加了。
【解决方案2】:

您可以在输入元素 HTML 中使用设置为布尔值 truefalsedata-attribute 跟踪输入焦点的当前状态。

首先将第一个data-current 属性定义为true,每隔一个属性定义为false。这样有一个默认设置为 true。然后我们运行一个事件来检查 textarea 元素上的 focus。如果 textareafocused,我们删除选择器 data-current 值的所有实例并将它们全部设置为 false,然后我们将当前事件目标 data-current 的值设置为 true

然后在 buttonsclick 事件中,我们检查我们的 textarea 元素 迭代 并运行一个 conditional 来检查他们的data-current value,我们找到一个设置为 true em> 然后将其 value 分配给 buttons 值

$('textarea').focus(e => {
  let $this = e.target;
  $('textarea').each((i, el) => {
    if(el.dataset.current === 'true'){
      el.dataset.current = false;
    }
    $this.dataset.current = true;
  })
  console.log(`Selected TextArea's id: ${$this.id}`)
})

$('input[type=button]').click(function(){
  const $this = $(this);
  const $ta = $('textarea');
  $ta.each((i, el) => {
  
    // do not retain previously set values when a new button
    // is selected on a different focused textarea
    el.dataset.current === 'true' ? 
      el.value = $this.val() :
      el.value = '';       
/*  
    // retain previously set values in TA's on button click
    // when new textarea is focused
    el.dataset.current === 'true' ?
      el.value = $this.val() : null;    
*/
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <textarea id="text1" data-current="true" cols="40" rows="3"></textarea>
  <textarea id="text2" data-current="false" cols="40" rows="3"></textarea>
  <textarea id="text3" data-current="false" cols="40" rows="3"></textarea>
  <br>
  <input type="button" value="one" />
  <input type="button" data-current="false" value="two" />
  <input type="button" data-current="false" value="three" />
</form>

【讨论】:

  • 感谢这是一个有趣的方法,在这种情况下,这可以很容易地扩展到威胁文本区域,并且还可以输入文本作为可能的候选插入,同时为输入文本创建另一个 for 循环。
【解决方案3】:

这实际上是一个简单而有趣的练习,有很多方法可以解决这个特殊问题,尽管我会建议我的。

这是解决 jsFiddle 示例的链接。

解释:

第 1 步:在所有 textarea 上添加 focus 事件侦听器。

第 2 步:在 textarea 集中,从现有的 last-focused.textarea 元素中删除类 last-focused

第 3 步:将 last-focused 类添加到当前关注的 textarea 元素。

第 4 步:在 button 上添加 click 侦听器

第 5 步:点击 button,选择 last-focused.textarea 元素,并将其内容替换为按钮的值。

注意:我们可以为类使用任何名称,只需将名称命名为 last-focused,因为它与当前上下文相关。

HTML:

<form>
  <textarea id="text1" cols="40" rows="3"></textarea>
  <textarea id="text2" cols="40" rows="3"></textarea>
  <br>
  <input type="button" value="one" />
  <input type="button" value="two" />
  <input type="button" value="three" />
</form>

JS + JQuery:

// Step 1
$('textarea').on('focus', function() {
    // Step 2
    $('textarea.last-focused').removeClass('last-focused');
    // Step 3
    $(this).addClass('last-focused');
});

// Step 4
$('input[type=button]').on('click', function() { 
    // Step 5
    $('textarea.last-focused').html($(this).val());
});

【讨论】:

    【解决方案4】:

    您可以使用 textarea 元素的焦点事件跟踪最后一个焦点输入元素,并在单击按钮时附加最后一个活动元素的值:

    var mostrecent=$('textarea')[0];
    $('textarea').each(function(i,item){
      $(item).focus(function(){
        mostrecent=this;
      });
    });
    

    var mostrecent=$('textarea')[0];
    $('textarea').each(function(i,item){
      $(item).focus(function(){
        mostrecent=this;
      });
    });
    $( 'input[type=button]' ).on('click', function(){
                var cursorPos = $('#text1').prop('selectionStart');
                var v = $('#text1').val();
                var textBefore = v.substring(0,  cursorPos );
                var textAfter  = v.substring( cursorPos, v.length );
                $(mostrecent).val( textBefore+ $(this).val() +textAfter );
            });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <form>
        <textarea id="text1" cols="40" rows="3"></textarea>
        <textarea id="text2" cols="40" rows="3"></textarea>
        <br>
        <input type="button" value="one" />
        <input type="button" value="two" />
        <input type="button" value="three" />
    </form>

    【讨论】:

      【解决方案5】:

      挂钩form events 以将最近的输入标记为“最近”(使用某些类)并取消标记所有其他输入。点击修改“最近”输入。

      您很可能需要onfocus,但也可能需要onchange,具体取决于您的具体用例。

      【讨论】:

        【解决方案6】:

        当前选中的字段是document.activeElement。

        【讨论】:

        • 当前选中的字段会变成你按下的按钮,所以这个答案是不正确的。
        • 好吧:function activeElement() { var fe = getSelection().focusNode;如果(!fe)返回null; if (fe.nodeType==3) fe=fe.parentNode; return fe.closest("div[contenteditable],input,textarea"); }
        猜你喜欢
        • 2014-04-06
        • 1970-01-01
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        相关资源
        最近更新 更多