Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Генератор оглавления страницы (https://javascript.ru/forum/misc/50495-generator-oglavleniya-stranicy.html)

Roman Koff 28.09.2014 21:13

Генератор оглавления страницы
 
Полезный функционал, не знаю как оптимально решить.

Есть div в котором находится некий контент страницы состоящий из h1..h2, p, ul, ol, li, a, img, table и т.д. То есть обычная веб-страница. Нужно разобрать все заголовки в диве и сформировать оглавление (как, например, делает word для многостраничного документа). Соответственно заголовкам присваиваются якоря (по порядковому номеру в иерархии) и генерируется дополнительный слой содержащий оглавление в виде дерева с ссылками на соответствующие заголовки.

Таким образом можно создавать автоматическое оглавление страницы, по примеру как сделано, например на бутстрапе.

Возможно есть уже готовые скрипты, но я что-то не нашел. Не понимаю как сформировать запрос.

ksa 28.09.2014 22:00

Цитата:

Сообщение от Roman Koff
Не понимаю как сформировать запрос

Как вариант, просто селектором
$('h1, h2, h3, h4')

Пройтись по элементам и меню готово...

Roman Koff 29.09.2014 10:09

Я имею ввиду, не знаю как правильно спросить у гугля. На запрос "генератор оглавления страницы на javascript" выходит всякая туфта и т.д.

Нужно не только просканировать заголовки, но и дописать для них анкоры (согласно дерева)

ksa 29.09.2014 14:28

Цитата:

Сообщение от Roman Koff
не знаю как правильно спросить у гугля

Т.е. сам-то ничего делать и не собираешся? :D

Цитата:

Сообщение от Roman Koff
Нужно не только просканировать заголовки, но и дописать для них анкоры

В том же проходе все и сделай...

Roman Koff 29.09.2014 14:46

Цитата:

Сообщение от ksa (Сообщение 332655)
Т.е. сам-то ничего делать и не собираешся?

Не собирался бы -- не спрашивал бы. Фрилансеров полно... Хочу сам разобраться и потом допиливать до нужного функционала. Я не дружу с JS, а хотелось бы...

ksa 29.09.2014 16:05

Цитата:

Сообщение от Roman Koff
Хочу сам разобраться

Где тогда твои варианты решения? Где тестовый пример?

Roman Koff 30.09.2014 16:17

На странице присутствуют два дива, один с html-контентом, второй – в который будет сливаться оглавление.

Скрипту скармливаются id обоих.

Скрипт проходит подряд все заголовки до третьего уровня, добавляет перед ними якорь с идентификатором по порядку следования и, по сути, дублирует во второй див копию заголовков контента помещенных в ссылки, указывающие на соответствующие якоря.

Как присвоить якоря ссылкам, я, в принципе, придумал. Не знаю, как собрать сведения о заголовках и как их потом передать во второй див.

!function ($) {
	$(function () {
		var c = 1;
		$('h1, h2, h3').each(function () {
			var h = $(this)
			h.before("<a id='" + c + "'></a>");
			c++;
		});
	});
}(window.jQuery);

Erolast 30.09.2014 17:20

$(function () {
  var index = 1;
  $('h1, h2, h3').each(function () {
    $(this).before("<a id='" + index + "'></a>");
    $(this).clone().appendTo("#second_div");
    index++;
  });
 });

Так, чтоли, нужно?

Roman Koff 30.09.2014 20:08

Это очень близко, спасибо. У меня получилось вот так. Теперь буду допиливать:
var line, header, title, tag, link = 0;
var pageContent = '<ul>';
$("h2, h3").each(function () {
	header = $(this);
	link++;
	header.before("<a id='par" + link + "'></a>");
	title = header.text();
	line = "<li><a href='#par" + link + "'>" + title + "</a></li>";
	pageContent += line;
});
pageContent += '</ul>';
$(".pageContent").prepend(pageContent);


Вопрос в том, как правильно скормить тег источник и как сделать функцию библиотечной, чтобы вызывать только там где нужно.

Erolast 30.09.2014 20:39

Можно так еще:
var list = $("<ul>"); //создание элемента ul.
...
    list.append($("<li>").append($("<a>").attr("href", link).html(title)));
...
$(".pageContent").append(list);

Цитата:

и как сделать функцию библиотечной, чтобы вызывать только там где нужно.
function myfunc(argument, second_argument) {
  alert(argument);
  alert(second_argument);
};

myfunc(1, 2); //Вызов функции. Может быть где угодно.

ksa 30.09.2014 21:04

Цитата:

Сообщение от Erolast
Можно так еще

Я бы сказал, что лучше так. :yes: Поскольку оглавление больше вложеные списки, нежели заголовки...

Roman Koff 30.09.2014 21:09

Ага, а как вложенность тогда реализовать? Мне кажется проще сгенерить список заголовков и применить стили к их контейнеру, с отступами, уменьшенным размером и другими блекджеками...

А как можно изящно выбрать теги вложенные в тег? У меня сейчас выглядит так:
$('.page-content-body h2,.page-content-body h3').each(function (i) {
	var c = $(this);
});


А можно какнить сократить запись? (и есть ли возможность перебрать таким образом несколько родительских тегов).

То есть если говорить императивным языком -- можно сделать два вложенных перебора для элементов .page-content-body и для заголовком внутри них?

ksa 30.09.2014 21:11

Цитата:

Сообщение от Roman Koff
а как вложенность тогда реализовать?

Так она понятна по названиям тегов...
Х1 - первый уровень
Х2- второй
и т.д.
Если они в твоем диве стоят как нужно, т.е. идут в правильной последовательности - нужно будет просто добавлять в конец нужного списка...

ksa 30.09.2014 21:12

Цитата:

Сообщение от Roman Koff
Мне кажется проще сгенерить список заголовков

Тебе может оно и проще... Но зачем двойной комплект заголовков на странице? :blink:

Roman Koff 30.09.2014 21:26

Про двойной комплект -- логично, но страницы формируют обычные юзверги, а они не всегда корректны "во вложениях".

ksa 30.09.2014 21:30

Roman Koff, как делать в итоге решать тебе... :)

Цитата:

Сообщение от Roman Koff
страницы формируют обычные юзверги, а они не всегда корректны "во вложениях"

Некорректные заголовки все равно покажутся некорректно... Как их не формируй. Линейно... Или вложено... Пофиг.

Roman Koff 30.09.2014 21:53

Генератор получился такой, но не ясно, как выбрать заголовки только у текущего элемента 'make-toc'. Кроме того, список, конечно, кошернее будет. Но не придумаю как вложенность правильно отработать.

$('.make-toc').each(function (cInd) {
	var source = $(this);
	var toc = document.createElement('div');
	var s = '';
	toc.className = 'toc';
	$('h2, h3').each(function (hInd) {
		var h = $(this);
		var headerId = 'header' + cInd + '_' + hInd;
		var tag = h.get(0).tagName.toLowerCase();
		h.before("<a id='" + headerId + "'></a>");
		s += "<" + tag + "><a href='#" + headerId + "'>"
			+ h.text() + "</a></" + tag + ">";
	});
	toc.innerHTML = s;
	source.before(toc);
});

ksa 30.09.2014 23:07

Цитата:

Сообщение от Roman Koff
не ясно, как выбрать заголовки только у текущего элемента 'make-toc'

С помощью того же
http://jquery-docs.ru/traversing/find/

ksa 30.09.2014 23:09

Цитата:

Сообщение от Roman Koff
не придумаю как вложенность правильно отработать

Это будет хорошей тренировкой на создание алгоритма, реализующего такую задачу. ;)

ksa 01.10.2014 23:05

Цитата:

Сообщение от Roman Koff
Ошибка: свойство find не поддерживается

Ты ссылку смотрел? Все понял?
Там ведь даже примеры есть...

Roman Koff 02.10.2014 10:05

Все нормально, я сообщение сразу удалил. Просто до этого не с тем объектом экспериментировал, поэтому и не срабатывало.

Roman Koff 09.10.2014 17:21

В итоге получилось это:
!function ($) {
	$(function () {
		$('.make-toc').each(function (cInd) {
			var source = $(this);
			var toc = document.createElement('div');
			toc.className = 'toc';
			var s = '';
			source.find('h2, h3').each(function (hInd) {
				var h = $(this);
				var id = 'header' + cInd + '_' + hInd;
				var tag = h.get(0).tagName.toLowerCase();
				h.before("<a id='" + id + "'></a>");
				s += "<" + tag + "><a href='#" + id + "'>" + h.text() + "</a></" + tag + ">";
			});
			toc.innerHTML = s;
			source.before(toc);
		});
	});
}(window.jQuery);

но нужно оптимизировать...

kostyanet 09.10.2014 19:41

Господин danik.js не хочет рассказывать, может быть тут кто-то расскажет откуда берется контент который надо реструктуризовать ява-скриптом.

У меня такая метафора что как будто из мозга жанны агузаровой веб-дизайнеру навалилась куча несусветного барахла в хтмле и приходится теперь долго и нудно разбираться с ним, витиевато селектить, добавлять структуры, обогащать индексами и так далее.

Я сталкивался с такими задачаи только в GM. Это что, все себе пишут в GM, или откуда такие задачи берутся?

Roman Koff 13.10.2014 06:59

??????


Часовой пояс GMT +3, время: 00:07.