Automatically Open <Details> Element on Id Call

Automatically open details element on ID call

I don't think you can open <details> with CSS alone. But you can:

  1. Get the hash with location.hash. Possibly listen to hashchange event.
  2. Use document.getElementById to get the element.
  3. Set its open property to true.

function openTarget() {

var hash = location.hash.substring(1);

if(hash) var details = document.getElementById(hash);

if(details && details.tagName.toLowerCase() === 'details') details.open = true;

}

window.addEventListener('hashchange', openTarget);

openTarget();
:target {

background: rgba(255, 255, 200, .7);

}
<details id="foo">Details <summary>Summary</summary></details>

<div><a href="#foo">#foo</a> <a href="#bar">#bar</a></div>

How to open details from link in another page

You cannot modify another page that is not active using Javascript. Javascript only runs on the active page and can modify the DOM of the active page. You will have to send the value to the next page.

HTML5 Session Storage to send data:

    home.html
<script type="text/javascript">
window.onload = function() {
var a = document.getElementById("mylink");
a.onclick = function() {
localStorage.setItem("open", "true");
}
}
</script>

second_page.html
<script>
var val = localStorage.getItem("open");
if (val == "true") {
var b = document.getElementById("mydetails");
b.open = true;
b.style.color = "red";
localStorage.removeItem("open");
}
</script>

Expand details element when URL is called with specific hashes

It's a question of relaxing your check of the hash to allow more than just exactly "comments", but also "comment-111". I have assumed, as your HTML suggests, that your IDs are numeric.

//grab hash and its parts
let hash = location.hash.match(/^#(comment(s|-(\d+)))$/);
if (hash) {

//resolve to element
let el = document.getElementById(hash[1]);
if (el) {

//open comments - not sure what your .open property does
el.closest('#comments').open = true;

//if is hash to specific comment, go to it
if (hash[3]) location.href = '#'+hash[3];
}
}

How to expand details/summary when opening page with anchor inside nested details ?

Sample Image

also: gist, codepen

function MakeArrayOfAllPrefixes(str){

//console.log("MakeArrayOfAllPrefixes("+str+")");

var prefixes = [];

for (var i=1; i<=str.length; i++){

prefixes.push(str.substr(0,i));

}

console.log("MakeArrayOfAllPrefixes("+str+") -> returns [" + prefixes + "]");

return prefixes;

}

function SetOpenAttrForIdsAndPrefixes(ids, openAttrBool){

$('details').attr('open',false); // close all others first

console.log("SetOpenAttrForIds([" +ids+"], "+openAttrBool+")");

for (idindex in ids) {

var id = ids[idindex];

if (id != ""){

var prefixes = MakeArrayOfAllPrefixes(id);

for (prefixidx in prefixes) {

var prefix = prefixes[prefixidx];

if(openAttrBool==true) { operationstr="Opening"; } else { operationstr="Closing"};

console.log(operationstr+" <details id='#"+prefix+"'> with $('#"+prefix+").attr('open',"+openAttrBool+");");

$('#'+prefix).attr('open',openAttrBool);

}

}

}

}

function SetOpenAttrForIdsAndPrefixesFromLocationHash(){

var hashes = $(location).attr('hash').split('#');

SetOpenAttrForIdsAndPrefixes(hashes, true);

}

$(document).ready(function(){

SetOpenAttrForIdsAndPrefixesFromLocationHash();

if ("onhashchange" in window) {// does the browser support the hashchange event?

window.onhashchange = function () {

SetOpenAttrForIdsAndPrefixesFromLocationHash();

}

}

});
  

<p>

Opens details/summeries, all parths, using prefixes. Supports multiple anchors in url, example:

</p>

<ul>

<li><a href="#Q0A0#Q1A">#Q0A0#Q1A</a>,</li>

<li><a href="#Q0B#Q0C#Q1B#Q1C">#Q0B#Q0C#Q1A#Q1C</a>.</li>

</ul>

<p>

references:

<a href="https://webdesign.tutsplus.com/tutorials/explaining-the-details-and-summary-elements--cms-21999">1</a>,

<a href="https://stackoverflow.com/a/48258026/544721">2</a>,

<a href="https://stackoverflow.com/q/55308339/544721">3</a>,

<a href="https://stackoverflow.com/q/3552944/544721">4</a>,

<a href="https://stackoverflow.com/q/2161906/544721">5</a>.

</p>



<ul>

<li><details id="Q0"><summary>Q0</summary>

<ul>

<li><details id="Q0A"><summary>Q0A</summary>

<ul>

<li><details id="Q0A0"><summary>Q0A0</summary><a href="#Q0A0">Answer to Q0A0</a></details></li>

<li><details id="Q0A1"><summary>Q0A1</summary><a href="#Q0A1">Answer to Q0A1</a></details></li>

<li><details id="Q0A2"><summary>Q0A2</summary><a href="#Q0A2">Answer to Q0A2</a></details></li>

</ul>

</details>

</li>

<li><details id="Q0B"><summary>Q0B</summary><a href="#Q0B">Answer to Q0B</a></details></li>

<li><details id="Q0C"><summary>Q0C</summary><a href="#Q0C">Answer to Q0C</a></details></li>

</ul>

</details>

</li>

<li><details id="Q1"><summary>Q1</summary>

<ul>

<li><details id="Q1A"><summary>Q1A</summary><a href="#Q1A">Answer to Q1A</a></details></li>

<li><details id="Q1B"><summary>Q1B</summary><a href="#Q1B">Answer to Q1B</a></details></li>

<li><details id="Q1C"><summary>Q1C</summary><a href="#Q1C">Answer to Q1C</a></details></li>

</ul>

</details>

</li>

</ul>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Hiding child elements inside an open details element

1. Is it "okay" / correct to hide child elements of an open details element

  • Yes, there's nothing wrong with hiding an element inside a details element.
  • Actually, you may programmatically toggle the display of those hidden elements just like any other element in the page.

2. Should details only have 1 child element, besides the summary element?

  • No, you are not limited to have only one element inside a details.
  • Also, details tags do not require summary elements to be rendered correctly. Although it is recommended to have a summary element in order to have your own label for the details element, you can ditch that summary element entirely and the browser will show its own placeholder/label (Chrome show the text "Details" if a details tag doesn't contain a summary).
  • In short, you can have as many elements inside a details but a maximum of 1 summary element.

With that being said, let's have a simple demo that illustrates the use of details that, on its own, has a bunch of different elements. You can use the button to toggle the div that is initially hidden:

const myDIV = document.getElementById('my-div'),
toggler = document.getElementById('toggler');

toggler.addEventListener('click', () => myDIV.classList.toggle('hidden'));
.hidden {
display: none;
}

/** just to make the demo visually appealing */

details {
border: 1px solid #aaa;
border-radius: 4px;
margin-top: 10px;
padding: .5em .5em 0;
}

summary {
font-weight: bold;
margin: -.5em -.5em 0;
padding: .5em;
cursor: pointer;
}

details[open] {
padding: .5em;
}

details[open] summary {
border-bottom: 1px solid #aaa;
margin-bottom: .5em;
}
<button id="toggler">Toggle Initially Hidden DIV</button>
<details open>
<summary>Some summary</summary>
<div>This content is display</div>
<div id="my-div" class="hidden">This content is NOT displayed and its display can be toggled</div>
<p>I have an image too!<img src="https://via.placeholder.com/150" style="display:block;margin: 10px auto 0" width="150"></p>
</details>

Is it possible to automatically declare thousands of variables in JavaScript?

This question is more of an architectural issue than a need for creating dynamic variables. Consider this example:

  • ids are removed (existing class names used)
  • This pattern scales for n sentence instances
  • In handleClick, we toggle the open class on the clicked element, which lets us leverage the adjacent sibling selector via CSS
  • No need for a close class, since the absence of the open class represents the closed state.

let outerUL = document.querySelectorAll('.sentcontent')

function handleClick() {

this.classList.toggle('open');

}

outerUL.forEach(ul => {

ul.addEventListener('click', handleClick);

})
.sentcontent {

cursor: pointer;

}

.sentcontent.open + .infobox {

display: block;

}

.infobox {

background-color: #eee;

display: none;

padding: .25em .5em;

}
<ul class='sentcontent'>

<li class='number'>1.</li>

<li class='thesent'>Sent</li>

</ul>

<div class='infobox'>

<ul class='sentinfo'>

<li class='information'>Info</li>

<li class='infotext'><em>Info text</em></li>

</ul>

<ul class='sentinfo'>

<li class='information'>Line info</li>

<li class='line'>Line</li>

</ul>

</div>

<ul class='sentcontent'>

<li class='number'>2.</li>

<li class='thesent'>Sent</li>

</ul>

<div class='infobox'>

<ul class='sentinfo'>

<li class='information'>Info</li>

<li class='infotext'><em>Info text</em></li>

</ul>

<ul class='sentinfo'>

<li class='information'>Line info</li>

<li class='line'>Line</li>

</ul>

</div>

Detecting the opening or closing of a details element

You can use the toggle event:

var details = document.querySelector("details")

details.addEventListener("toggle", function() {

details.firstChild.textContent = "done"

})
<!doctype html>

<details>

<summary>toggle event</summary>

</details>


Related Topics



Leave a reply



Submit