Does window.find() work across <p> elements or line breaks? - javascript

I'm trying to use window.find() in JavaScript to find and select text across elements. Overall it works as expected, except across <p> elements (or line breaks?).
Here's my simplified HTML:
findText("first with style"); // true
findText("second"); // true
findText("third"); // true
findText("second\nthird"); // false
findText("second\n\nthird"); // false
findText("second\rthird"); // false
findText("second\r\nthird"); // false
findText("second<br>third"); // false
findText("second</p><p>third"); // false
findText("second
third"); // false
function findText(needle) {
console.log(window.find(needle));
}
.as-console-wrapper{ max-height:75px !important; }
<p>first<b> with style</b></p>
<p>second</p>
<p>third</p>
Here's a JS fiddle.
What am I missing?

I don't think any browser allows doing multiline search with their native search feature, so it's normal the DOM API doesn't either, since it's supposed to more or less mirror that feature.
If all you want to do is to check if the given text is present in the current visible text, you can get the document's innerText which will return only the visible text (here "visible" means the ones that are rendered, not necessarily the ones that are in screen).
const text = document.documentElement.innerText;
const toFind = "orci.\n\nPhasellus"; // end of first paragraph + start of second.
console.log(text.includes(toFind));
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed malesuada, massa nec elementum imperdiet, enim arcu fringilla purus, ac bibendum massa augue nec odio. Donec vel hendrerit ligula. Maecenas ante dolor, faucibus tristique commodo non, sollicitudin
at augue. In lobortis quis est a mattis. Aenean blandit lorem at porta ultrices. Nullam sit amet mauris a justo congue iaculis. Duis urna velit, luctus vel tempus quis, consequat id ex. Etiam accumsan urna ac imperdiet gravida. Etiam gravida rhoncus
quam sit amet placerat. In tincidunt lorem non lacus semper hendrerit. Phasellus nec ultrices orci.
</p>
<p>
Phasellus sit amet porttitor leo. Phasellus ut eleifend nulla. Morbi luctus odio quis risus aliquam fermentum. Aenean ultrices tortor leo, eu fermentum tortor tincidunt in. Maecenas sodales nisl erat, nec porta tortor mollis non. Donec vulputate non quam
imperdiet ornare. Integer ex mauris, hendrerit in est sed, sagittis lacinia nulla. Curabitur efficitur dui et neque condimentum, eu lacinia nisi rutrum.
</p>
<p>
Ut vel lorem id justo sodales venenatis. Vestibulum nec mattis risus. Ut a imperdiet lacus, eget molestie dolor. Sed nisl diam, facilisis a nunc non, faucibus suscipit diam. Quisque aliquet, eros sed sodales cursus, ex metus vulputate ante, sagittis dapibus
leo diam sed ligula. Fusce felis nulla, euismod in facilisis vel, viverra sed eros. Praesent ut diam quis nunc ultrices dignissim et vitae ligula. Donec quam orci, consequat eget leo sit amet, fringilla tempus leo. Nullam felis enim, sodales non lectus
ut, pretium tincidunt felis. Sed eget odio sit amet nunc consequat vulputate. Vivamus nisl nisl, condimentum vitae malesuada non, tempus ac metus. Nulla placerat arcu eu risus feugiat, efficitur semper diam fringilla. Curabitur et blandit felis. Curabitur
vel eleifend mi.
</p>
<p>
Maecenas tincidunt mi vestibulum nisi aliquet, at rhoncus mi tristique. Nullam sagittis sed dolor ut aliquet. Sed neque nunc, pulvinar vel ornare id, convallis ut nulla. Integer rhoncus velit non pulvinar commodo. Praesent finibus libero ante, eget venenatis
augue dignissim id. Nam id odio id ante maximus blandit vel nec purus. Sed eleifend leo ut commodo maximus. Nam pretium a mauris a scelerisque.
</p>
<p>
Duis laoreet lorem a nibh dapibus sodales. Curabitur ac orci scelerisque lorem maximus blandit nec ut leo. Nulla feugiat maximus congue. Proin velit leo, suscipit et mollis eu, tempor non eros. Morbi nec mi non lectus auctor fermentum vitae at lectus.
Sed ut massa sapien. Vivamus eu ipsum quis ante mollis volutpat at ac ipsum. Vivamus ut est sem. Quisque eget nulla posuere sapien rutrum ullamcorper. Donec porta nisl quis quam dignissim elementum sit amet ut turpis. Suspendisse ullamcorper non sapien
vitae faucibus. Praesent mollis bibendum pretium. Donec auctor lectus nec urna tincidunt egestas vitae vel quam. Sed a neque eleifend, elementum metus quis, sagittis diam. Pellentesque id purus sed nulla euismod tincidunt.
</p>
</div>
If you also need to select the text, you might be able to do so with the Selection API and walking over every node to find where the match was, but that will be quite tedious to build that, so I leave it as an exercise for now.

Maximum you can do is to query for elements and select in between:
findText("first with style"); // true
findText("second"); // true
findText("third"); // true
findMultiple("body p:nth-child(2)","body p:nth-child(4)"); // true
function findText(needle){
console.log(window.find(needle));
}
function findMultiple(start,end){
var range = document.createRange();
var root_node = document.body;
range.setStart(root_node.querySelector(start).firstChild, 0);
range.setEnd(root_node.querySelector(end).firstChild, root_node.querySelector(end).innerText.length);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
<p>first<b> with style</b></p>
<p>second</p>
<p>middle</p>
<p>third</p>
You could also querySelect all elements and check if contains your text, store that element then run the function. But that can be slower, depends.

Please refer this solution - JavaScript window.find doesn't work absolutely
Below solution will give us the boolean value based on the matches of string irrespective of the lines.
I hope you're looking for the below one.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<p>first<b> with style</b></p>
<p>second</p>
<p>third</p>
<p id="demo"></p>
<script>
let name = window.name;
document.getElementById("demo").innerHTML = "Result of matching: "+ containsStr$("second third");
function containsStr$(str) {
return $('body:contains("'+str+'")').length > 0;
}
</script>
</body>

Related

Catch event when users scrolls up to a certain element

<p onscroll="function(){alert('scroll');}"></p>
I want to catch an event when I scroll to a certain element.
I'me code in the middle of a page. When I scroll to it, alert doesn't appear. By the way, in console there is no errors.
Why does this happen, and how can I solve the problem?
onscroll event doesn't work that way.
The event is dispatched when you are actually scrolling on that specific element. If that element has no scroll bar it won't work.
For example, you have a long HTML body that you can scroll over, you have a p element inside it that has no scroll bar. And you do some scrolling. You would be doing that scrolling on the document itself and not the p element.
If you need to show an alert when an element enters your viewport you should use IntersectionObserver API
Example 1
Scrolling on the red paragraph or the white document, both of them still dispatch the document event listener.
let containerScrollCount = 0;
let textScrollCount = 0;
const alertScrollCounts = () => {
console.log(`container was scrolled ${containerScrollCount} times`);
console.log(`text was scrolled ${textScrollCount} times`);
}
document.getElementById('text').addEventListener('scroll', () => {
textScrollCount++;
alertScrollCounts();
})
document.addEventListener('scroll', () => {
containerScrollCount++;
alertScrollCounts();
})
#text {
background: red;
max-width:50%;
}
<div id="container">
<p id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In aliquet venenatis hendrerit. Quisque id interdum sem. Etiam at iaculis augue. Mauris fermentum imperdiet velit, ut bibendum odio lacinia ut. Suspendisse sed varius velit. Quisque ultricies bibendum velit, in mattis odio venenatis sed. Ut eget eleifend nisl, vel sodales risus. Integer purus risus, finibus eget congue nec, mattis nec felis. Nullam sit amet venenatis est.
Phasellus ut pretium ante, vitae hendrerit elit. Duis ac diam et nunc rhoncus finibus. Proin dictum sed ipsum ut pellentesque. Aenean vestibulum fermentum malesuada. Nulla feugiat risus eget nisi cursus scelerisque. Vivamus ullamcorper efficitur metus in congue. Proin porttitor urna in magna varius rutrum. Maecenas dui enim, volutpat sed lorem nec, tincidunt vulputate ante. Integer tincidunt tellus sit amet lacinia tincidunt. Fusce imperdiet, urna condimentum semper sodales, ligula nulla cursus lorem, at elementum sapien dui eget elit. Donec pharetra egestas pulvinar. Nullam a nisi et nunc laoreet feugiat non ut sem. Donec efficitur diam lorem, sed ultrices quam vestibulum sit amet. Aenean tempor erat dolor, viverra efficitur augue cursus blandit. Quisque in efficitur tellus. Integer blandit aliquet ante sit amet tristique.
Vivamus at tortor at orci euismod semper ac quis lacus. Ut pharetra sit amet quam non laoreet. Integer ac blandit nunc. Suspendisse mollis sapien odio, ac convallis sapien semper non. Nunc finibus, neque vitae viverra cursus, leo turpis eleifend metus, et ornare eros ligula et orci. Vivamus rutrum et turpis at congue. Phasellus suscipit, lorem vel pharetra convallis, urna ipsum commodo orci, vitae mollis nulla tortor in dui. Nam rhoncus, arcu ut egestas suscipit, nulla lacus gravida nisl, sed porttitor dolor sem gravida lacus. Cras nulla nisl, cursus sed dictum vitae, fermentum nec tellus. Donec et nisi eget nisi elementum ultricies id non mi. Integer quam massa, porttitor ac tortor vitae, elementum eleifend odio. Morbi malesuada faucibus nisi, ac volutpat sem vestibulum eu. Donec blandit nunc non tellus pellentesque cursus a vel risus. Suspendisse quis venenatis risus, eu consectetur neque. Etiam tincidunt lectus dui, a mattis arcu scelerisque id.
Nulla vel erat at sapien rhoncus venenatis ut eget velit. Duis eu dolor porta, dapibus dui in, lacinia risus. Mauris commodo dui et eros condimentum, at feugiat dui vehicula. Nulla eu nulla viverra, laoreet mi eget, euismod nisi. Pellentesque lorem odio, consequat imperdiet sodales sit amet, tincidunt in odio. Proin in urna eget dolor blandit ullamcorper. Pellentesque non erat ante. Quisque ornare arcu id ex accumsan, sit amet suscipit lorem euismod. Nam eu turpis ultricies, luctus nisi a, facilisis justo. Vivamus ullamcorper lectus at rutrum vestibulum. Duis vehicula augue vitae imperdiet sagittis.
Mauris in posuere justo. Etiam blandit turpis non tincidunt blandit. Aenean vestibulum, lacus non dapibus egestas, leo lorem vestibulum odio, mollis fringilla felis eros sit amet nulla. Vestibulum a suscipit leo, a tempor lectus. Praesent justo enim, facilisis quis purus nec, convallis efficitur velit. Cras metus turpis, pulvinar tristique tincidunt et, consequat a neque. Vivamus vehicula id orci at tincidunt.</p>
<div>
Example 2
Scrolling on red dispatches its own listener. Why? Because it has a scroll bar.
let containerScrollCount = 0;
let textScrollCount = 0;
const alertScrollCounts = () => {
console.log(`container was scrolled ${containerScrollCount} times`);
console.log(`text was scrolled ${textScrollCount} times`);
}
document.getElementById('text').addEventListener('scroll', () => {
textScrollCount++;
alertScrollCounts();
})
document.addEventListener('scroll', () => {
containerScrollCount++;
alertScrollCounts();
})
#text {
background: red;
max-width:50%;
max-height:300px;
overflow-y:auto;
}
<div id="container">
<p id="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In aliquet venenatis hendrerit. Quisque id interdum sem. Etiam at iaculis augue. Mauris fermentum imperdiet velit, ut bibendum odio lacinia ut. Suspendisse sed varius velit. Quisque ultricies bibendum velit, in mattis odio venenatis sed. Ut eget eleifend nisl, vel sodales risus. Integer purus risus, finibus eget congue nec, mattis nec felis. Nullam sit amet venenatis est.
Phasellus ut pretium ante, vitae hendrerit elit. Duis ac diam et nunc rhoncus finibus. Proin dictum sed ipsum ut pellentesque. Aenean vestibulum fermentum malesuada. Nulla feugiat risus eget nisi cursus scelerisque. Vivamus ullamcorper efficitur metus in congue. Proin porttitor urna in magna varius rutrum. Maecenas dui enim, volutpat sed lorem nec, tincidunt vulputate ante. Integer tincidunt tellus sit amet lacinia tincidunt. Fusce imperdiet, urna condimentum semper sodales, ligula nulla cursus lorem, at elementum sapien dui eget elit. Donec pharetra egestas pulvinar. Nullam a nisi et nunc laoreet feugiat non ut sem. Donec efficitur diam lorem, sed ultrices quam vestibulum sit amet. Aenean tempor erat dolor, viverra efficitur augue cursus blandit. Quisque in efficitur tellus. Integer blandit aliquet ante sit amet tristique.
Vivamus at tortor at orci euismod semper ac quis lacus. Ut pharetra sit amet quam non laoreet. Integer ac blandit nunc. Suspendisse mollis sapien odio, ac convallis sapien semper non. Nunc finibus, neque vitae viverra cursus, leo turpis eleifend metus, et ornare eros ligula et orci. Vivamus rutrum et turpis at congue. Phasellus suscipit, lorem vel pharetra convallis, urna ipsum commodo orci, vitae mollis nulla tortor in dui. Nam rhoncus, arcu ut egestas suscipit, nulla lacus gravida nisl, sed porttitor dolor sem gravida lacus. Cras nulla nisl, cursus sed dictum vitae, fermentum nec tellus. Donec et nisi eget nisi elementum ultricies id non mi. Integer quam massa, porttitor ac tortor vitae, elementum eleifend odio. Morbi malesuada faucibus nisi, ac volutpat sem vestibulum eu. Donec blandit nunc non tellus pellentesque cursus a vel risus. Suspendisse quis venenatis risus, eu consectetur neque. Etiam tincidunt lectus dui, a mattis arcu scelerisque id.
Nulla vel erat at sapien rhoncus venenatis ut eget velit. Duis eu dolor porta, dapibus dui in, lacinia risus. Mauris commodo dui et eros condimentum, at feugiat dui vehicula. Nulla eu nulla viverra, laoreet mi eget, euismod nisi. Pellentesque lorem odio, consequat imperdiet sodales sit amet, tincidunt in odio. Proin in urna eget dolor blandit ullamcorper. Pellentesque non erat ante. Quisque ornare arcu id ex accumsan, sit amet suscipit lorem euismod. Nam eu turpis ultricies, luctus nisi a, facilisis justo. Vivamus ullamcorper lectus at rutrum vestibulum. Duis vehicula augue vitae imperdiet sagittis.
Mauris in posuere justo. Etiam blandit turpis non tincidunt blandit. Aenean vestibulum, lacus non dapibus egestas, leo lorem vestibulum odio, mollis fringilla felis eros sit amet nulla. Vestibulum a suscipit leo, a tempor lectus. Praesent justo enim, facilisis quis purus nec, convallis efficitur velit. Cras metus turpis, pulvinar tristique tincidunt et, consequat a neque. Vivamus vehicula id orci at tincidunt.</p>
<div>

jQuery to Javascript/Vue

I want to create a custom search box that can jump to its matches using mark.js mark.js web page.
They do have an example here:
https://jsfiddle.net/julmot/973gdh8g/
But it is written using jQuery.
I tried converting it to JS/Vue (using Quasar), but now I couldn't get it to work.
No errors, but also no highlights.
I have updated jQuery lines like:
$prevBtn = $("button[data-search='prev']")
to:
prevBtn = document.querySelector('#prev')
And these, I dont know how to convert the others, such as:
$nextBtn.add($prevBtn).on("click", function() {})
Here is my fiddle (simplified version, but not completely done yet, also make sure to click "Search" after input):
https://codepen.io/keechan/pen/JjWEYmP?editors=1111
What am I missing? Help please!
I rewrote their jQuery example using pure JavaScript.
You should be able to compare the two examples to see how the various jQuery functions translate to JavaScript and then implement them into your Vue project.
https://jsfiddle.net/75qyu3j8/
I tried to keep the variable names the same so it is easier to understand.
document.body.onload = function() {
// the input field
var $input = document.querySelector("input[type='search']"),
// clear button
$clearBtn = document.querySelector("button[data-search='clear']"),
// prev button
$prevBtn = document.querySelector("button[data-search='prev']"),
// next button
$nextBtn = document.querySelector("button[data-search='next']"),
// the context where to search
$content = document.querySelector(".content"),
$contentMark = new Mark($content),
// jQuery object to save <mark> elements
$results,
// the class that will be appended to the current
// focused element
currentClass = "current",
// top offset for the jump (the search bar)
offsetTop = 50,
// the current index of the focused element
currentIndex = 0;
/**
* Jumps to the element matching the currentIndex
*/
function jumpTo() {
if ($results.length) {
var position,
$current = $results[currentIndex];
$results.forEach($result => $result.classList.remove(currentClass));
if ($current) {
$current.classList.add(currentClass);
position = $current.offsetTop - offsetTop;
window.scrollTo(0, position);
}
}
}
/**
* Searches for the entered keyword in the
* specified context on input
*/
$input.addEventListener("input", function() {
var searchVal = this.value;
$contentMark.unmark({
done: function() {
$contentMark.mark(searchVal, {
separateWordSearch: true,
done: function() {
$results = $content.querySelectorAll("mark");
currentIndex = 0;
jumpTo();
}
});
}
});
});
/**
* Clears the search
*/
$clearBtn.addEventListener("click", function() {
$contentMark.unmark();
$input.value = ""
$input.focus();
});
/**
* Next and previous search jump to
*/
$nextBtn.after($prevBtn);
function prevNextHandler() {
if ($results.length) {
currentIndex += (this.dataset.search === "prev" ? -1 : 1);
if (currentIndex < 0) {
currentIndex = $results.length - 1;
}
if (currentIndex > $results.length - 1) {
currentIndex = 0;
}
jumpTo();
}
}
$nextBtn.addEventListener("click", prevNextHandler);
$prevBtn.addEventListener("click", prevNextHandler);
};
mark {
background: yellow;
}
mark.current {
background: orange;
}
.header {
padding: 10px;
width: 100%;
background: #eee;
position: fixed;
top: 0;
left: 0;
}
.content {
margin-top: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js"></script>
<div class="header">
Search:
<input type="search" placeholder="Lorem">
<button data-search="next">↓</button>
<button data-search="prev">↑</button>
<button data-search="clear">✖</button>
</div>
<div class="content">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eu ullamcorper orci, eget porttitor justo. Aliquam id sollicitudin elit. Nulla in sodales ipsum. Donec vulputate venenatis magna. Vestibulum sit amet leo lacinia, cursus lectus in, gravida
metus. In ultricies sed tortor non pellentesque. Mauris quis tempor neque. Donec nec sagittis magna. Integer fringilla posuere metus eu mollis. Ut ac porta metus. Duis sed lacinia metus. Nunc malesuada iaculis risus vitae bibendum.
</p>
<p>
Vivamus posuere condimentum leo eu hendrerit. Pellentesque placerat iaculis ante a rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu ipsum ac magna congue congue sed maximus tortor. Vivamus id odio elementum, vehicula nunc
ut, efficitur felis. Nullam hendrerit velit libero, gravida porttitor tortor ullamcorper eu. Ut ut lectus non enim sagittis aliquam quis in orci. Donec a arcu eu eros cursus cursus. Donec dictum dignissim tellus, dictum egestas purus pellentesque
sed.
</p>
<p>
Vestibulum eu ornare urna, nec aliquam lectus. Phasellus eu odio sapien. Vestibulum eu turpis at lorem sagittis posuere. Quisque tellus nunc, facilisis id lacus nec, ornare rhoncus elit. Vivamus vehicula eros a condimentum venenatis. Sed orci massa, pulvinar
sed erat nec, pellentesque suscipit leo. Mauris lobortis tincidunt nunc, sed tempus ex congue vitae. Curabitur lobortis mauris in ex malesuada, quis vehicula neque lobortis. Curabitur aliquam porttitor tellus eget tempus. Donec maximus tempus tristique.
Aliquam tincidunt odio dictum, scelerisque ipsum ut, facilisis quam. Ut nec malesuada neque.
</p>
<p>
Proin felis eros, tincidunt vitae scelerisque sit amet, dictum nec ante. Praesent tincidunt ac lacus nec elementum. Vivamus sed gravida purus, sed efficitur tortor. Nulla non molestie arcu. Sed tincidunt consectetur ligula sed lobortis. In non sapien
ac urna lacinia placerat sed nec lacus. Aenean lobortis tincidunt sapien a hendrerit. Quisque eu turpis accumsan nisl blandit efficitur.
</p>
<p>
Nam sit amet pellentesque est. Sed ligula turpis, ultricies sit amet mattis elementum, tristique non risus. Phasellus at congue ex. Proin nisi leo, vestibulum vitae accumsan in, imperdiet id dolor. Quisque at blandit nisl. Class aptent taciti sociosqu
ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc eget metus augue. Morbi faucibus venenatis sapien, fermentum porttitor felis pharetra a. Nam interdum nibh tortor, quis maximus turpis blandit eget. Praesent in feugiat neque, sed
vulputate quam. Curabitur erat quam, efficitur et congue quis, iaculis euismod libero. Quisque odio sapien, efficitur non mauris ac, tincidunt condimentum turpis.
</p>
<p>
Maecenas dapibus aliquam vehicula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent convallis viverra leo quis porta. Sed sit amet porttitor quam. Fusce nec risus non augue consectetur ultricies. Aliquam
elit lorem, tincidunt ac dolor vel, vulputate consectetur ex. In hac habitasse platea dictumst. Sed eget nisl aliquam, cursus odio nec, commodo lorem. Nulla mollis tortor eu odio rutrum vulputate. Donec condimentum molestie mauris, nec sodales nisi
volutpat aliquam. Nulla mollis libero sed nibh volutpat, ac mollis elit tincidunt. Vestibulum cursus velit vitae felis aliquam ultricies. Donec vehicula dictum feugiat. Vestibulum volutpat sollicitudin sagittis.
</p>
<p>
Aliquam consequat, diam eu ullamcorper porta, diam eros rhoncus turpis, in rutrum sem diam a risus. Duis lacinia velit sed ante feugiat venenatis. Aenean orci leo, dictum non finibus nec, dignissim quis eros. Nullam sit amet orci ac purus blandit commodo
sit amet eget neque. Sed pellentesque dictum tortor. Ut dui erat, tempus in odio in, aliquet convallis mi. Morbi efficitur justo ante, quis ultricies turpis suscipit ac. Sed sit amet nisl rutrum, laoreet mauris id, ullamcorper orci. In facilisis nisi
eget fringilla imperdiet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi ut ultricies dui. Pellentesque elit urna, imperdiet sed congue eget, hendrerit sed urna.
</p>
<p>
Proin vel hendrerit nulla. Vivamus vehicula nibh nec lorem blandit, quis aliquam ipsum suscipit. Nulla at vestibulum felis. Aenean ac nibh eget enim molestie pulvinar. Duis nulla justo, tristique id nulla nec, faucibus imperdiet arcu. In vel pretium dui,
at lobortis sapien. Phasellus ullamcorper id enim eget dictum. Ut imperdiet rutrum est a rutrum. Curabitur eget dignissim tellus. Fusce tempus leo nisl, vitae auctor diam feugiat sit amet. Vestibulum accumsan justo eget odio imperdiet, consectetur
efficitur ex dapibus.
</p>
<p>
Sed pharetra odio a nibh pharetra rutrum. Suspendisse ut ullamcorper lectus. Donec ipsum mauris, congue et lobortis sit amet, ultricies ac tellus. Sed nisi risus, condimentum at varius quis, condimentum ac velit. In condimentum, magna sed ornare eleifend,
dolor nulla mollis felis, quis feugiat elit turpis non ipsum. Etiam aliquam est imperdiet dolor rutrum, at varius leo sodales. Morbi quis iaculis metus.
</p>
<p>
Maecenas auctor nec ligula ac luctus. Nam sit amet euismod mauris. Donec et diam sit amet eros efficitur tempor. Mauris non erat sit amet nunc interdum pulvinar. Sed luctus hendrerit justo eget pulvinar. Cras non arcu sed ligula faucibus pulvinar. Sed
egestas risus nisl. Duis quis arcu tempus, cursus erat ac, gravida enim. Cras et condimentum ante. Nullam eleifend egestas velit, quis semper est imperdiet non. Donec quis purus varius, placerat mi et, dictum lorem. Sed quis finibus nisi, vitae molestie
metus. Donec lobortis eros quis vestibulum vulputate.
</p>
</div>

ajax page loading content having history implementation AND hashtag functionality

I'm extending functionality based on ajax loader like this
cats loader and this mia loader
I can't seem to smash a bug if I have pages using anchors like
Contacto
Ajax pages load like this, with (kind of because retrieves from json) target page on data-
//<a data-mia="home" href="/home">Home</a>
if ( el.getAttribute('data-mia') in pages ){
el.addEventListener('click', clickHandler, true);
The scroll stops in the middle instead going fully to bottom. I believe because popstate is fired.
I can have the fwd and back buttons functionality and broke hashtags or viceversa but I'm unable to do both. Can't we do that by 2020?
This some things I tried, commented out:
// Revert to a previously saved state
window.addEventListener('popstate', function(event) {
console.log('popstate fired!');
//console.log(history.state);
// if prevents hashes/anchor scroll navigation in same url bugging
// var w = window.location+"";
// if (!w.lastIndexOf('#') > 0)
updateContent(event.state);
});
Adding this I also tried but seems not the way or I'm missing how to combine with the correct previous:
window.addEventListener('hashchange', function() {
console.log('The hash has changed!');
event.preventDefault();
// nasty hack #footer for contact link.
// if (window.location.lastIndexOf('#footer') > 0)
document.querySelector('#footer').scrollIntoView();
}, false);
Right now with these 2 like that, anchors and ajax load works, but fwd/back are bugged when #hashes involved. Like this:
Navigate: /page1 /2 /2#footer /3
Back: /3 /2#footer (not going to anchor) /2 (goes here to anchor) ...
I'd prefer not to resort to onclick event like
<a onclick"js:goto('footer')" href="#footer">Contacto</a>
Following a full snippet example.
var pages = [];
var home_title = $(document).attr('title');
var home_meta_desc = $('meta[name="description"]').attr('content');
pages = {
"1": {
"title": "title 1 ",
"meta_desc": "meta 1",
"file": "1 file"
},
"2": {
"title": "title 12 ",
"meta_desc": "meta 12",
"file": "12 file"
},
"3": {
"title": "title 3 ",
"meta_desc": "meta 3",
"file": "3 file"
},
"4": {
"title": "title 4 ",
"meta_desc": "meta 4",
"file": "4 file"
}
};
els = document.querySelectorAll('[data-mia]');
els.forEach(function(el) {
if (el.getAttribute('data-mia') in pages) {
el.addEventListener('click', clickHandler, true);
}
});
function updateContent(data) {
document.querySelector('#one').scrollIntoView();
//$( "#one" ).fadeOut(); //
$("#one > .inner").hide();
console.log("updating content", data);
if (data == null) {
console.log('home content triggered updt content');
$(document).prop('title', home_title);
$("meta[name='description']").attr("content", home_meta_desc);
$('#one').text(data.file); //$( "#one > .inner" ).fadeIn(100).load( "blog/home.html " );
return;
}
$(document).prop('title', data.title);
$("meta[name='description']").attr("content", data.meta_desc);
$('#one').text(data.file); //$("#one > .inner").fadeIn(300).load("blog/" + data.file + ".html");
}
// Load some mock JSON data into the page
function clickHandler(event) {
var cat = event.target.getAttribute('href').split('/').pop(),
data = pages[cat]; // || null; // In reality this could be an AJAX request
console.log("clickHandler data:", data);
updateContent(data);
// Add an item to the history log
history.pushState(data, event.target.textContent, event.target.href);
return event.preventDefault();
}
// Revert to a previously saved state
window.addEventListener('popstate', function(event) {
console.log('popstate fired!');
//console.log(history.state);
// if prevents hashes/anchor scroll navigation in same url bugging
// var w = window.location+"";
// if (!w.lastIndexOf('#') > 0)
updateContent(event.state);
});
window.addEventListener('hashchange', function() {
console.log('The hash has changed!');
event.preventDefault();
// nasty hack #footer for contact link.
// if (window.location.lastIndexOf('#footer') > 0)
document.querySelector('#footer').scrollIntoView();
}, false);
// Store the initial content so we can revisit it later
//console.log("hist pre", history.state);
history.replaceState(null, document.title, document.location.href);
//console.log("hist post ", history.state);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="nav">
<a data-mia="1" href="/1">Home</a>
<a data-mia="2" href="/2">Manual</a>
<a data-mia="3" href="/3">Not only 3</a>
<a data-mia="4" href="/4">Fotos</a>
Contacto
<!-- onclick="document.querySelector('#footer').scrollIntoView({ behavior: 'smooth' })" -->
</nav>
<section id="one">
<div class="inner">
server load content['body'];
</div>
</section>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin sollicitudin nunc vel libero malesuada semper. Praesent porttitor tincidunt finibus. Morbi elementum massa vitae quam eleifend, eget dignissim diam tempus. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Morbi non iaculis nunc. Cras ac sollicitudin erat, nec pharetra ipsum. Proin in condimentum est, eget ullamcorper orci. Cras accumsan ante leo, et sodales orci tempor sed. Pellentesque feugiat ac
urna quis rhoncus. Pellentesque convallis lorem libero, et tincidunt nibh varius ac. Maecenas magna urna, mattis at aliquam semper, hendrerit sed libero. Sed feugiat risus mi, ut tempor justo sodales in. Duis justo diam, viverra eu sodales nec, accumsan
non ex. Fusce sed suscipit sem. Donec a nibh suscipit, blandit felis vitae, consectetur metus. Maecenas faucibus odio id vulputate accumsan. Fusce porta non enim vel rutrum. Vestibulum ullamcorper fermentum eleifend. Proin ullamcorper placerat purus sed
tempor. Suspendisse suscipit suscipit urna quis placerat. Maecenas at justo pulvinar, varius nunc non, dictum justo. Curabitur in mollis tortor, at consequat ante. Duis commodo tellus neque, id molestie dui pellentesque ut. Quisque nec felis quis nulla
sollicitudin finibus. Fusce mattis mauris quis est pulvinar, sed interdum nisl pharetra. Morbi dictum, mi vitae viverra rhoncus, nibh ex varius magna, vel tincidunt erat odio ultrices tellus. Maecenas feugiat nibh quis lectus sodales, vel fringilla nulla
tincidunt. Phasellus condimentum rhoncus feugiat. Nam vel condimentum purus, et venenatis odio. Nam nisl tortor, faucibus in egestas vel, lacinia quis massa. Curabitur vel consectetur leo. Mauris sed imperdiet nunc. Nam enim eros, accumsan sit amet pulvinar
id, bibendum sit amet neque. Ut magna nulla, lobortis in imperdiet et, sagittis at enim. Etiam malesuada eu felis id consectetur. Nulla libero eros, fringilla ac consectetur non, efficitur a massa. Praesent ornare, ex id vulputate suscipit, dolor neque
eleifend magna, a posuere tellus justo sollicitudin massa. Pellentesque at mollis magna, at dapibus orci. Suspendisse sagittis libero quis augue accumsan euismod ut a arcu. Nulla sit amet nulla at augue imperdiet rhoncus id a mi. Morbi eu elementum augue,
eget luctus ex. Vivamus neque neque, tristique at bibendum et, posuere vel ligula. Vestibulum nec scelerisque erat, at fermentum massa. Donec et nulla rhoncus, ullamcorper enim vitae, convallis odio. Etiam consequat mauris leo, gravida consequat ex porta
vel. Mauris sed dignissim risus. Sed risus tellus, ullamcorper eu neque quis, rhoncus pulvinar massa. Suspendisse arcu tellus, varius sed luctus vel, viverra vel ex. Nullam ac mi eros. Proin ac volutpat orci, quis ornare augue. Donec a ultrices nunc.
Curabitur at aliquet augue. Aenean pharetra placerat sem. Donec blandit euismod ipsum, a cursus lorem fringilla ut. Nulla sed feugiat metus. Nam mollis, massa vel viverra lobortis, odio purus convallis mauris, ac accumsan sem turpis eu urna. Aliquam vel
lacus non dolor tempus lacinia in eget ante. Phasellus congue erat eu interdum luctus. Sed non sapien finibus, porta augue quis, luctus sapien. Praesent euismod porta nisi, nec volutpat metus hendrerit sed. Aenean gravida sed sem in consequat. Donec non
nisi euismod, fermentum nibh bibendum, pellentesque lorem. Vestibulum at placerat nulla. Ut sodales nulla at tincidunt blandit. Nulla non elit non nisl aliquet luctus. Nam lacinia justo ac ipsum finibus, non pellentesque ante hendrerit. Duis auctor auctor
tincidunt. Morbi porta odio id arcu tristique, vel finibus felis tristique. Nulla maximus ullamcorper augue, ut efficitur enim sagittis at. Fusce vitae lorem mi. Maecenas ultrices nisl et nibh feugiat vehicula. Ut dignissim placerat arcu, pellentesque
varius tortor. Quisque egestas massa dui. Vestibulum finibus interdum est, a porttitor diam scelerisque at. Donec egestas dui sed orci consectetur, quis tincidunt dolor lobortis. Duis mollis leo sed velit varius, ut laoreet turpis accumsan. Sed ac neque
eu nisl porta eleifend. In turpis urna, dignissim at convallis vel, luctus nec lectus. Nullam in mi laoreet, euismod urna ut, sagittis libero. Nam iaculis, metus vehicula tempus cursus, arcu turpis imperdiet orci, id posuere nulla mi vel dui. Aenean tempus
sit amet ligula vel ultricies. Quisque ac tortor bibendum sapien consectetur blandit in at felis. Vivamus consectetur velit tincidunt, eleifend augue vel, gravida quam. In at sodales purus. Aenean pulvinar sapien at ante viverra scelerisque. Duis nulla
diam, efficitur sit amet enim a, ornare tempus libero. Maecenas vitae lacinia ipsum. Nunc elementum mollis consequat. Duis dapibus vehicula purus, ac rhoncus diam interdum et. Quisque lacinia sit amet elit non ornare. Ut at tellus aliquam, sodales dui
sed, placerat leo. Aliquam erat volutpat. Nunc interdum egestas lacus sit amet eleifend. Donec ultrices, diam vitae imperdiet dignissim, metus purus accumsan quam, eget vehicula lorem diam rhoncus magna. Vestibulum ante libero, aliquet fringilla pretium
at, ultricies sed massa. Pellentesque vulputate ut nisl a egestas. Aliquam faucibus est et ligula ultrices, vitae tempor enim fringilla. Sed nunc nulla, lobortis in leo eu, sollicitudin vestibulum eros. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Donec a erat vel lacus porttitor euismod rhoncus sit amet diam. Suspendisse pharetra dui quis tempor commodo. Cras tristique, ligula non venenatis sagittis, sapien justo consectetur nisi, ac suscipit sem turpis in nisi.
Maecenas leo lacus, lobortis a suscipit at, fermentum sit amet lacus. Nam mattis, augue vitae consectetur dapibus, leo lacus consequat mi, at placerat tellus orci sed nisi. Donec imperdiet vehicula metus vel venenatis. Sed finibus a tellus eu laoreet.
Mauris mattis magna tellus, quis lobortis lacus facilisis eget. Sed eu luctus ante, a porttitor est. Nunc et lobortis lacus. Duis eu volutpat lectus, et convallis nisl. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Phasellus condimentum auctor tortor, id molestie libero tincidunt sed. Duis vitae felis sit amet tellus malesuada gravida congue in mauris. Mauris rutrum placerat tincidunt. Suspendisse cursus pharetra finibus. Nulla laoreet turpis ac ante luctus, vitae
luctus turpis pharetra. Duis a congue ligula. Cras commodo urna sit amet ante maximus iaculis. Duis sollicitudin lobortis faucibus. Etiam mauris sem, blandit at finibus eu, congue sed felis. Vivamus aliquam massa eget turpis fermentum ornare. Sed lobortis
aliquet est, eget fermentum lorem sagittis at. Suspendisse dui risus, interdum eu massa vel, fermentum iaculis mi. Nullam sed quam ut quam pretium mattis. Donec vel ornare nisi. Morbi dapibus arcu id gravida ultrices. Donec ullamcorper metus id ex volutpat
porta. Donec sollicitudin ante pharetra orci rutrum hendrerit pellentesque vel nibh. Nulla pharetra imperdiet mi, non fringilla neque interdum in. Nam fermentum augue vitae facilisis feugiat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
posuere cubilia Curae; Nunc imperdiet mi eget quam tristique aliquam. Phasellus vel semper nibh, in imperdiet justo. Maecenas efficitur pretium erat, quis fringilla magna malesuada ac. Etiam pretium cursus vulputate. Sed sit amet euismod ante. Aliquam
interdum nulla sit amet lacus gravida, ac malesuada libero ullamcorper. Ut volutpat enim a elit pharetra, sit amet efficitur dui porttitor. Nam erat orci, elementum eu fermentum nec, tempor id odio. Morbi id imperdiet leo, sit amet ultrices diam. Maecenas
sed accumsan tortor, ut sollicitudin neque. Nulla mi nunc, egestas in ex at, cursus finibus ligula. Sed bibendum porttitor lectus a ornare. Pellentesque augue tellus, rhoncus sed molestie a, hendrerit et dolor. Donec malesuada pretium libero et cursus.
Nunc tristique molestie orci, vitae lacinia augue. Maecenas molestie porttitor dui nec blandit. Pellentesque et pulvinar diam, eget vehicula neque. In quis ligula sit amet nisl condimentum ornare sit amet eu purus. Donec et commodo augue, nec volutpat
nisi. Nulla ullamcorper et libero id viverra. Aliquam lobortis, libero sit amet maximus faucibus, sapien nisi imperdiet enim, quis fermentum nulla velit eu ipsum. Sed non urna at quam imperdiet rutrum sed in leo. Curabitur at lectus condimentum, maximus
augue at, bibendum tellus. Nulla varius eros facilisis, pretium ante at, dignissim urna. Ut in malesuada diam. Fusce a nulla lacinia, tincidunt dolor vitae, luctus eros. Cras consequat a purus quis elementum. Quisque finibus fermentum cursus. Vestibulum
bibendum, purus id vestibulum pulvinar, nulla ante ullamcorper nisl, vitae dictum dolor ipsum in neque. Sed arcu massa, aliquet lacinia magna ac, aliquet finibus ex. Nam imperdiet dignissim turpis at laoreet. Proin nisl felis, varius sed facilisis ac,
maximus sit amet ante. Ut accumsan erat id iaculis condimentum. Curabitur consectetur ultricies lorem vel dignissim. Sed rutrum ante felis, vel venenatis massa pulvinar at. Sed consectetur sed erat vitae accumsan. Maecenas malesuada neque a lorem fringilla,
sed elementum quam posuere. Sed interdum tempus nulla at cursus. In non tristique est. Nulla bibendum purus lorem, non consequat nibh feugiat sit amet. Mauris ultrices enim eros, eu ornare est molestie molestie. Duis in ipsum ut augue rutrum semper volutpat
ultrices nulla. Phasellus gravida tempus nisi eu luctus. Cras volutpat, massa eu facilisis accumsan, dui turpis ullamcorper ligula, eget porta lectus purus id odio. Duis nulla felis, dictum ac nisl ut, aliquet cursus urna. Curabitur metus mi, iaculis
nec sapien in, aliquet dapibus metus. Nunc a risus semper orci ultrices venenatis facilisis eu mi. Mauris sodales aliquet neque eu tempor. Nulla in nisl lacinia, ultricies arcu placerat, tincidunt nunc. Quisque rutrum, urna id dictum tincidunt, purus
neque aliquam ex, nec accumsan ante metus et risus. Quisque facilisis, nisi viverra accumsan dignissim, orci urna fringilla turpis, quis tempor lorem arcu vel risus. Ut sit amet finibus tellus, vel congue nunc. Etiam sit amet bibendum nisl. Aliquam nec
rutrum purus. Sed eget nunc eget justo venenatis accumsan. Fusce vel est semper, rutrum orci ac, ullamcorper orci. Donec in ornare urna. Sed sollicitudin maximus ante, eget finibus lacus pharetra sed. Ut interdum, nulla ultricies euismod mollis, tortor
lorem accumsan ex, sit amet pharetra ante urna id libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean facilisis non purus at pulvinar. Fusce consectetur vestibulum purus. Ut finibus justo pretium,
dictum sapien nec, tincidunt eros. Nunc a sagittis nulla. Ut ac rhoncus libero. Aliquam egestas laoreet felis in volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ex nibh. Donec ac diam eget leo venenatis porta. Vivamus nisl
dolor, dictum eu justo vel, luctus euismod erat. Nunc imperdiet odio id turpis auctor scelerisque.
<hr>
<section id="footer">
<br>
<div class="inner">
I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot
<br> Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean facilisis non purus at pulvinar. Fusce consectetur vestibulum purus. Ut finibus justo pretium, dictum sapien nec, tincidunt eros. Nunc a sagittis
nulla. Ut ac rhoncus libero. Aliquam egestas laoreet felis in volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eu ex nibh. Donec ac diam eget leo venenatis porta. Vivamus nisl dolor, dictum eu justo vel, luctus euismod erat.
Nunc imperdiet odio id turpis auctor scelerisque.
<hr> I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot I'm a foot
</div>
</section>
I noticed that for all your links you execute the below code.
els = document.querySelectorAll('[data-mia]');
els.forEach(function(el) {
if (el.getAttribute('data-mia') in pages) {
el.addEventListener('click', clickHandler, true);
}
});
The clickHandler updates the history, hence when you navigate back the history contains the previous entries. But on the click of #footer the history is not updated, possibly this could be the reason for the issue you are facing.
Updating my answer.
I see you have used document.querySelector('#one').scrollIntoView(); assuming this is for scrolling to the top of page.
I suggest you use
// This prevents the page from scrolling to the previous position.
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
// scrolled to the top
window.scrollTo(0,0);
Use this for the IE/Edge
var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
var isEdge = /Edge/.test(navigator.userAgent);
if(isIE11 || isEdge) {
setTimeout(function(){ window.scrollTo(0, 0); }, 300);
// you need to scroll up once the page is loaded, you may need to change the timeout
}
with this, you would need to change the below listener as well.
window.addEventListener('hashchange', function() {
console.log('The hash has changed!');
//event.preventDefault();
// nasty hack #footer for contact link.
if (window.location.hash ==='#footer')
document.querySelector('#footer').scrollIntoView();
}, false);
This will prevent the listner from scrolling to the footer when "#footer" not in the location.
Hope this helps.

Section breaks for very long CSS columns

Using CSS columns I can format contiguous data into columns without having to manually break it into sections. This is especially useful when displaying complex, dynamic content.
However when the columns' content is so long that their height is greater than the viewport, dividing into columns makes for a poor reading experience. When the reader reaches the bottom of one column they must manually scroll up to begin reading the next.
In traditional print layouts, readability issues with very long columns are generally mitigated by breaking the columns into sections that 'restart' the column. (Physical pages themselves form a natural separation that the endlessly scrolling webpage does not have). The image below shows how horizontal section breaks makes columnar content that is longer than the height of the viewport more readable.
(Note that by 'restart the columns' I mean that once you reach the end of a left-hand column section you then read the right-hand column of that section before scrolling down to read both columns of the next section. https://www.shutterstock.com/image-vector/newspaper-template... might illustrate it more clearly).
There are very few guarantees for the column content. It may contain any number of paragraphs, images, nested block elements, nested inline elements and so on. Example markup is shown below.
.columns {
columns: 2 200px;
}
.columns * {
max-width: 100%;
}
<div class="columns">
<div class="introduction">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere dictum tincidunt. Cras in lectus eget libero suscipit venenatis at sit amet dolor. Donec tempor cursus justo, volutpat sodales dolor tempor eu.</p>
<p class="a-class">Pellentesque nec tempor sapien, sed vehicula sem. Ut pretium leo eget nisi cursus viverra. Ut ultrices porta nibh, sed laoreet felis condimentum sit amet. Aliquam a felis nec urna dignissim placerat sed sit amet elit. Donec elementum sagittis purus, facilisis convallis urna dapibus eu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam erat volutpat. Phasellus vel placerat metus. In efficitur enim eget lacinia ultrices. Duis ultricies dignissim nisi, id ultricies nulla venenatis vitae.</p>
</div>
<img src="https://i.kym-cdn.com/entries/icons/original/000/016/546/hidethepainharold.jpg">
<div class="body" style="">
<p>Suspendisse quis ante ullamcorper, lobortis orci ut, vestibulum dolor. Aenean sit amet purus commodo, sagittis leo vel, consequat nisi. Vestibulum sit amet sem vitae sapien pulvinar finibus. Ut sapien purus, luctus condimentum iaculis quis, lobortis at elit. Cras nulla ante, scelerisque ut aliquet in, elementum vel turpis. Vestibulum ipsum magna, congue sit amet sodales vel, aliquam vel nunc. <img src="https://upload.wikimedia.org/wikipedia/commons/e/e0/SNice.svg" width="100"> Sed eu dapibus nulla. In ut libero sit amet elit elementum gravida. Suspendisse quis quam consequat, pretium felis vel, laoreet turpis. Proin fringilla lobortis magna. Duis quam sapien, sodales nec accumsan id, ullamcorper eget tellus. Aliquam vitae orci cursus, porttitor ligula ut, fringilla odio. Donec a lorem ac eros interdum varius ultricies quis nulla.</p>
</div>
<p contenteditable="true">Nunc in elit tincidunt, ultrices massa sed, ultricies elit. In nec accumsan metus. Nullam ultricies eget tortor ut malesuada. Fusce in elit sit amet dolor bibendum malesuada.</p>
<div style="display:none">
<p>Curabitur sed hendrerit massa, vitae porta enim.</p>
</div>
<div><div><span>hey</span><div id="an-id">
Nullam ultricies eget tortor ut malesuada. Fusce in elit sit amet dolor bibendum malesuada. Nulla sed nisi vel nulla aliquam blandit. Nam vel tellus ut libero ultrices volutpat. Curabitur blandit quis arcu rutrum ullamcorper. Cras et pharetra augue, eget eleifend sem.
<img src="https://socialnewsdaily.com/wp-content/uploads/2018/08/Webp.net-resizeimage-27.jpg">
</div></div></div>
<p>
Mauris accumsan condimentum porttitor. Quisque tellus justo, suscipit sit amet posuere in, scelerisque nec orci. Aenean iaculis nisi in porta viverra. Sed eget ultricies nibh. Donec accumsan laoreet interdum. Donec risus mauris, dapibus et pulvinar at, posuere non nisi. Mauris at viverra nunc. Ut laoreet suscipit erat et cursus. Aenean id lacus volutpat lectus condimentum posuere. Nam ut lectus elit. Morbi sagittis elementum libero. Donec congue dolor sed tristique efficitur.
</p>
<p>
<div>
<p>Sed elementum velit sapien, et tristique justo bibendum at. Aliquam tincidunt magna nec nisi congue varius. Etiam dolor eros, rhoncus quis purus a, tempus malesuada quam. Sed bibendum condimentum eros vitae varius. Donec fermentum magna vel tellus tempus, nec finibus neque fermentum. Mauris tempus nisl sit amet lacus fermentum, at egestas urna egestas.</p>
<p>Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse ultrices lectus vitae nisl congue, sed porta dolor luctus. Donec aliquet at sapien sit amet tincidunt. Mauris vestibulum consectetur augue at imperdiet.</p>
</div>
</p>
</div>
I would like to automatically break my columns into regular sections after the columns reach a maximum height, as in the image above.
I have not found any property that controls the layout of CSS columns in this way. CSS regions look promising but have very poor browser support.
Computing the height of content with JavaScript and then inserting wrappers for each column block is probably possible, but not ideal. The content is dynamic and may change at any time, meaning the function must be run on every change. In addition the content may be very complex with sub elements that need to traverse section breaks, so naively inserting wrappers for each section will likely break the layout.
How can I automatically set section breaks for columnar content after a maximum height? (I am not married to the idea of CSS columns; perhaps a creative use of flex or inline-block will give the result I need).
There's actually a pretty simple solution using CSS columns. And the column-span attribute.
You can achieve all of this WITHOUT injecting anything into the content and simply styling HTML tags.
Basically, the CSS Columns Layout Module is intended to replicate print design layouts (like a newspaper) where the stylistic rule is that headlines should cross all columns of a story. Therefore any element with column-span: all will separate columns and cause the wrapping to reset. (notice the colors in my example show the wrap).
In this case, since you don't control the content its best to provide a common structure to your users. For example, I'd set H1, H2, H3 tags as well as <hr> and maybe some images to break columns. Allow your users to implement these tags as they normally would in writing and you'll achieve a nice layout. However, if they decide NOT to implement any of that stuff, that's up to them and you should let it wrap and cause a long scroll. (I might also suggest providing a preview so they can see what the result will look like)
Example of column-span
.columns {
margin: 30px;
columns: 2;
}
h1, h2, h3, h4, h5 {
column-span: all;
}
// simply to show where things wrap
h2 {
background-color: #eee;
padding: 5px 10px;
}
h5 {
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
text-align: center;
}
p:nth-of-type(1) {
color: blue;
}
p:nth-of-type(2) {
color: green;
}
p:nth-of-type(3) {
color: orange;
}
p:nth-of-type(4) {
color: teal;
}
<div class="columns">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras venenatis tellus non nunc tincidunt, vitae rutrum metus dapibus. Fusce at ante massa. Nam et nibh aliquet, porta nibh quis, rhoncus tortor. Aenean vestibulum neque sed urna lacinia aliquet.
Vestibulum facilisis egestas commodo. Cras sed maximus odio. Mauris posuere, ante id posuere facilisis, ligula libero consectetur lacus, at pellentesque nibh elit at magna. Proin sollicitudin quis nibh at viverra. Duis feugiat, lorem vitae facilisis
blandit, augue tortor cursus orci, sed porttitor eros elit at sapien. Quisque eleifend pulvinar pellentesque.
</p>
<h2>This is a header (h2) with column-span: all set on it</h2>
<p>
Donec blandit sapien leo, id aliquam purus vulputate a. Sed vel turpis ut eros suscipit blandit vel id eros. Nullam ut mauris luctus magna sollicitudin venenatis. Pellentesque leo mauris, malesuada nec purus ut, vestibulum malesuada lectus. Nullam ultricies
tellus sapien, ut fermentum risus pretium a. Nullam magna urna, ullamcorper non congue a, efficitur nec orci. Ut aliquam molestie nisi. In at accumsan purus. Etiam non tempor ipsum. Maecenas gravida mauris in nibh vehicula ullamcorper. Sed libero lorem,
faucibus eu lorem ut, gravida eleifend enim. Nunc vehicula fermentum consequat. Phasellus a pellentesque nisl. Nulla vel suscipit nibh, ac cursus dui. Suspendisse elementum dapibus risus. Nam egestas congue finibus.
</p>
<p>
Nunc vel risus nec nulla dignissim congue. Cras sit amet lacus nec nisl mollis pellentesque in vel purus. Suspendisse efficitur mollis nibh, congue facilisis libero auctor ac. Nulla facilisi. Etiam ut erat eget erat egestas suscipit. Curabitur vitae varius
mauris. Sed accumsan diam eros, id dapibus metus rutrum at. Nunc vitae pretium massa. Aenean quis mauris leo. Nulla egestas ligula eu libero interdum feugiat. Aliquam maximus erat et tortor auctor varius. Nulla in pharetra leo, vel suscipit nunc. Orci
varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec nec egestas ante, vitae sollicitudin arcu. Pellentesque posuere tempus nibh, nec tempus eros pellentesque ac.
</p>
<p>
Curabitur tempus massa dolor, nec congue purus efficitur id. Phasellus a dictum mauris. In porta nulla lectus, pretium semper erat semper id. Fusce ornare fringilla mi, ut auctor tortor semper non. Aliquam sed felis fermentum, molestie dolor vel, eleifend
diam. Donec accumsan bibendum mi, sed pretium tortor pulvinar nec. Aliquam et metus accumsan, pretium neque eu, elementum ipsum. Nam dapibus risus sed velit viverra, non consequat nibh pretium. Morbi nec gravida turpis. Quisque convallis justo ut rhoncus
porttitor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
<h5>This is a header (h5) with column-span: all set on it</h5>
<p>
Proin fringilla, sapien molestie mattis commodo, leo ligula viverra massa, eget semper leo purus sit amet est. Quisque eu diam interdum, pretium dui sed, dictum sem. Sed cursus eu est in ultrices. Suspendisse eleifend imperdiet lectus eu consectetur.
Duis semper libero nec magna commodo, sollicitudin pharetra magna luctus. Fusce pellentesque sollicitudin dolor, eu scelerisque elit condimentum vel. Curabitur id condimentum nisi, eu rhoncus arcu. Proin metus purus, condimentum nec semper vitae, blandit
at leo. Proin commodo et ipsum ac euismod. Aliquam erat volutpat. Nam neque nisi, ornare sit amet metus ac, faucibus tempor nulla. Quisque tristique malesuada finibus. Praesent fermentum posuere urna, a blandit risus sollicitudin nec.
</p>
</div>
Using 'break-inside: avoid;' each paragraph
In the solution I attached, I gave each DIV a break-avoid class to avoid breaking in the middle of the paragraph.
Like you asked, if the paragraph is not over yet you can scroll down. I added a gray color that you can see in the paragraphs.
You can control when it will break and you can also insert a div into a div if you want it in sequence.
Hope the solution is effective for you.
.columns {
columns: 5 250px;
}
.columns * {
max-width: 100%;
}
.break-avoid{
break-inside: avoid;
background-color: #ccc;
}
<div class="columns">
<div class="introduction break-avoid">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere dictum tincidunt. Cras in lectus eget libero suscipit venenatis at sit amet dolor. Donec tempor cursus justo, volutpat sodales dolor tempor eu.</p>
<p class="a-class">Pellentesque nec tempor sapien, sed vehicula sem. Ut pretium leo eget nisi cursus viverra. Ut ultrices porta nibh, sed laoreet felis condimentum sit amet. Aliquam a felis nec urna dignissim placerat sed sit amet elit. Donec elementum sagittis purus, facilisis convallis urna dapibus eu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam erat volutpat. Phasellus vel placerat metus. In efficitur enim eget lacinia ultrices. Duis ultricies dignissim nisi, id ultricies nulla venenatis vitae.</p>
</div>
<img src="https://i.kym-cdn.com/entries/icons/original/000/016/546/hidethepainharold.jpg">
<div class="body break-avoid" style="">
<div>
<p>Suspendisse quis ante ullamcorper, lobortis orci ut, vestibulum dolor. Aenean sit amet purus commodo, sagittis leo vel, consequat nisi. Vestibulum sit amet sem vitae sapien pulvinar finibus. Ut sapien purus, luctus condimentum iaculis quis, lobortis at elit. Cras nulla ante, scelerisque ut aliquet in, elementum vel turpis. Vestibulum ipsum magna, congue sit amet sodales vel, aliquam vel nunc.Suspendisse quis ante ullamcorper, lobortis orci ut, vestibulum dolor. Aenean sit amet purus commodo, sagittis leo vel, consequat nisi. Vestibulum sit amet sem vitae sapien pulvinar finibus. Ut sapien purus, luctus condimentum iaculis quis, lobortis at elit. Cras nulla ante, scelerisque ut aliquet in, elementum vel turpis. Vestibulum ipsum magna, congue sit amet sodales vel, aliquam vel nunc.Suspendisse quis ante ullamcorper, lobortis orci ut, vestibulum dolor. Aenean sit amet purus commodo, sagittis leo vel, consequat nisi. Vestibulum sit amet sem vitae sapien pulvinar finibus. Ut sapien purus, luctus condimentum iaculis quis, lobortis at elit. Cras nulla ante, scelerisque ut aliquet in, elementum vel turpis. Vestibulum ipsum magna, congue sit amet sodales vel, aliquam vel nunc.Suspendisse quis ante ullamcorper, lobortis orci ut, vestibulum dolor. Aenean sit amet purus commodo, sagittis leo vel, consequat nisi. Vestibulum sit amet sem vitae sapien pulvinar finibus. Ut sapien purus, luctus condimentum iaculis quis, lobortis at elit. Cras nulla ante, scelerisque ut aliquet in, elementum vel turpis. Vestibulum ipsum magna, congue sit amet sodales vel, aliquam vel nunc. <img src="https://upload.wikimedia.org/wikipedia/commons/e/e0/SNice.svg" width="100"> Sed eu dapibus nulla. In ut libero sit amet elit elementum gravida. Suspendisse quis quam consequat, pretium felis vel, laoreet turpis. Proin fringilla lobortis magna. Duis quam sapien, sodales nec accumsan id, ullamcorper eget tellus. Aliquam vitae orci cursus, porttitor ligula ut, fringilla odio. Donec a lorem ac eros interdum varius ultricies quis nulla.</p>
</div>
</div>
<p class="break-avoid" contenteditable="true">Nunc in elit tincidunt, ultrices massa sed, ultricies elit. In nec accumsan metus. Nullam ultricies eget tortor ut malesuada. Fusce in elit sit amet dolor bibendum malesuada.</p>
<div style="display:none;" class="break-avoid">
<p>Curabitur sed hendrerit massa, vitae porta enim.</p>
</div>
<div class="break-avoid"><div><span>hey</span><div id="an-id">
Nullam ultricies eget tortor ut malesuada. Fusce in elit sit amet dolor bibendum malesuada. Nulla sed nisi vel nulla aliquam blandit. Nam vel tellus ut libero ultrices volutpat. Curabitur blandit quis arcu rutrum ullamcorper. Cras et pharetra augue, eget eleifend sem.
<img src="https://socialnewsdaily.com/wp-content/uploads/2018/08/Webp.net-resizeimage-27.jpg">
</div></div></div>
<div class="break-avoid">
<p>
Mauris accumsan condimentum porttitor. Quisque tellus justo, suscipit sit amet posuere in, scelerisque nec orci. Aenean iaculis nisi in porta viverra. Sed eget ultricies nibh. Donec accumsan laoreet interdum. Donec risus mauris, dapibus et pulvinar at, posuere non nisi. Mauris at viverra nunc. Ut laoreet suscipit erat et cursus. Aenean id lacus volutpat lectus condimentum posuere. Nam ut lectus elit. Morbi sagittis elementum libero. Donec congue dolor sed tristique efficitur.
</p>
</div>
<div class="break-avoid">
<p>Sed elementum velit sapien, et tristique justo bibendum at. Aliquam tincidunt magna nec nisi congue varius. Etiam dolor eros, rhoncus quis purus a, tempus malesuada quam. Sed bibendum condimentum eros vitae varius. Donec fermentum magna vel tellus tempus, nec finibus neque fermentum. Mauris tempus nisl sit amet lacus fermentum, at egestas urna egestas.</p>
<p>Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse ultrices lectus vitae nisl congue, sed porta dolor luctus. Donec aliquet at sapien sit amet tincidunt. Mauris vestibulum consectetur augue at imperdiet.</p>
</div>
</div>

Odd results from ie/edge when getting bounding rect of selected text close to document border

Basic fiddle: https://jsfiddle.net/p6790wv9/
When trying to get the bounding rectangle of selected text everything works as expected in Firefox or Chrome but with the same code on IE and Chrome I'm experiencing odd results when selecting the last word* in a row.
For example this is the bounding rectangle when selecting the last word in the first row in Firefox:
{
x: 552.4166870117188,
y: 28.5,
width: 40.866668701171875,
height: 19,
top: 28.5,
right: 593.2833557128906,
bottom: 47.5,
left: 552.4166870117188
}
This is the result from IE 11:
{
bottom: 63.199996948,
constructor: ClientRect {...},
height: 36.799995422,
left: 8, // This is wrong!
right: 597.23999023,
top: 26.399999618,
width: 589.23999023 // ??
}
This is the js code used to obtain the previous two:
var selection = window.getSelection();
if (selection && selection.toString() !== "") {
rect = selection.getRangeAt(0).getBoundingClientRect();
console.log(rect);
}
I'm making sure the selection doesn't include any words from the following row (I just double click the word to select it).
Is this behaviour known/expected? Am I missing something?
EDIT:
*When I wrote last word of a row, I meant the text closer to the right border of the document, sorry it's late o\
Well the first issue is the browser clearly have different default styles and you don't have any CSS specified on the text you are creating your ranges on.
If you specify font-size and line-height and set a wild card pardding and margin to 0 the numbers start get closer.
However some things are being interpreted different.
For example 8pt font with 12pt line-height gives me 15 or 16px rect height (as expected) in IE Edge. But FireFox puts the rectangle height to 12 to 13px height. I am not sure why it varies by one pixel but it is apparent IE's height is based on line height but Firefox's height is based on font' size.
The point is each browser is making uses its own calculations.
document.getElementById("lorem").addEventListener("mouseup", mouseup);
function mouseup() {
selection = window.getSelection();
if (selection && selection.toString() !== "") {
rect = selection.getRangeAt(0).getBoundingClientRect();
console.log(rect);
}
}
* {margin:0px;padding:0px;}
#lorem {
font-size:8pt;
line-height:12pt;
font-family:arial;
}
<body>
<div id="lorem">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pretium mauris eu turpis rhoncus, et dictum nunc eleifend. Nullam ultricies iaculis lorem, eget faucibus purus ornare et. Aenean et tortor elementum, commodo urna sed, sollicitudin augue. Integer
pharetra iaculis augue, vitae vulputate magna pulvinar ac. Curabitur pretium augue eu mi gravida ultricies. Ut semper luctus nisl a pretium. Aliquam at lacus vel justo porttitor rhoncus sit amet quis mi. Integer ac enim condimentum, malesuada
massa ut, fermentum lacus. Nullam laoreet elit eu diam lacinia euismod. Nullam nec aliquet mauris, et maximus erat. Proin in ex justo. Aliquam dictum nisl vitae molestie tempor. Quisque id turpis at metus dictum ultrices in ac augue. Fusce tempus
tincidunt sem at commodo. Donec dapibus erat sed finibus consequat. Nullam et nisi lacus. Sed diam quam, faucibus vulputate egestas a, consequat a enim. Donec congue velit molestie, vulputate ante quis, finibus odio. Integer et erat sed ligula
egestas ornare sit amet quis nunc. In hac habitasse platea dictumst. Morbi feugiat libero nec lacus elementum malesuada. Fusce dictum turpis velit, in suscipit nibh tincidunt ut. Sed viverra tellus risus, vel laoreet augue lobortis nec. Suspendisse
tincidunt semper ante. Vestibulum sodales risus posuere enim placerat, ut convallis tortor mollis. Curabitur vitae dictum tortor. Curabitur pellentesque, enim eu malesuada placerat, nibh nulla iaculis mi, et vestibulum lorem metus vitae eros.
Ut nec ipsum in libero volutpat placerat. Suspendisse feugiat quam eu mauris elementum, sit amet venenatis velit malesuada. In iaculis eu odio id elementum. Curabitur nec augue ut turpis volutpat auctor ac non nunc. Sed posuere, purus quis accumsan
aliquam, mi sapien ultricies augue, sed bibendum nisl nibh id nulla. Aliquam fermentum elit ac condimentum laoreet. Sed pharetra elit gravida metus vulputate, a pharetra magna finibus. Aenean tincidunt orci sed libero sollicitudin cursus. Donec
sapien nisl, molestie non elementum et, efficitur ut lectus. Nulla scelerisque non arcu et sodales. Aliquam nisi neque, fermentum non arcu in, efficitur fermentum lorem. Proin laoreet magna lorem, a molestie leo sollicitudin efficitur. In hendrerit
purus et nulla lobortis, eget efficitur nisl aliquet. Donec nisl erat, tempus hendrerit lorem iaculis, varius feugiat purus. Aenean ac dolor eget ipsum blandit iaculis vel sed justo. Mauris tortor tortor, interdum vitae lectus id, ultricies vulputate
nibh. Cras convallis, risus eget semper scelerisque, erat urna tincidunt nisl, vel ultricies dui neque a felis. Pellentesque ut ligula vitae tortor tincidunt pellentesque in id nunc. Ut ac dictum quam. Nulla pretium commodo libero, quis tempor
mi pulvinar ac. Aliquam sagittis ex arcu, a scelerisque urna commodo in. Curabitur pharetra posuere efficitur. Mauris blandit urna vel libero euismod faucibus. Pellentesque laoreet magna ex. Vivamus commodo orci et commodo egestas. Nulla vel dapibus
libero.
</div>
</body>

Categories