Helpex - Trao đổi & giúp đỡ Đăng nhập
40

Sử dụng jQuery, cách tốt nhất để tìm phần tử biểu mẫu tiếp theo trên trang, bắt đầu từ một phần tử tùy ý là gì? Khi tôi nói yếu tố hình thức Ý tôi là <input>, <select>, <button>hoặc <textarea>.

Trong các ví dụ sau, phần tử có id "this" là điểm bắt đầu tùy ý và phần tử có id "tiếp theo" là phần tử tôi muốn tìm. Câu trả lời giống nhau sẽ hoạt động cho tất cả các ví dụ.

Ví dụ 1:

<ul>
 <li><input type="text" /></li>
 <li><input id="this" type="text" /></li>
</ul>

<ul>
 <li><input id="next" type="text" /></li>
</ul>

<button></button>

Ví dụ 2:

<ul>
 <li><input id="this" type="text" /></li>
</ul>

<button id="next"></button>

Ví dụ 3:

<input id="this" type="text" />
<input id="next" type="text" />

Ví dụ 4:

<div>
  <input id="this" type="text" />
  <input type="hidden" />
  <div>
    <table>
      <tr><td></td><td><input id="next" type="text" /></td></tr>
    </table>
  </div>
  <button></button>
</div>

CHỈNH SỬA: Hai câu trả lời được cung cấp cho đến nay đều yêu cầu viết một số thứ tự cho tất cả các phần tử đầu vào trên trang. Như tôi đã đề cập trong phần nhận xét của một trong số họ, đây là loại điều tôi đang làm và tôi muốn có một giải pháp chỉ đọc vì điều này sẽ xảy ra bên trong một plugin.

40 hữu ích 0 bình luận 60k xem chia sẻ
12 trả lời 12
52

thanh danh,

Điều gì về việc sử dụng .index?

ví dụ $(':input:eq(' + ($(':input').index(this) + 1) + ')');

52 hữu ích 5 bình luận chia sẻ
14

redsquare hoàn toàn đúng và cũng là một giải pháp tuyệt vời, mà tôi cũng đã sử dụng trong một dự án của mình.

Tôi chỉ muốn chỉ ra rằng anh ta thiếu một số dấu ngoặc đơn, vì giải pháp hiện tại nối chỉ mục với 1, thay vì thêm chúng lại với nhau.

Vì vậy, giải pháp sửa chữa sẽ giống như sau:

$(":input:eq(" + ($(":input").index(this) + 1) + ")");

Xin lỗi về bài đăng kép, nhưng tôi không thể tìm cách nhận xét bài đăng của anh ấy ...

14 hữu ích 0 bình luận chia sẻ
10

Giải pháp này không yêu cầu chỉ mục và cũng hoạt động tốt với tabindex - nói cách khác, nó cung cấp cho bạn phần tử chính xác mà trình duyệt sẽ cung cấp cho bạn trên tab, mọi lúc mà không cần thêm bất kỳ thao tác nào.

function nextOnTabIndex(element) {
      var fields = $($('form')
                    .find('a[href], button, input, select, textarea')
                    .filter(':visible').filter('a, :enabled')
                    .toArray()
                    .sort(function(a, b) {
                      return ((a.tabIndex > 0) ? a.tabIndex : 1000) - ((b.tabIndex > 0) ? b.tabIndex : 1000);
                    }));


      return fields.eq((fields.index(element) + 1) % fields.length);
    }

Nó hoạt động bằng cách lấy tất cả các trường có thể tab trong biểu mẫu (như được cho phép bởi http://www.w3.org/TR/html5/editing.html#focus-management ), rồi sắp xếp các trường dựa trên ( http: // www .w3.org / TR / html5 / edit.html # sequential-focus-navigation-and-the-tabindex-property ) để tìm ra phần tử tiếp theo để tab. Khi có điều đó, nó sẽ xem trường được truyền vào ở đâu trong mảng đó và trả về phần tử tiếp theo.

Một số điều cần lưu ý:

  • jQuery dường như hỗ trợ sort () trên một đối tượng jQuery, nhưng tôi không thể tìm thấy nó một cách rõ ràng trong tài liệu, do đó gọi toArray () và sau đó cuộn lại mảng trong một đối tượng jQuery.
  • Có những trường khác mà bạn có thể tab vào, nhưng tôi đã bỏ chúng đi vì chúng không phải là trường biểu mẫu chuẩn.

Mã tôi đã sử dụng để kiểm tra điều này là (sử dụng jQuery 1.7):

<script>
  $(function() {
    $('a[href], button, input, select, textarea').click(function() {
      console.log(nextOnTabIndex($(this)).attr('name'));
    })
  });
</script>

<form>
  <input type='text' name='a'/>
  <input type='text' name='b' tabindex='1' />
  <a>Hello</a>
  <input type='text' name='c'/>
  <textarea name='d' tabindex='2'></textarea>
  <input id='submit' type='submit' name='e' tabindex='1' />
</form>
10 hữu ích 1 bình luận chia sẻ
7

Sau khi thử mọi mã tôi có thể tìm thấy (và gặp sự cố giữa các trình duyệt), tôi đã tìm thấy một mã hoạt động trong các trình duyệt hàng đầu. Không thể sử dụng các quy trình trước đó vì một số vấn đề lạ.

$(document.body).keydown(function(event) {
    if(event.keyCode == 13 ) {
        $(":input")[$(":input").index(document.activeElement) + 1].focus();
        return false;
    }
});

Hy vọng điều này sẽ giúp người khác. Thưởng thức.

7 hữu ích 0 bình luận chia sẻ
2

Bạn có thể cung cấp cho mỗi mục biểu mẫu một id (hoặc tên lớp duy nhất) xác định nó là một phần tử biểu mẫu và cũng cấp cho nó một chỉ mục. Ví dụ:

<div>
    <input id="FormElement_0" type="text" />
    <input id="FormElement_1" type="text" />
<div>

Sau đó, nếu bạn muốn chuyển từ phần tử đầu tiên sang phần tử thứ hai, bạn có thể làm như sau:

//I'm assuming "this" is referring to the first input

//grab the id
var id = $(this).attr('id');

//get the index from the id and increment it
var index = parseInt(id.split('_')[0], 10);
index++;

//grab the element witht that index
var next = $('#FormElement_' + index);

Lợi ích của việc này là bạn có thể gắn thẻ bất kỳ phần tử nào tiếp theo, bất kể vị trí hoặc loại. Bạn cũng có thể kiểm soát thứ tự chuyển tải của mình. Vì vậy, nếu vì bất kỳ lý do gì bạn muốn bỏ qua một phần tử và quay lại phần tử đó sau, bạn cũng có thể làm điều đó.

2 hữu ích 2 bình luận chia sẻ
2

Bạn có thể thực hiện việc này để có danh sách đầy đủ các phần tử biểu mẫu mà bạn đang tìm kiếm:

var yourFormFields = $("yourForm").find('button,input,textarea,select');

Sau đó, sẽ dễ dàng tìm thấy phần tử tiếp theo:

var index = yourFormFields.index( this ); // the index of your current element in the list. if the current element is not in the list, index = -1

if ( index > -1 && ( index + 1 ) < yourFormFields.length ) { 

                    var nextElement = yourFormFields.eq( index + 1 );

                    }
2 hữu ích 0 bình luận chia sẻ
1

Hoặc bạn có thể sử dụng thuộc tính html 'tabindex' để khi người dùng tab xung quanh một biểu mẫu, nó sẽ chuyển đến tabindex = "i" thành tabindex = "i + 1". Bạn có thể sử dụng jQuery để lấy thuộc tính rất dễ dàng. Cũng sẽ tạo ra một sự sụt giảm tốt cho người dùng mà không cần bật javascript.

1 hữu ích 1 bình luận chia sẻ
1

Tôi đã nghĩ ra một hàm thực hiện công việc mà không cần xác định rõ ràng các chỉ mục:

function nextInput(form, id) {
    var aInputs = $('#' + form).find(':input[type!=hidden]');
    for (var i in aInputs) {
        if ($(aInputs[i]).attr('id') == id) {
            if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
                return aInputs[parseInt(i) + 1];
            }
        }
    }
}

Và đây là một ví dụ hoạt động. Các thẻ biểu mẫu là để nhất quán. Tất cả những gì bạn thực sự cần là cha mẹ chung và thậm chí có thể chỉ sử dụng thẻ body làm cha mẹ (với một chút sửa đổi đối với hàm).

Dán tệp này vào một tệp và mở bằng firefox / firebug và bạn sẽ thấy nó trả về phần tử chính xác cho tất cả các ví dụ của bạn:

<html>
  <head>
    <script src="http://www.google.com/jsapi"></script>
    <script>
      function nextInput(form, id) {
        var aInputs = $('#' + form).find(':input[type!=hidden]');
        for (var i in aInputs) {
          if ($(aInputs[i]).attr('id') == id) {
            if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
              return aInputs[parseInt(i) + 1];
            }
          }
        }
      }

      google.load("jquery", "1.2.6");
      google.setOnLoadCallback(function() {
        console.log(nextInput('myform1', 'this1'));
        console.log(nextInput('myform2', 'this2'));
        console.log(nextInput('myform3', 'this3'));
        console.log(nextInput('myform4', 'this4'));
      });
    </script>
  </head>
  <body>
    <form id="myform1">
      <ul>
         <li><input type="text" /></li>
         <li><input id="this1" type="text" /></li>
      </ul>
      <ul>
        <li><input id="next1" type="text" /></li>
      </ul>
    </form>

    <form id="myform2">
      <ul>
         <li><input type="text" /></li>
         <li><input id="this2" type="text" /></li>
      </ul>
      <ul>
        <li><input id="next2" type="text" /></li>
      </ul>
    </form>

    <form id="myform3">
      <input id="this3" type="text" />
      <input id="next3" type="text" />
    </form>

    <form id="myform4">
      <div>
        <input id="this4" type="text" />
        <input type="hidden" />
        <div>
        <table>
          <tr><td></td><td><input id="next4" type="text" /></td></tr>
        </table>
        </div>
        <button></button>
      </div>
    </form>
  </body>
</html>
1 hữu ích 3 bình luận chia sẻ
0

Bạn có thể sử dụng plugin trường jQuery cho phép bạn làm điều đó.

0 hữu ích 0 bình luận chia sẻ
0
var elementSelector = "input:visible,textarea:visible";
var nextSibling = $(elementSelector )[$(elementSelector ).index() + 1];
//$(nextSibling).focus(); possible action

Tôi chỉ nghĩ rằng giải pháp ở trên là đơn giản hơn, hoặc bạn có thể thêm tất cả vào một dòng nếu bạn muốn :-)

var nextSibling = $("input:visible,textarea:visible")[$("input:visible,textarea:visible").index() + 1];
0 hữu ích 0 bình luận chia sẻ
0

Điều này hoạt động tốt đối với tôi và nó bỏ qua chính xác các đầu vào ẩn:

input_el.nextAll( 'input:visible:first' ).focus();
0 hữu ích 0 bình luận chia sẻ
0

Tất cả các giải pháp sử dụng chỉ mục (hoặc nextAll) sẽ chỉ hoạt động khi tất cả các đầu vào biểu mẫu là anh chị em, ví dụ trong cùng một <div>khối. Phần sau sẽ làm tròn điều đó bằng cách tạo một mảng id của tất cả các đầu vào hiển thị, không chỉ đọc trên trang và chọn ra cái đầu tiên sau điều khiển hiện tại, kết thúc vòng nếu điều khiển hiện tại là điều khiển cuối cùng trên trang.

ids = $(":input:visible:not([readonly])").map(function () { return this.id });
nextId = ids[($.inArray($(this).attr("id"), ids) + 1) % ids.length];
$("#" + nextId).focus();

Sử dụng chức năng bản đồ làm cho nó ngắn gọn hơn một chút so với các giải pháp liên quan đến trình vòng lặp.

0 hữu ích 1 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript jquery , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading