#javascript #html #jquery #css
#javascript #HTML #jquery #css
Вопрос:
У меня есть следующая разметка, в которой у меня есть div-держатель <div data-name="holder"></div>
для динамического содержимого.
<div id="main" class="agent">
<div class="page">
<div data-name="holder">
<div class="child">
<div class="area" >
<div class="box">
<div class="section" >
<div data-type="text" class="widget_type_text hidden" >
<div>
<label for="child0name">Full name</label>
</div>
<div>
<div class="validationMessage">
Enter Name
</div>
<input id="child0name" type="text" name="child[0][name]" required="" title="Enter full name">
</div>
</div>
<div data-type="radio" class="widget_type_radio" >
<div>
<fieldset>
<legend>Gender</legend>
<span data-value="male"><input id="child0genderMale" type="radio" name="child[0][gender]" value="male"><label for="child0genderMale">Male</label></span>
<span data-value="female"><input id="child0genderFemale" type="radio" name="child[0][gender]" value="female"><label for="child0genderFemale">Female</label></span>
</fieldset>
</div>
</div>
</div>
</div>
</div>
<div class="area hidden">
<div class="box">
<div class="section">
<div data-type="date" class="widget_type_date">
<div>
<label for="child0dob">Date of Birth</label>
</div>
<div>
<div class="validationMessage">
Enter Date of Birth
</div>
<input id="child0dob" type="date" name="child[0][dob]" required="" title="Enter date of Birth">
</div>
</div>
</div>
</div>
</div>
<div class="area ">
<div class="box">
<div class="section" data-access="agent">
<div data-type="text" class="widget_type_text">
<div>
<label for="child0school">School</label>
</div>
<div>
<div class="validationMessage">
Enter School
</div>
<input id="child0school" type="text" name="child[0][school]" required="" title="Enter school">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
- У владельца может быть несколько дочерних подразделений, у которых есть класс, называемый
child
удобно. - Каждый дочерний div может содержать несколько divs с вызываемым классом
area
. - Каждый div с вызываемым классом
area
может содержать один div с вызываемым классомsection
- Каждый div с вызываемым классом
section
может содержать несколько виджетов ввода формы, которые находятся внутри div с атрибутом типа данных.
видимость div с классом area
section
или data-type
атрибутом можно переключать, включая hidden
класс.
видимость каждого из этих divs также может быть ограничена путем включения data-access
атрибута со значением либо agent, либо guest — это работает путем добавления класса agent или guest в #main
div.
Таким образом, если гостевой пользователь получает доступ к сайту, в div с #main будет введен guest
класс, и если это агент, у него будет agent
класс, а затем следующий CSS используется для переключения видимости каждого div.
#main.guest [data-access="agent"] {
display: none;
}
#main.agent [data-access="guest"] {
display: none;
}
Мне нужно получить метки полей и значения для всех входных данных формы, видимость которых не скрыта ни скрытым классом, ни
атрибутами доступа к данным, а затем повторно отобразить их на другой странице, например. страница сводки.
Итак, в приведенном выше примере, если #main div имеет класс agent, пользователю отображаются только поля gender и school, поэтому функция будет извлекать метку поля и значение этих полей только потому, что виджет полного имени скрыт, а область даты рождения скрыта
Если бы у #main div был класс guest, то отображалось бы только поле gender, потому что виджет full name скрыт, область date of birth скрыта, а раздел школы div имеет доступ к данным только для агента.
Короче говоря, мне нужно проверить три divs, которые имеют либо класс area, section, либо тип данных attr, чтобы увидеть, не скрыты ли они. Я также должен проверить те же divs, чтобы увидеть, содержат ли они атрибут доступа к данным, и убедиться, что видимость не была скрыта этим.
так что на самом деле, если область div имеет либо скрытый класс, либо значение атрибута доступа к данным, которое не соответствует классу, <div id="main" class="agent">
нет необходимости проходить глубже, поскольку поле ввода будет скрыто
аналогично было бы в случае с div с классом раздела и, наконец, с div с типом данных attr.
Как мне выполнить цикл через такую разметку, чтобы извлекать метки полей и значения только тех элементов формы, которые были отображены?
Это то, что у меня есть до сих пор:
if ($("[data-name='holder']").children().length > 0 ) {
$('.child').each(function(index, element) {
//pseudo code
for each div with class area
if div does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
if div with class section does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
for each div with data-type attribute
if div does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
save the field label and field value in array
end if
end for
end if
end if
endfor
});
}
Изо всех сил пытаюсь преобразовать псевдокод в jQuery. любая помощь приветствуется.
*** ОБНОВЛЕНИЕ ***
Держатель div может отображаться на нескольких страницах внутри <div class="page">
div, и по мере прохождения пользователем формы видимость предыдущих страниц скрывается. Таким образом, простое использование псевдокласса jQuery:visible не будет работать, поскольку элементы на предыдущих страницах будут скрыты, но все равно должны быть представлены на странице сводки, поскольку они будут представлены пользователю.
Ответ №1:
Если классы (например: агент, гость) исправлены, и вы знаете, каковы все возможные комбинации, вы можете выполнить выбор следующим образом
var $main = $('#main');
// filter all the class that are not in the main
var aClasses = ['agent', 'guest'].filter(function(cl) {
return !$main.hasClass(cl)
});
// build the selector
var selector = ':not(.hidden)';
aClasses.forEach(function(cl) {
selector = ':not([data-access="' cl '"])'
})
$('div.area' selector).each(function(i, el) {
$('div.section' selector, el).each(function(_i, _el) {
$('div[data-type]' selector, _el).each(function(__i, __el) {
// you are inside the visible 'div[data-type]' here; do your stuff
});
});
});
или сделайте это одним большим махом, например:
$(
'div.area' selector
' div.section' selector
' div[data-type]' selector
).each( function(i, el) {
// your stuff
}
Или, если вы действительно не хотите выполнять выбор на основе основного div, имеющего класс (например: agent, guest) и проверяющего то же самое, вы могли бы попробовать
var $main = $('#main');
// get the main div's class
var sClass = (['agent', 'guest'].filter(function(cl) {
return $main.hasClass(cl)
})[0];
// make the two selector combination
var s1 = ':not(.hidden):not([data-access])';
s2 = '[data-access="' sClass '"]:not(.hidden)';
$('div.area' s1 ',div.area' s2).each(function(i, el) {
$('div.section' s1 ',div.section' s2, el).each(function(_i, _el) {
$('div[data-type]' s1 ',div[data-type]' s2, el).each(function(__i, __el) {
// your stuff
});
});
});
но здесь, чтобы написать все одним махом, вам пришлось бы использовать 8 разных комбинаций
например:
// area-s1 sect-s1 div-s1,
// area-s1 sect-s1 div-s2,
// area-s1 sect-s2 div-s1,
// area-s1 sect-s2 div-s2,
// area-s2 sect-s1 div-s1,
// area-s2 sect-s1 div-s2,
// area-s2 sect-s2 div-s1,
// area-s2 sect-s2 div-s2,
// ie:
$(
'div.area' s1 ' div.section' s1 ' div[data-type]' s1
',div.area' s1 ' div.section' s1 ' div[data-type]' s2
',div.area' s1 ' div.section' s2 ' div[data-type]' s1
',div.area' s1 ' div.section' s2 ' div[data-type]' s2
',div.area' s2 ' div.section' s1 ' div[data-type]' s1
',div.area' s2 ' div.section' s1 ' div[data-type]' s2
',div.area' s2 ' div.section' s2 ' div[data-type]' s1
',div.area' s2 ' div.section' s2 ' div[data-type]' s2
).each(function(i, el) {
// your stuff
})
поэтому было бы лучше использовать сам вложенный цикл.
Пример
// assume the classes are (agent, guest) and main div is having class 'agent' then
/* First approch */
$('div.area:not(.hidden):not([data-access="guest"] div.section:not(.hidden):not([data-access="guest"] div[data-type]:not(.hidden):not([data-access="guest"]').each(function(index, elem) {
//your stuff
})
// using nested loops
$('div.area:not(.hidden):not([data-access="guest"]').each(function(i, el) {
$('div.section:not(.hidden):not([data-access="guest"'], el).each(function(_i, _el) {
$('div[data-type]:not(.hidden):not([data-access="guest"'], _el).each(function(__i, __el) {
// you are inside the visible 'div[data-type]' here; do your stuff
});
});
});
/* Second approch */
$(
'div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type]:not(.hidden):not([data-access]), '
'div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type][data-access="agent"]:not(.hidden), '
...
).each(function(i, el) {
//your stuff
})
// using nested loops
$('div.area:not(.hidden):not([data-access]), div.area[data-access="agent"]:not(.hidden)').each(function(i, el) {
$('div.section:not(.hidden):not([data-access]), div.section[data-access="agent"]:not(.hidden)', el).each(function(_i, _el) {
$('div[data-type]:not(.hidden):not([data-access]), div[data-type][data-access="agent"]:not(.hidden)', _el).each(function(__i, __el) {
// your stuff
});
});
});
Комментарии:
1. у вас есть пример без использования ES6, поскольку мой jquery очень простой.?
2. @adam78 также добавил примеры.
3. означает ли следующее его условие и И
$('div.area:not(.hidden):not([data-access="guest"]
, т.Е. Область не скрыта, А доступ к данным не является гостевым? Как вы делаете это условием ИЛИ, т.Е. Область не скрыта или доступ к данным не является гостевым?4. С помощью запятой. Смотрите второй подход. например:
$('div.area:not(.hidden), div.area:not([data-access="guest"])
5. второй подход работает, но я столкнулся с другой проблемой: что, если у меня есть другие
<div class="area"><div class="section"><div data-type="text"></div></div></div>
вложенные внутри родительского раздела div. Я заметил, что в этом случае второй подход дублирует результаты, т.Е. Повторяет один и тот же div несколько раз?
Ответ №2:
:visible
Псевдокласс jQuery будет фильтровать только [data-type]
элементы, видимые пользователю.
Поэтому его использования в селекторе должно быть достаточно в соответствии с вашим описанием:
<script>
$(function () {
function fetchFormData() {
var result = [];
$('[data-name=holder] [data-type]:visible').each(function (idx, elem) {
var $elem = $(elem);
var type = $elem.data('type');
var label, value;
// specific case: radio input
if (type === 'radio') {
label = $elem.find('legend').text();
value = $elem.find('input[type=radio]:checked').val();
result.push({label: label, value: value});
// done with this item, skip to next one
return true; // continue;
}
// generic case, works with most inputs
label = $elem.find('label').text();
value = $elem.find('input').val();
result.push({label: label, value: value});
});
return resu<
}
// add this to an event handler
console.log(fetchFormData());
});
</script>
Комментарии:
1. это не сработает. Смотрите Мой обновленный пост, так как разделы-владельцы содержатся внутри раздела страниц, видимость которого скрыта как страницы пользователя через форму.