2011-09-08 41 views
9

Tôi có thể tìm kiếm anh chị em "trở lên" bằng cách sử dụng JavaScript như thế nào? Về cơ bản, tôi cần một hàm prevUntil() tương tự như một hàm trong jQuery.Nhận anh chị em bằng JavaScript, không có thư viện

Tôi có rất nhiều <div> yếu tố, tất cả trên cùng cấp, chẳng hạn như:

<div></div> 
<div></div> 
<div></div> 
<div></div> 
<div></div> 
<div></div> 

Tôi muốn bắt đầu tại một yếu tố nhấp, và làm việc theo cách của tôi lên cây anh chị em cho đến khi một phù hợp với một lớp tiêu chí tên đạt được, sau đó dừng lại.

Làm cách nào để tôi thực hiện việc này?

+1

@glowcoder: Cá nhân tôi thấy thú vị khi biết jQuery thực sự là gì * đang làm *. – pimvdb

+2

@pimvdb, jQuery là mã nguồn mở, đừng ngần ngại tham khảo mã nguồn của nó nếu bạn quan tâm đến nó thực sự đang làm gì và quan trọng nhất là * làm thế nào * là nó đang thực hiện nó. –

+1

@Darin Dimitrov: Tôi biết, ý tôi là không có gì sai khi hỏi những gì đang diễn ra đằng sau hậu trường. – pimvdb

Trả lời

9

Câu trả lời này đã được xuất bản trước đây here để trả lời cho một câu hỏi tương tự.

Có một số cách để thực hiện.

Hoặc một trong những điều sau đây nên thực hiện thủ thuật.

// METHOD A (ARRAY.FILTER, STRING.INDEXOF) 
var siblings = function(node, children) { 
    siblingList = children.filter(function(val) { 
     return [node].indexOf(val) != -1; 
    }); 
    return siblingList; 
} 

// METHOD B (FOR LOOP, IF STATEMENT, ARRAY.PUSH) 
var siblings = function(node, children) { 
    var siblingList = []; 
    for (var n = children.length - 1; n >= 0; n--) { 
     if (children[n] != node) { 
      siblingList.push(children[n]); 
     } 
    } 
    return siblingList; 
} 

// METHOD C (STRING.INDEXOF, ARRAY.SPLICE) 
var siblings = function(node, children) { 
    siblingList = children; 
    index = siblingList.indexOf(node); 
    if(index != -1) { 
     siblingList.splice(index, 1); 
    } 
    return siblingList; 
} 

FYI: Các jQuery mã cơ bản là một nguồn lực lớn để quan sát Hạng A Javascript.

Đây là một công cụ tuyệt vời cho thấy mã cơ sở jQuery theo cách rất hợp lý. http://james.padolsey.com/jquery/

1

Có một tài sản previousSibling trong HTML DOM

Dưới đây là một số tài liệu tham khảo

http://reference.sitepoint.com/javascript/Node/previousSibling

+0

Thuộc tính 'previousSibling' là tham chiếu đến nút DOM, không phải là hàm. –

+0

Tôi hiểu điều đó hoàn toàn. Nhưng với một số lần lặp đơn giản, bạn có thể sử dụng điều này để tìm phần tử trước phù hợp với điều kiện của mình. –

1

Chỉ cần có một cái nhìn tại how jQuery does it.

prevUntil: function(elem, i, until) { 
    return jQuery.dir(elem, "previousSibling", until); 
}, 

Sử dụng chức năng while/looping caled dir(). PrevUntil chỉ tiếp tục cho đến khi previousSibling giống với phần tử until.

dir: function(elem, dir, until) { 
    var matched = [], 
     cur = elem[ dir ]; 

    while (cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until))) { 
     if (cur.nodeType === 1) { 
      matched.push(cur); 
     } 
     cur = cur[dir]; 
    } 
    return matched; 
}, 
4

Sử dụng .children kết hợp với .parentNode. Sau đó lọc NodeList, sau khi chuyển đổi nó thành một mảng: http://jsfiddle.net/pimvdb/DYSAm/.

var div = document.getElementsByTagName('div')[0]; 
var siblings = [].slice.call(div.parentNode.children) // convert to array 
       .filter(function(v) { return v !== div }); // remove element itself 
console.log(siblings); 
+0

NodeList để Mảng đúc bằng '[] .slice.call (nl)'? Nice ':)' –

+0

Giải pháp tuyệt vời, cảm ơn bạn! – Kholiavko

7

Example Sử dụng previousSibling:

var className = "needle"; 
    var element = clickedElement; 
    while(element.previousSibling && element.previousSibling.className != className) { 
     element = element.previousSibling; 
    } 
    element.previousSibling; // the element or null 
+0

'element.previousSibling.className' này là vấn đề. Nếu không có anh chị em nào trước đó có lớp mong muốn, 'element.previousSibling' cuối cùng sẽ trả về' null', vì vậy 'element.previousSibling.className' sẽ ném một lỗi. –

+2

Đó là để ngăn chặn một vòng lặp vô hạn! Chỉ đùa thôi. Tôi đã cập nhật – Joe

+0

Cảm ơn bạn, anh chàng có tên dài. – Francisc

2

Làm thế nào về điều này:

while (node = node.previousElementSibling) { 
    if ((' ' + node.className + ' ').indexOf('foo') !== -1) { 
     // found; do your thing 
     break; 
    } 
} 

Đừng bận tâm nói với tôi rằng điều này không làm việc trong IE8 ...

+0

Bạn có muốn bị lừa dối không? Vì tôi sẽ không lừa dối bạn, tôi không thể trả lời câu hỏi của bạn bởi vì bạn đã yêu cầu tôi không. – Wayne

+0

@Wayne Không, tôi không thích bị lừa dối. Tôi đã không yêu cầu bạn không trả lời câu hỏi của tôi. Xin hãy trả lời! Và tôi đã hỏi gì? Tôi nghĩ tôi đã trả lời một câu hỏi, không hỏi. –

+0

Xin lỗi sự hiểu lầm về phía tôi. Tôi nghĩ rằng bạn không nói với tôi nó không hoạt động trong IE8 theo nghĩa đen ... không phải là bạn đã biết. – Wayne

0

Về cơ bản bạn có getElementsByTagName và getElementsByName chúng trả về mảng và có thể sử dụng thẻ hoang dã. Nếu bạn muốn prevUntil bạn cần phải thực hiện một chức năng hoặc sử dụng một cái gì đó đã tồn tại như một thư viện.

function getElements() 
    { 
    var x=document.getElementsByName("*"); 
    alert(x.length); 
    } 

cập nhật

getElementByID trả về chỉ là một yếu tố.

Các vấn đề liên quan