2009-05-08 4 views
8

Вот моя цель: сделать что-нибудь на элементе, <optgrooup>, если все его дети невидимы.jQuery выбор элементов без видимых детей

Мой код ниже показывает красный, если он имеет любой невидимых детей. Но я хочу сделать это, только если все дети невидимы. Если элемент имеет какие-либо дочерние элементы, которые не видны, не выделяйте его.

Как я могу настроить селектор jQuery для этого?

Заранее спасибо.

<select multiple="multiple" name="availableInstanceId" id="availableInstanceId"> 
<optgroup label="Option Group 1"> 
    <option >visible item 1</option> 
    <option >visible item 2</option> 
</optgroup> 
<optgroup label="Option Group 2 - Should be highlighted"> 
    <option style="display:none;">invisible A</option> 
    <option style="display: none">invisible B</option> 
</optgroup> 

<optgroup label="Option Group 3 - Should not be highlighted"> 
    <option >visible C</option> 
    <option style="display: none">invisible D</option> 
</optgroup></select> 

<script type="text/javascript"> 
var filterOptions = function(e) { 
    // Goal: highlight the <optgroup>'s that have *only* invisible children 
    $('#availableInstanceId > * > *:hidden').parent().css("border","3px solid red"); 
} 
$(document).ready(function() { 
    filterOptions(); 
}); 
</script> 

Скриншот картинки здесь: http://img144.imageshack.us/img144/556/selectexample.gif

+0

насчет сравнивая длины массивов между невидимым и общим чи ldren? –

ответ

0

Вам нужно сравнить массив всех: видимый VS.: скрытый

вот некоторые псевдо-код

if ($("#element:hidden").length == $("#element:visible").length) { 
    // Do stuff 
} ... 
1

Как насчет двух строк? Один, чтобы включить его для каждого элемента, и один, чтобы отключить его снова для каждого с видимым ребенком?

$('#availableInstanceId > *').css("border","3px solid red"); 
$('#availableInstanceId > * > *:visible').parent().css("border","none"); 
12

Предполагая, что вы хотите, чтобы исключить элементы без дочерних элементов:

$(":has(*):not(:has(:visible))") 

Working example.

UPDATE: Это имеет гораздо более высокую производительность, чем мой оригинальный ответ:

$(":hidden").parent().not($(":visible").parent()) 
+1

+1 Так приятно, что мне пришлось отказаться от моего собственного взлома, чтобы вставить код в пример :) – cgp

+0

Ха, спасибо! Я обычно опасаюсь вкладывать столько логиков в селекторов, но этот был слишком хорош, чтобы уйти. –

+0

На самом деле есть более быстрый способ сделать это с обходом вместо выбора: http://stackoverflow.com/questions/841401/jquery-selection-of-elements-with-no-visible-children/841568#841568 –

2

Это намного лучше perfo rmance чем мой original answer:

$(":hidden").parent().not($(":visible").parent()) 
+0

Не могли бы вы объяснить логику кода? – Jrgns

1

Заслуга Jed Schmidt. Следующий код работает в IE8.

Обратите внимание, что IE8 фактически не скрывает элементы <option>, несмотря на стиль display: none. Также IE8, похоже, не принимает border стилей для <optgroup> элементов.

Работа образца: http://jsbin.com/aquya (редактируемые через http://jsbin.com/aquya/edit)

$(document).ready(function() { 
    // Prevent CSS inherits 
    $("option").css('backgroundColor', 'white') 

    $("option") 
    .filter(function(){ 
     return this.style.display == 'none'; 
    }) 
    .parent() 
    .not($('option').filter(function(){ 
     return this.style.display != 'none'; 
    }).parent()) 
    .css('backgroundColor', 'blue') 
    .css('border', '1px solid red'); //this doesn't work in IE8 
}); 
+0

Спасибо, это было здорово, по крайней мере, для выделения К сожалению, я действительно хочу, чтобы это * скрыть * optgroup, а не выделить его. Я должен был сказать это в оригинальном вопросе - я не думал, что это изменит ситуацию, поскольку моя главная забота была о селекторе, - но оказывается, что это действительно имеет значение, поскольку, как вы уже упоминали ранее, IE имеет ошибка со скрытыми опциями выбора (и optgroups - см. http://dev.jquery.com/ticket/1100). Итак, похоже, что мне не повезло с IE – Glen

+0

Если вы не против дополнительной работы и усложнения, возможно, вы можете подделать ее, временно удалив элементы, которые вы хотите скрыть (я предполагаю, IE может не понравиться или). – brianpeiris

1

// ответ на вопрос меняющийся CSS по желанию

if($.browser.msie || $.browser.safari){ 

     $('optgroup:not(:has(:hidden))').css("border","3px solid red"); 

    } else { 

     $('optgroup:not(:has(:visible))').css("border","3px solid red"); 

    } 

// удалить пустой optgroups пример

if($.browser.msie || $.browser.safari){ 

     $('optgroup:not(:has(:hidden))').remove(); 

    } else { 

     $('optgroup:not(:has(:visible))').remove(); 

    }