I’m using SplitLines.js . I’m calling it on a variety of elements on pages, and some pages have multiple elements on the page which run the function. E.g. here are a few
DEFAULT_STYLES.splitHTML(".image-button > header .fsElementTitle");
DEFAULT_STYLES.splitHTML(".home .school-box > header .fsElementTitle");
DEFAULT_STYLES.splitHTML(".home .school-events > header .fsElementTitle");
I’ll clean up the code once I get this working.
My goal is to get something like this blue text, but it must be very flexible and responsive - https://fnlst.com/xxGaHg
So this means I need to account for people resizing the browsers, it being used over top of images/videos where there isn’t a solid background color (so a repeating linear gradient is out of the question).
The above code runs and calls the below code.
splitHTML(ele) {
$(ele).each(function() {
$(this).splitLines({
tag: '<div class="line">',
width: Math.round(parseInt($(ele).width()))
});
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function() {
const lineWidths = [];
const linePositions = [];
$(ele).find(".line").each(function(i) {
lineWidths.push($(this).outerWidth());
linePositions.push($(this).position().top);
if($(ele).find(".line").length - 1 === i) {
for(let j=0;j<$(ele).find(".line").length;j++) {
const eleWidth = $(ele).width();
if(lineWidths[j] > eleWidth) {
DEFAULT_STYLES.unwrapHTML(ele);
break;
}
if(linePositions.some((val, i) => linePositions.indexOf(val) !== i)) {
DEFAULT_STYLES.unwrapHTML(ele);
break;
}
}
}
});
}, 250);
});
});
},
unwrapHTML(ele) {
$(ele).each(function() {
$(this).find(".line").contents().unwrap();
if($(this).is(":first-child")) {
$(this).clone().addClass("cloned").prependTo($(this).parent());
} else {
$(this).clone().addClass("cloned").insertAfter($(this).parent().find("> *").eq($(this).index() - 1));
}
$(this).remove();
$(ele+".cloned").splitLines({
tag: '<div class="line">',
width: Math.round(parseInt($(ele+'.cloned').width()))
});
$(ele+".cloned").removeClass("cloned");
});
}
How it works (or rather, how I believe it to work)…
- splitHTML function gets called per element
- I set the width (per an option in the plugin) - more on that in a bit.
- I use a window resize event and wait until the user has finished resizing (250ms).
- After the user is done resizing, I check 2 things: the individuals line WIDTH and the position offset relative to the nearest element with position: relative
- The width check is to see if my individual lines (which have white-space: nowrap) is overflowing the container, and if so, I begin the step of deconstruction of the HTML and reapplying the plugin. So this part of the code checks users resizing smaller.
- The position offset check is to see if a user is resizing their browser window larger and my inline-block lines have shifted up to be on a higher up row.
- If either conditions are true, I then call the
unwrapHTML
function which basically removes the.line
divs, clones the element, and calls the plugin back on that same element. I found the clone to be necessary due to issues I had.
The problem I have is that if I call this plugin on multiple elements, it doesn’t seem to work properly. If I call this…
DEFAULT_STYLES.splitHTML(".home .school-box > header .fsElementTitle");
This is found twice on my homepage. It works fine if both elements get this plugin. See this video.
However, if I call this twice…so e.g.
DEFAULT_STYLES.splitHTML(".home .school-box > header .fsElementTitle");
DEFAULT_STYLES.splitHTML(".home .school-events > header .fsElementTitle");
The .school-box is found twice on my page, and the school-events…just 1. But the act of calling this twice screws up my resizing.
https://fnlst.com/QFbKmg
The order of the calls matter. If I call both, and reverse the order, then the functionality is reversed - those 2 stacked boxes are fine, whereas my purple “Calendar Heading” does not work. Somehow I need to be able to call this on multiple elements. What am I missing? Sorry for the long post.