wpbakery visual tutorial instalar gratis full elementor descargar consultas composer como javascript

visual - ¿Hay una solución de JavaScript para generar una "tabla de contenidos" para una página?



visual composer vs wpbakery (11)

¿Está buscando una solución preempaquetada o pregunta cómo se puede implementar?

Para este último, podrías usar getElementsByTagName() recursivamente en <h1> a <h6> XPath para iterar a través de todos los elementos <h*> y construir las listas anidadas <ul> o <ol> . También debería agregar las etiquetas <a> a los encabezados.

Tengo encabezados en las etiquetas <h1> a <h6> . ¿Hay alguna forma de que pueda usar JavaScript para generar una tabla de contenidos para los contenidos que también sirven como etiquetas de anclaje?

Me gustaría que la salida sea algo así como:

<ol> <li>Header 1</li> <li>Header 1</li> <li>Header 2</li> <li>Header 3</li> </ol>

Actualmente no estoy usando un marco de JavaScript, pero no veo por qué no podría usar uno.

También estoy buscando algo hecho, ya que supongo que este es un problema común, pero si no, un punto de partida para lanzar el mío sería bueno.




después de la carga de la página, recorre el DOM y busca los elementos que te interesan. construya una lista agradable de anclajes y agréguelos al documento en el lugar que desee.


No pude resistirme a armar una implementación rápida.

Agregue la siguiente secuencia de comandos en cualquier lugar de su página:

window.onload = function () { var toc = ""; var level = 0; document.getElementById("contents").innerHTML = document.getElementById("contents").innerHTML.replace( /<h([/d])>([^<]+)<//h([/d])>/gi, function (str, openLevel, titleText, closeLevel) { if (openLevel != closeLevel) { return str; } if (openLevel > level) { toc += (new Array(openLevel - level + 1)).join("<ul>"); } else if (openLevel < level) { toc += (new Array(level - openLevel + 1)).join("</ul>"); } level = parseInt(openLevel); var anchor = titleText.replace(/ /g, "_"); toc += "<li><a href=/"#" + anchor + "/">" + titleText + "</a></li>"; return "<h" + openLevel + "><a name=/"" + anchor + "/">" + titleText + "</a></h" + closeLevel + ">"; } ); if (level) { toc += (new Array(level + 1)).join("</ul>"); } document.getElementById("toc").innerHTML += toc; };

Tu página debe estructurarse de la siguiente manera:

<body> <div id="toc"> <h3>Table of Contents</h3> </div> <hr/> <div id="contents"> <h1>Fruits</h1> <h2>Red Fruits</h2> <h3>Apple</h3> <h3>Raspberry</h3> <h2>Orange Fruits</h2> <h3>Orange</h3> <h3>Tangerine</h3> <h1>Vegetables</h1> <h2>Vegetables Which Are Actually Fruits</h2> <h3>Tomato</h3> <h3>Eggplant</h3> </div> </body>

Puede verlo en acción en http://magnetiq.com/exports/toc.htm (Funciona en IE, FF, Safari, Opera)


Puede crear una tabla de contenido dinámica para cualquier documento HTML que use JavaScript, que pueda mostrar la lista de los títulos de h1 a h6 con enlaces a los títulos y facilitar la navegación por el documento siguiendo los pasos a continuación.

Primero crea la función window.onload que se ejecuta automáticamente cuando el documento termina de cargarse como se indica a continuación

window.onload=function(){ function getSelectedText(){ if (window.getSelection) return window.getSelection().toString()+" "+document.URL; else if (document.selection) return document.selection.createRange().text+" "+document.URL; } var toc=document.getElementById("TOC"); if(!toc) { toc=document.createElement("div"); toc.id="TOC"; document.body.insertBefore(toc, document.body.firstChild); }

Agregue los siguientes códigos a la función para buscar todas las etiquetas y las establece como encabezados.

var headings; if (document.querySelectorAll) headings=document.querySelectorAll("h1, h2, h3, h4, h5, h6"); else headings=findHeadings(document.body, []);

Use el siguiente código CSS para diseñar la Tabla de contenido

#TOC {border:solid black 1px; margin:10px; padding:10px;} .TOCEntry{font-family:sans-serief;} .TOCEntry a{text-decoration:none;} .TOCLevel1{font-size:17pt; font-weight:bold;} .TOCLevel2{font-size:16pt; font-weight:bold;} .TOCLevel3{font-size:15pt; font-weight:bold;} .TOCLevel4{font-size:14pt; margin-left:.25in;} .TOCSectNum{display:none;}

Aquí hay un código JavaScript completo para crear una tabla de contenido dentro de la etiqueta de script.

window.onload=function(){ function getSelectedText(){ if (window.getSelection) return window.getSelection().toString()+"<br/>"+document.URL; else if (document.selection) return document.selection.createRange().text+"<br/>"+document.URL; } var toc=document.getElementById("TOC"); if(!toc) { toc=document.createElement("div"); toc.id="TOC"; document.body.insertBefore(toc, document.body.firstChild); } var headings; if (document.querySelectorAll) headings=document.querySelectorAll("h1, h2, h3, h4, h5, h6"); else headings=findHeadings(document.body, []); function findHeadings(root, sects){ for(var c=root.firstChild; c!=null; c=c.nextSibling){ if (c.nodeType!==1) continue; if (c.tagName.length==2 && c.tagName.charAt(0)=="H") sects.push(c); else findHeadings(c, sects); } return sects; } var sectionNumbers=[0,0,0,0,0,0]; for(var h=0; h<headings.length; h++) { var heading=headings[h]; if(heading.parentNode==toc) continue; var level=parseInt(heading.tagName.charAt(1)); if (isNaN(level)||level<1||level>6) continue; sectionNumbers[level-1]++; for(var i=level; i<6; i++) sectionNumbers[i]=0; var sectionNumber=sectionNumbers.slice(0, level).join("."); var span=document.createElement("span"); span.className="TOCSectNum"; span.innerHTML=sectionNumber; heading.insertBefore(span, heading.firstChild); heading.id="TOC"+sectionNumber; var anchor=document.createElement("a"); heading.parentNode.insertBefore(anchor, heading); anchor.appendChild(heading); var link=document.createElement("a"); link.href="#TOC"+sectionNumber; link.innerHTML=heading.innerHTML; var entry=document.createElement("div"); entry.className="TOCEntry TOCLevel" + level; entry.appendChild(link); toc.appendChild(entry); } };

Fuente: Cómo crear una tabla de contenido usando JavaScript

Modifiqué la función en la respuesta aceptada de AtesGoral para generar listas anidadas correctamente y HTML5 válido.

Simplemente agregue el código a continuación a sus scripts y llame a TableOfContents(container, output); en carga, donde container es la clase o id de su elemento de contenido y el resultado es la clase o id del elemento TOC. Los valores predeterminados son ''#contents'' y ''#toc'', respectivamente.

Ver http://codepen.io/aufmkolk/pen/RWKLzr para una demostración funcional.

function TableOfContents(container, output) { var toc = ""; var level = 0; var container = document.querySelector(container) || document.querySelector(''#contents''); var output = output || ''#toc''; container.innerHTML = container.innerHTML.replace( /<h([/d])>([^<]+)<//h([/d])>/gi, function (str, openLevel, titleText, closeLevel) { if (openLevel != closeLevel) { return str; } if (openLevel > level) { toc += (new Array(openLevel - level + 1)).join(''<ul>''); } else if (openLevel < level) { toc += (new Array(level - openLevel + 1)).join(''</li></ul>''); } else { toc += (new Array(level+ 1)).join(''</li>''); } level = parseInt(openLevel); var anchor = titleText.replace(/ /g, "_"); toc += ''<li><a href="#'' + anchor + ''">'' + titleText + ''</a>''; return ''<h'' + openLevel + ''><a href="#'' + anchor + ''" id="'' + anchor + ''">'' + titleText + ''</a></h'' + closeLevel + ''>''; } ); if (level) { toc += (new Array(level + 1)).join(''</ul>''); } document.querySelector(output).innerHTML += toc; };


this.insert = (el, h) => { let li = document.createElement(''li''); li.innerText = h.innerText; li.setAttribute(''tagName'', h.tagName); if(el.tagName == ''OL'') { el.appendChild(li); return li; } else if(el.getAttribute(''tagName'') < h.tagName) { let ol = el.children.length > 0 ? ol = el.querySelector(''ol'') : document.createElement(''ol''); ol.appendChild(li); el.appendChild(ol); return li; } else if(!el.parentNode.parentNode) { el.parentNode.appendChild(li); return li; } else { return this.insert(el.parentNode.parentNode, h); } } this.parse = (headers) => { let list = document.createElement(''ol''); let el = list; for(i=0; i<headers.length; i++) { el = this.insert(el, headers[i]); } return list; } let headers = document.querySelectorAll(''h1,h2,h3,h4,h5,h6''); let toc = this.parse(headers); console.log(toc);


let headers = document.querySelectorAll(''h1,h2,h3,h4,h5,h6''); let list = document.createElement(''ol''); let _el = list; for(i=0; i<headers.length; i++) { while(_el) { let li = document.createElement(''li''); li.innerText = headers[i].innerText; li.setAttribute(''tagName'', headers[i].tagName); if(_el.getAttribute(''tagName'') < headers[i].tagName) { let ol = _el.children.length > 0 ? ol = _el.querySelector(''ol'') : document.createElement(''ol''); ol.appendChild(li); _el.appendChild(ol); _el = li; break; } else { if(_el.tagName == ''OL'') { _el.appendChild(li); _el = li; break; } else if (!_el.parentNode.parentNode) { _el.parentNode.appendChild(li); _el = li; break; } else { _el = _el.parentNode.parentNode; } } } } console.log(list);


Aquí hay un gran script para hacer esto:

https://github.com/matthewkastor/html-table-of-contents/wiki

Para usarlo:

  1. Agregue esta etiqueta:

    <script src="./node_modules/html-table-of-contents/src/html-table-of-contents.js" type="text/javascript">

  2. Llame a la función, como en el atributo de carga de su cuerpo:

    <body onload="htmlTableOfContents();">

Aquí está la definición del método que hace la generación:

/** * Generates a table of contents for your document based on the headings * present. Anchors are injected into the document and the * entries in the table of contents are linked to them. The table of * contents will be generated inside of the first element with the id `toc`. * @param {HTMLDOMDocument} documentRef Optional A reference to the document * object. Defaults to `document`. * @author Matthew Christopher Kastor-Inare III * @version 20130726 * @example * // call this after the page has loaded * htmlTableOfContents(); */ function htmlTableOfContents (documentRef) { var documentRef = documentRef || document; var toc = documentRef.getElementById(''toc''); var headings = [].slice.call(documentRef.body.querySelectorAll(''h1, h2, h3, h4, h5, h6'')); headings.forEach(function (heading, index) { var anchor = documentRef.createElement(''a''); anchor.setAttribute(''name'', ''toc'' + index); anchor.setAttribute(''id'', ''toc'' + index); var link = documentRef.createElement(''a''); link.setAttribute(''href'', ''#toc'' + index); link.textContent = heading.textContent; var div = documentRef.createElement(''div''); div.setAttribute(''class'', heading.tagName.toLowerCase()); div.appendChild(link); toc.appendChild(div); heading.parentNode.insertBefore(anchor, heading); }); } try { module.exports = htmlTableOfContents; } catch (e) { // module.exports is not defined }


Realmente me encanta la respuesta de Sridhar-Sarnobat , pero me gustaría mejorarla ligeramente para usar las notaciones html5 y mantener el ID existente de un encabezado:

document.addEventListener(''DOMContentLoaded'', function() { htmlTableOfContents(); } ); function htmlTableOfContents( documentRef ) { var documentRef = documentRef || document; var toc = documentRef.getElementById("toc"); // Use headings inside <article> only: // var headings = [].slice.call(documentRef.body.querySelectorAll(''article h1, article h2, article h3, article h4, article h5, article h6'')); var headings = [].slice.call(documentRef.body.querySelectorAll(''h1, h2, h3, h4, h5, h6'')); headings.forEach(function (heading, index) { var ref = "toc" + index; if ( heading.hasAttribute( "id" ) ) ref = heading.getAttribute( "id" ); else heading.setAttribute( "id", ref ); var link = documentRef.createElement( "a" ); link.setAttribute( "href", "#"+ ref ); link.textContent = heading.textContent; var div = documentRef.createElement( "div" ); div.setAttribute( "class", heading.tagName.toLowerCase() ); div.appendChild( link ); toc.appendChild( div ); }); } try { module.exports = htmlTableOfContents; } catch (e) { // module.exports is not defined }

Lo usa incluyendo la secuencia de comandos en su encabezado.

Lo asombroso es que puedes usar hojas de estilo para tu tabla de contenido:

<style> #toc div.h1 { margin-left: 0 } #toc div.h2 { margin-left: 1em } #toc div.h3 { margin-left: 2em } #toc div.h4 { margin-left: 3em } </style>

En mi script personal, utilizo un selector ligeramente diferente:

var headings = [].slice.call(documentRef.body.querySelectorAll("article h1, article h2, article h3, article h4, article h5, h6"));

La página principal se mantiene dentro de <article></article> y el script buscará los encabezados dentro del artículo principal solamente. Puedo usar un encabezado dentro de la tabla de contenido, como <nav id="toc"><h3>Table of contents</h3></nav> o en un pie de página / encabezado sin que aparezca dentro del toc.