patternjavascriptMinor
Performance of a method to mask all but one rectangular element on the page
Viewed 0 times
themaskmethodallbutoneperformancerectangularelementpage
Problem
The point of this code is to mask a page where the user is editing the page's 'body' content. This is in a CMS. The rest of the page is the website template (i.e. header, index bar etc...). I've covered resizing the window, and the DIV itself growing larger.
I'd love to know if there is a more efficient way to do this. I've used a DIV position: fixed as a mask under the editable DIV but some of our templates have irregular background colours (or images) and I really want to have a transparent editing area so that the experience is as close as possible to the end result.
If it's not apparent, this code creates a DIV whose borders cover the space that the editable DIV does not take up on the document. As the page resizes or the editable DIV changes size, these borders need to change size.
NOTE: The outer container may have overflow: hidden applied (thus the need to append the mask to the body element). The intention of the mask is to prevent clicking on any other area of the page other than the area that is being edited.
`var content_builder_element = $("#content_builder");
var mask = $('');
buildMask(content_builder_element, mask, false);
$('body').append(mask);
$(window).resize(function() {
buildMask(content_builder_element, mask, true);
});
window.setInterval(function() {
buildMask(content_builder_element, mask, true);
}, 100);
function buildMask(reference, mask, resize) {
var offset = reference.offset();
var height = reference.outerHeight(true);
var width = reference.outerWidth(true);
// We don't want the width of the masks to mess with the document width
if (resize) {
mask.css('borderRightWidth', 0);
mask.css('borderBottomWidth', 0);
}
var document_width = $(document).width();
var document_height = $(document).height();
mask.width(width);
mask.height(height);
mask.css('borderTopWidth', offset.top);
mask.css('borderRightWidth', document_width - offset.left - width);
mask.
I'd love to know if there is a more efficient way to do this. I've used a DIV position: fixed as a mask under the editable DIV but some of our templates have irregular background colours (or images) and I really want to have a transparent editing area so that the experience is as close as possible to the end result.
If it's not apparent, this code creates a DIV whose borders cover the space that the editable DIV does not take up on the document. As the page resizes or the editable DIV changes size, these borders need to change size.
NOTE: The outer container may have overflow: hidden applied (thus the need to append the mask to the body element). The intention of the mask is to prevent clicking on any other area of the page other than the area that is being edited.
`var content_builder_element = $("#content_builder");
var mask = $('');
buildMask(content_builder_element, mask, false);
$('body').append(mask);
$(window).resize(function() {
buildMask(content_builder_element, mask, true);
});
window.setInterval(function() {
buildMask(content_builder_element, mask, true);
}, 100);
function buildMask(reference, mask, resize) {
var offset = reference.offset();
var height = reference.outerHeight(true);
var width = reference.outerWidth(true);
// We don't want the width of the masks to mess with the document width
if (resize) {
mask.css('borderRightWidth', 0);
mask.css('borderBottomWidth', 0);
}
var document_width = $(document).width();
var document_height = $(document).height();
mask.width(width);
mask.height(height);
mask.css('borderTopWidth', offset.top);
mask.css('borderRightWidth', document_width - offset.left - width);
mask.
Solution
It is not entirely clear to me what the goal of that mask exactly is, but I guess you want to bring focus to your content div while editing it (correct me if I'm wrong, perhaps a simple demo would be nice to see what you want to achieve exactly)
If my assumption is correct, I would keep thing a lot simpler, and let css take care of things. This is by far the most performant solution I believe, since browser are obviously quite well optimized for applying css.
You could just apply a ridiculously large box shadow to your focus div, which will obscure the rest of the content, while keeping it's background in tact. No need to alter your DOM and check for resizes or anything. The css would look something like this:
I've set up a very simple demo to demonstrate (hit the edit button to see the effect, and edit the content to see how it reacts on resize)
If my assumption is correct, I would keep thing a lot simpler, and let css take care of things. This is by far the most performant solution I believe, since browser are obviously quite well optimized for applying css.
You could just apply a ridiculously large box shadow to your focus div, which will obscure the rest of the content, while keeping it's background in tact. No need to alter your DOM and check for resizes or anything. The css would look something like this:
div[contenteditable] {
box-shadow: 0 0 0 9999px rgba(0,0,0,.8);
}I've set up a very simple demo to demonstrate (hit the edit button to see the effect, and edit the content to see how it reacts on resize)
$('button').click(function() {
$('div').first().attr('contenteditable', true);
});
body {
background: red;
}
div[contenteditable] {
box-shadow: 0 0 0 9999px rgba(0,0,0,.8);
}
Test CMS
Lorem ipsum
Lorem ipsum
editCode Snippets
div[contenteditable] {
box-shadow: 0 0 0 9999px rgba(0,0,0,.8);
}Context
StackExchange Code Review Q#62769, answer score: 2
Revisions (0)
No revisions yet.