2017-02-17 103 views
0

我有几个输入html元素。在输入im的变化事件(tab-out)中,制作一个ajax文章并取回html。然后我用这个新的html替换现有的html。这样做会减少对下一个输入元素的关注。 然而,在我做ajax post im存储当前焦点元素的id之前,我可以在html被替换后重新调整相同的输入。但它不工作如何在重新加载html后重新关注输入元素

下面是我的代码

<div id="mycontainer"> 
    <input id="input1" /> 
    <input id="input2" /> 
    <input id="input3" /> 
</div> 


$(function() { 
    $("input").change(function() { 
     $.ajax(
      { 
       data: "somedata", 
       url: "someurl", 
       method: "POST" 
      }) 
      .done(function (response) { 
        var currentElement = $(':focus').attr("id"); 
        $("#mycontainer").html(response) 
        $("#" + currentElement).focus(); 
       }) 
    }) 
}) 
+1

更改事件在模糊事件后触发,焦点移动。你调试过并检查currentElement是什么吗?顺便说一句,取代所有的HTML是一个坏主意,你失去处理程序,重点,滚动位置... –

回答

2

变化事件触发,所以焦点已经转移。如果您想专注于已更改的元素,则可以使用event.target获取对已更改的输入的引用。

$("input").change(function (event) { 
     $.ajax({ 
      data: "somedata", 
      url: "someurl", 
      method: "POST" 
     }) .done(function (response) { 
       var currentElement = event.target.id; 
       $("#mycontainer").html(response) 
       $("#" + currentElement).focus(); 
     }); 
}) 

如果你想专注于保持它的位置,你的代码应该工作,这是证明。

const HTML = ` 
 
    <input id="input1" /> 
 
    <input id="input2" /> 
 
    <input id="input3" /> 
 
`; 
 

 
$(() => { 
 
    $("input").change(() => { 
 
    // Add async code to fake ajax 
 
    new Promise((resolve, reject) => { 
 
     setTimeout(() => resolve(HTML), 100); 
 
    }).then(response => { 
 
     const currentElement = $(':focus').attr("id"); 
 
     $("#mycontainer").html(response) 
 
     $("#" + currentElement).focus(); 
 
    }); 
 
    }) 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="mycontainer"> 
 
    <input id="input1" /> 
 
    <input id="input2" /> 
 
    <input id="input3" /> 
 
</div>

然而,在我的评论中提到,这是穷人的做法,因为你失去的处理程序,所以你必须得复位处理,也许滚动位置。为了避免这种情况,您可以让AJAX返回数据并只更新需要更新的位。

+0

这会得到焦点回到ajax加载后更改的输入,而不是新集中输入。 –

+0

@BulentVural那么,如果OP想要集中新的输入,现有的代码应该可以工作,并添加一个解释。 –

+0

然后我upvote你的答案@Juan :)也感谢您的答案底部的评论,这将是解决这种要求的最佳途径。 –

0

是否链接了jQuery方法调用,让他们在指定的顺序运行,帮助吗?

.done(function (response) { 
     var currentElement = $(':focus').attr("id"); 
     $("#mycontainer") 
      .html(response) 
      .find("#" + currentElement) 
      .focus(); 
     }) 
+0

为什么会这样? Chaining只是语法糖? –

1

当你点击页面(包括按钮/链接加载您的Ajax内容)上的某个地方,单击元素立即把焦点。所以就在改变html之前,现在已经太晚以至于无法存储关注的ID。您需要将其存储在焦点更改上。

编辑: 由于没有“点击”参与OP的问题,我提出了上述方案的更新版本:存储改变输入焦点处理器运行Ajax的东西。

let changedInput; 
 
$(document).on('focus', 'input', function() { 
 
    if (changedInput) { 
 
    // do whatever with changedInput.val() needed here 
 
    changedInput = null; 
 
    const currentElement = $(this).attr('id'); 
 
    $.ajax({ 
 
     data: "somedata", 
 
     url: "someurl", 
 
     method: "POST" 
 
     }) 
 
     .done(function(response) { 
 
     $("#mycontainer").html(response); 
 
     $("#" + currentElement).focus(); 
 
     }) 
 
    } 
 

 
}); 
 

 
$(document).on('change', 'input', function() { 
 
    changedInput = this; 
 
}) 
 

 

 

 
/* BEGIN FAKE AJAX STUFF 
 
* 
 
*/ 
 
let counter = 0; 
 
$.ajax = function(params) { 
 
    $('#msg').text("Fake AJAX Loading..."); 
 
    return { 
 
    done: function(cb) { 
 
     setTimeout(function() { 
 
     $('#msg').text(""); 
 
     cb(` 
 
     <div id="mycontainer"> 
 
     <input value="${counter}" id="input1" /> 
 
     <input value="${counter}" id="input2" /> 
 
     <input value="${counter++}" id="input3" /> 
 
     </div> 
 
     `); 
 
     }, 300); 
 
    } 
 
    } 
 
} 
 
/* END FAKE AJAX STUFF */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div style="height:20px;" id="msg"></div> 
 
<div id="mycontainer"> 
 
    <input value="" id="input1" /> 
 
    <input value="" id="input2" /> 
 
    <input value="" id="input3" /> 
 
</div>
模糊事件后

+0

这可能会起作用,但可以更简单,请参阅我的回答 –

+0

我不想将焦点放在已更改的元素上,而是将它保留在原来的位置 – LP13