Open Jemt opened 5 years ago
Unfortunately the approach described above scales poorly on mobile. When the width of the screen is reduced, text takes up more space vertically. Defining a height with the 'em' unit is not sufficient. So the text can either overflow, become hidden, or cause scroll.
We need to support this using JavaScript. The example below (review - quick and dirty!) calculates the height of the designer element, and adds a pseudo element behind it that spans the page, with the same height.
SMEventHandler.AddEventHandler(document, "DOMContentLoaded", function(e)
{
// Helpers (copied from Fit.UI)
var UpperCaseFirst = function(str)
{
Fit.Validation.ExpectString(str);
if (str === "")
return str;
return str[0].toUpperCase() + str.slice(1);
}
var ForEach = SMCore.ForEach;
var GetComputedStyle = function(elm, style)
{
var res = null;
if (window.getComputedStyle) // W3C
{
res = window.getComputedStyle(elm)[style];
}
else if (elm.currentStyle)
{
if (style.indexOf("-") !== -1) // Turn e.g. border-bottom-style into borderBottomStyle which is required by legacy browsers
{
var items = style.split("-");
style = "";
/*Fit.Array.*/ForEach(items, function(i)
{
if (style === "")
style = i;
else
style += /*Fit.String.*/UpperCaseFirst(i);
});
}
res = elm.currentStyle[style]; // Might return strings rather than useful values - e.g. "3em" or "medium"
// IE Computed Style fix by Dean Edwards - http://disq.us/p/myl99x
// Transform values such as 2em or 4pt to actual pixel values.
if (res !== undefined && res !== null && /^\d+/.test(res) === true && res.toLowerCase().indexOf("px") === -1) // Non-pixel numeric value
{
// Save original value
var orgLeft = elm.style.left;
// Calculate pixel value
var runtimeStyle = elm.runtimeStyle.left;
elm.runtimeStyle.left = elm.currentStyle.left;
elm.style.left = ((style === "fontSize") ? "1em" : res || 0); // Throws error for a value such as "medium"
res = elm.style.pixelLeft + "px";
// Restore value
elm.style.left = orgLeft;
elm.runtimeStyle.left = runtimeStyle;
}
}
return (res !== undefined ? res : null);
}
var bars = document.querySelectorAll(".page-wide-bar");
// Configure bars
SMCore.ForEach(bars, function(bar)
{
var s = document.createElement("style");
s.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(s);
if (!bar.id)
{
bar.id = "rid_" + SMRandom.CreateGuid(); // Random ID (rid)
}
else if (bar.className.indexOf("SMDesignerElement") > -1 && !bar.getAttribute("data-id"))
{
bar.setAttribute("data-id", bar.id);
}
bar.__pageWideBarStyle = s;
//bar.style.boxSizing = "border-box";
});
// Define updator
var designerOpen = false;
var updateBars = function()
{
SMCore.ForEach(bars, function(bar)
{
var newHeight = bar.offsetHeight;
if (designerOpen === false && newHeight === bar.__prevBarOffsetHeight)
{
//console.log("Escaping (offset height)");
return; // Skip
}
bar.__prevBarOffsetHeight = newHeight;
// TODO: Include borders etc!
var paddingTop = /*SMDom.*/GetComputedStyle(bar, "paddingTop");
var paddingTopFloat = parseFloat(paddingTop);
var paddingBottomFloat = parseFloat(/*SMDom.*/GetComputedStyle(bar, "paddingBottom"));
var checkSum = newHeight + "#" + paddingTop + "#" + paddingTopFloat + "#" + paddingBottomFloat;
if (bar.__prevBarCheckSum === checkSum)
{
//console.log("Escaping (checksum)");
return; // Skip
}
bar.__prevBarCheckSum = checkSum;
bar.__prevAlternateValue = !bar.__prevAlternateValue;
var css = "#" + bar.id + ":before";
css += "\n{";
css += "\n\t content: '" + (bar.__prevAlternateValue ? "" : " ") + "';"; // Value MUST change to make the element update in Legacy IE
css += "\n\t margin-top: -" + paddingTop + ";";
css += "\n\t background: inherit;";
//css += "\n\t background: orange;";
css += "\n\t position: absolute;";
css += "\n\t padding: inherit;";
css += "\n\t padding-left: 0px;";
css += "\n\t padding-right: 0px;";
css += "\n\t left: 0px;";
css += "\n\t width: 100%;";
css += "\n\t height: " + (bar.offsetHeight - paddingTopFloat - paddingBottomFloat) + "px;"; // Does not take borders into account!
css += "\n\t z-index: -1;";
css += "\n}";
console.log("Updating CSS: ", css);
if (bar.__pageWideBarStyle.styleSheet)
{
bar.__pageWideBarStyle.styleSheet.cssText = css; // Legacy IE
}
else
{
bar.__pageWideBarStyle.innerHTML = css;
}
});
}
updateBars();
// Monitor - update when necessary
setInterval(function() { updateBars(); }, (designerOpen === true ? 500 : 1500));
SMEventHandler.AddEventHandler(window, "resize", function(e) { updateBars(); });
});
Consider the following example.
Using pseudo elements we can make a container "stretch" across the page, just like a header image. It would be great if this was supported out of the box for a container registered as a designer element (SMDesignerElement class).