Я делаю этот метод для глубокого присваивания с помощью es6.
function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item) && item !== null)
}
function deepAssign(...objs) {
if (objs.length < 2) {
throw new Error('Need two or more objects to merge')
}
const target = objs[0]
for (let i = 1; i < objs.length; i++) {
const source = objs[i]
Object.keys(source).forEach(prop => {
const value = source[prop]
if (isObject(value)) {
if (target.hasOwnProperty(prop) && isObject(target[prop])) {
target[prop] = deepAssign(target[prop], value)
} else {
target[prop] = value
}
} else if (Array.isArray(value)) {
if (target.hasOwnProperty(prop) && Array.isArray(target[prop])) {
const targetArray = target[prop]
value.forEach((sourceItem, itemIndex) => {
if (itemIndex < targetArray.length) {
const targetItem = targetArray[itemIndex]
if (Object.is(targetItem, sourceItem)) {
return
}
if (isObject(targetItem) && isObject(sourceItem)) {
targetArray[itemIndex] = deepAssign(targetItem, sourceItem)
} else if (Array.isArray(targetItem) && Array.isArray(sourceItem)) {
targetArray[itemIndex] = deepAssign(targetItem, sourceItem)
} else {
targetArray[itemIndex] = sourceItem
}
} else {
targetArray.push(sourceItem)
}
})
} else {
target[prop] = value
}
} else {
target[prop] = value
}
})
}
return target
}
<ul>
, вам нужно будет проверять каждый <li>
на наличие вложенного <ul>
. Если это так, вы снова вызовете функцию, передав ей вложенный <ul>
, а также «префикс» строки.
На основании ваших комментариев параметр по умолчанию (и, вероятно, оператор остальных (...
)) вызовет проблемы с вашим браузером.
Разветвленный JSFiddle: https://jsfiddle.net/h56zeqkg/
Вот версия с некоторым унаследованным, дружественным к IE11 JS:
function stringBuilder(ul, prefix) {
prefix = prefix || '';
var arr = [].slice.call(ul.children);
var stringArr = arr.map(function (li) {
if (li.children.length > 1) {
return stringBuilder(li.querySelector('ul'), prefix + li.querySelector('a').textContent + '/');
} else {
return prefix + li.querySelector('a').textContent;
}
});
return [].concat.apply([], stringArr);
}
stringBuilder(document.querySelector('ul'));
[1113 ] Оригинал: JSFiddle: https://jsfiddle.net/hvojpds6/
Вот фрагмент кода JS:
function stringBuilder(ul, prefix = '') {
return [].concat(...Array.from(ul.children).map(li => {
// recurse
if (li.children.length > 1) {
return stringBuilder(li.querySelector('ul'), prefix + li.querySelector('a').textContent + '/');
} else {
return prefix + li.querySelector('a').textContent;
}
}))
}
stringBuilder(document.querySelector('ul'));
Выходные данные из stringBuilder
будет array
, со следующим:
stringBuilder(document.querySelector('ul'))
(7) ["First", "Second/Second - 1", "Second/Second - 2", "Second/Second - 3/Aaa", "Second/Second - 3/Bbb", "Second/Second - 3/Ccc", "Third"]
0: "First"
1: "Second/Second - 1"
2: "Second/Second - 2"
3: "Second/Second - 3/Aaa"
4: "Second/Second - 3/Bbb"
5: "Second/Second - 3/Ccc"
6: "Third"
length: 7
__proto__: Array(0)
Пройдите через DOM с помощью рекурсивной функции
//Main recursion
function getChildPaths($elements, parentPath) {
//Traverse the children of each level
$elements.children().each(function(){
if ($(this).prop('tagName') === 'LI'){
//Check if this level has children
if ($(this).children('UL').length > 0) {
getChildPaths($(this).children('UL'), `${parentPath}/${$(this).children('A').html()}`)
}
else {
//Show the path if no children
console.log(`${parentPath}/${$(this).children('A').html()}`)
}
}
})
}
getChildPaths($('#1'), '');
.as-console-wrapper {
max-height: 200% !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="1">
<li><a href="#">First</a></li>
<li><a href="#">Second</a>
<ul id="2">
<li><a href="#">Second - 1</a></li>
<li><a href="#">Second - 2</a></li>
<li><a href="#">Second - 3</a>
<ul id="3">
<li><a href="#">Aaa</a></li>
<li><a href="#">Bbb</a></li>
<li><a href="#">Ccc</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Third</a></li>
</ul>
Рекурсивная функция с использованием методов children()
и each()
function getHierarchy($ul, level = '') {
$ul.children('li').each(function(i, li) {
let text = $(li).children('a').text();
let list = $(li).children('ul');
(list.length)
? getHierarchy(list, level + text + '/')
: console.log(level + text)
});
}
getHierarchy($('#1'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="1">
<li><a href="#">First</a></li>
<li><a href="#">Second</a>
<ul id="2">
<li><a href="#">Second - 1</a></li>
<li><a href="#">Second - 2</a></li>
<li><a href="#">Second - 3</a>
<ul id="3">
<li><a href="#">Aaa</a></li>
<li><a href="#">Bbb</a></li>
<li><a href="#">Ccc</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Third</a></li>
</ul>
function recursive_loop(parent, text) {
if (text) {
var c = parent.children;
for (let i = 0; i < c.length; i++) {
var t = c[i].getElementsByTagName('a')[0].textContent;
if (c[i].getElementsByTagName('ul').length) {
return recursive_loop(c[i].getElementsByTagName('ul')[0], text + '/' + t);
}else{
console.log(text + '/' + t);
}
}
}
}
var parent = document.getElementById('1');
var c = parent.children;
for (let i = 0; i < c.length; i++) {
var text = c[i].getElementsByTagName('a')[0].textContent;
if (c[i].getElementsByTagName('ul').length) {
recursive_loop(c[i].getElementsByTagName('ul')[0], text);
}else{
console.log(text);
}
}
recursive_loop(parent);