2013-05-31 33 views
11

Tôi đang thực sự đấu tranh để xem cách thực hiện việc này. Tôi muốn kiểm tra xem một lớp có tồn tại ở đâu đó trong một trong các phần tử cha của một phần tử hay không.Kiểm tra xem lớp học có tồn tại ở đâu đó trong phụ huynh - vanilla JS

Tôi không muốn sử dụng bất kỳ thư viện nào, chỉ cần vani JS.

Trong các ví dụ bên dưới, nó sẽ trả về true nếu phần tử được đề cập nằm ở đâu đó trong phần tử con của một phần tử có "lớp học" làm tên lớp.

Tôi nghĩ rằng nó sẽ là một cái gì đó như thế này với jQuery:

if($('#the-element').parents().hasClass('the-class')) { 
    return true; 
} 

Vì vậy, đây trả về true:

<div> 
    <div class="the-class"> 
     <div id="the-element"></div> 
    </div> 
</div> 

Vì vậy, thực hiện điều này:

<div class="the-class"> 
    <div> 
     <div id="the-element"></div> 
    </div> 
</div> 

... nhưng điều này trả về false:

<div> 
    <div class="the-class"> 
    </div> 
    <div id="the-element"></div> 
</div> 
+2

Sử dụng jquery này sẽ có gần (' theClass.) .length –

+0

Bạn có bất kỳ mã nào để hiển thị những gì bạn đã thử để chúng tôi có thể thấy nơi bạn có thể cần trợ giúp không? –

+0

Vì vậy, bạn muốn xem liệu có bất kỳ tổ tiên nào, hoặc anh chị em ruột của tổ tiên, có một tên lớp nhất định không? –

Trả lời

23

Bạn sẽ phải làm điều đó một cách đệ quy:

// returns true if the element or one of its parents has the class classname 
function hasSomeParentTheClass(element, classname) { 
    if (element.className.split(' ').indexOf(classname)>=0) return true; 
    return element.parentNode && hasSomeParentTheClass(element.parentNode, classname); 
} 

Demonstration (mở giao diện điều khiển để xem true)

+0

Hoàn hảo. Cảm ơn. – user2143356

+1

điều này không thành công nếu một phụ huynh không có lớp học –

+0

@ Carl91 Nếu một phần tử không có lớp, 'className' là' "" '. –

4

Các fiddle

function hasClass(element, className) { 
    var regex = new RegExp('\\b' + className + '\\b'); 
    do { 
    if (regex.exec(element.className)) { 
     return true; 
    } 
    element = element.parentNode; 
    } while (element); 
    return false; 
} 

HOẶC

function hasClass(element, className) { 
    do { 
    if (element.classList && element.classList.contains(className)) { 
     return true; 
    } 
    element = element.parentNode; 
    } while (element); 
    return false; 
} 
2

Tôi tin rằng if($('#the-element').parents('.the-class').length) sẽ hiệu quả hơn, nhưng có lẽ không phải là người có thể đọc được; đó, với querySelector trong hình, có thể được thay thế bằng các phương pháp sau đây:

function hasParent(element, parentSelector) { 
    var potentialParents = document.querySelectorAll(parentSelector); 
    for(i in potentialParents) if(potentialParents[i].contains(element)) 
     return potentialParents[i]; 
    return false; 
} 

Đó sẽ cung cấp cho bạn khả năng để làm:

var elm = document.getElementById('the-element'); 
if(hasParent(elm, '.the-class')) return true; 
+0

Tôi đã có cùng một vấn đề và tôi đã đưa ra giải pháp này, vì vậy tôi nghĩ rằng tôi muốn đăng nó ở đây cho những người khác phải đối mặt với vấn đề này. – Fardin

+0

tại sao hiệu quả hơn $? – SuperUberDuper

+0

@SuperUberDuper Tôi đã không đề xuất rằng jQuery hiệu quả hơn mã vani đơn lẻ, nếu đó là những gì bạn đang yêu cầu. Tôi đã ngụ ý, tôi nghĩ rằng, bằng cách sử dụng một bộ chọn với 'cha mẹ' có thể dẫn đến một vòng lặp ít hơn, so với dòng jq của OP. Phrasing xấu, huh? – Fardin

0

Bởi vì ID phải là duy nhất trên bối cảnh tài liệu, bạn chỉ có thể sử dụng thay vì:

return !!document.querySelector('.the-class #the-element'); 

Nếu bạn muốn bao gồm yếu tố riêng của mình, bạn có thể sử dụng:

return !!document.querySelector('.the-class #the-element, #the-element.the-class'); 
0

dụ của tôi cho Vanilla JS, đó là sử dụng một tương đương vani của parents() từ jQuery

var htmlElement = <htmlElement>, 
    parents = [], 
    classExist; 
while (htmlElement = htmlElement.parentNode.closest(<parentSelector>)) { 
    parents.push(htmlElement); 
} 
classExist = (parents > 0); 

Vì vậy chọn của bạn chỉ để được một .className

Và chỉ cần kiểm tra nếu cha mẹ là> 0

2

Tôi ổn với chức năng Denys Séguret được đăng, có vẻ thanh lịch và tôi thích nó. Tôi chỉ tinh chỉnh một chút chức năng vì nếu lớp được chỉ định trong tham số, không có trong toàn bộ DOM, nó không thành công khi đệ quy đến đối tượng tài liệu vì đúng là chúng ta kiểm soát nếu phần tử có nút cha (trong dòng cuối cùng, và khi tài liệu là phần tử nút cha là null) nhưng trước khi chúng ta thực thi dòng trước đó, và khi phần tử là tài liệu, document.classNameundefined và nó không thành công, do đó điều khiển phải được di chuyển lên trên cùng.

function hasSomeParentTheClass(element, classname) { 
    // 
    // If we are here we didn't find the searched class in any parents node 
    // 
    if (!element.parentNode) return false; 
    // 
    // If the current node has the class return true, otherwise we will search 
    // it in the parent node 
    // 
    if (element.className.split(' ').indexOf(classname)>=0) return true; 
    return hasSomeParentTheClass(element.parentNode, classname); 
} 
0

Bạn có thể sử dụng somecontains để đạt được các kết quả:

function hasParentWithMatchingSelector (target, className) { 
    return [...document.querySelectorAll(className)].some(el => 
    el !== target && el.contains(target) 
) 
} 

// usage 
hasParentWithMatchingSelector(myElement, '.some-class-name'); 
+0

Điều này thực sự thông minh .. chỉ cần sửa chữa vì 'el.contains (el) trả về true'. Vì vậy, chúng ta nên viết lại nó như: 'el! == target && el.contains (target)' – chrislopresto

+0

cố định nhờ ... –

0

Dưới đây là một giải pháp đơn giản, đủ

if ($elem.parents('.the-class').length) { 
    return true 
} 
Các vấn đề liên quan