概述网页上的任何内容块

时间:2015-09-19 06:08:56

标签: javascript html css

目前,在我们正在构建的Web cms中,我们允许用户包含要在网站的任何部分显示的任何内容(无论是纯文本还是任何html内容)。这些块称为小部件(显然我们会采取措施清理它们以达到安全目的)。

我希望能够在必要时突出显示这些块以进行调试,但是我不能将它们包装在任何其他元素(例如div)中,因为它可能会破坏布局。我在这个网站上发现了几个问题,重新提出同样的问题,但还没有任何好的解决方案。

如果我们被允许使用某种非布局元素(例如注释标签)来包装内容以便能够执行某些操作(例如突出显示),那将是很好的,但我没有找到了办法。

我对任何解决方案(js,基于服务器等)感到满意,只要它允许我在不破坏布局的情况下概述任何内容块。如果您有任何建议,请告诉我。

小部件内容的一些示例:

仅文字小部件:

this is a the content of text only widget, there is also no wrapper here.

HTML小部件:

<h1>Hello world </h1>

<section class="content">
    The problem here is that we do not want to force the users to 
    always wrap their contents inside a root element.
    In this example you can see that the content contains 1 h1 element
    and 1 section element. To outline this whole widget we may need to 
    wrap it by an outer element which may break the layout.
</section>

2 个答案:

答案 0 :(得分:2)

这不完全是您想要的,但它可能足够接近(fiddle)。该脚本将使用<span class="highlight">包装小部件。跨度应该不会以任何方式影响布局:

.highlight {
    display: block; // this will change the layout as it inserts a line break
    outline: 1px dashed red;
}

渲染html时,在窗口小部件之前和之后添加注释:

<!--!!!start widget!!!-->
this is a the content of text only widget, there is also no wrapper here.
<!--!!!end widget!!!-->

当您转到调试模式时,请运行此脚本以添加突出显示范围:

var START_WIDGET = '!!!start widget!!!';
var END_WIDGET = '!!!end widget!!!';

function filter( node ) {
    if ( node.nodeValue !== START_WIDGET && node.nodeValue !== END_WIDGET) { // filter all comment nodes that are not start or end widget
        return( NodeFilter.FILTER_SKIP );
    }
    return( NodeFilter.FILTER_ACCEPT );
}

filter.acceptNode = filter;

var treeWalker = document.createTreeWalker(
    document.body,
    NodeFilter.SHOW_COMMENT,
    filter,
    false
);

var start = null;

while ( treeWalker.nextNode() ) {
    if(treeWalker.currentNode.nodeValue === START_WIDGET) {
         start = treeWalker.currentNode;
    } else if(treeWalker.currentNode.nodeValue === END_WIDGET) {
        highlight(start, treeWalker.currentNode);
        start = null;
    }
}

function highlight(start, end) {
    var currentNode = start.nextSibling;
    var span = document.createElement('span');
    var temp;

    span.className = 'highlight';

    while(currentNode !== end) {
        temp = currentNode;
        currentNode = currentNode.nextSibling;
        span.appendChild(temp);
    }

    $(span).insertAfter(start);
}

treeWalker代码基于这篇文章 - Finding HTML Comment Nodes In The DOM Using TreeWalker

答案 1 :(得分:1)

尝试样式属性outline。它与border类似,但它的大小不会影响布局。将您的小部件包装在<span>中,因为它们是内嵌元素,如果您不想破坏您的布局,这将使它们变得完美。除了使用outline<span>之外,您还可以使用默认值来实现平滑均匀的布局。

<强> CSS

&#13;
&#13;
/* DEFAULTS */

html {
  box-sizing: border-box;
  font: 400 16px/1.45'Source Code Pro';
}
*,
*:before,
*:after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
  border: 0 solid transparent;
}
/* WIDGETS */

.widget {
  outline: 3px dashed orange;
}
.widget.text {
  outline: 1px solid blue;
}
.widget.html {
  outline: 1px solid red;
}
.widget.html > .content {
  outline: 1px solid black;
  background: yellow;
}
&#13;
<span class="widget text">
this is a the content of text only widget, there is also no wrapper here.
</span>
<span class="widget html">
<h1>Hello world</h1>

<section class="content">
    The problem here is that we do not want to force the users to 
    always wrap their contents inside a root element.
    In this example you can see that the content contains 1 h1 element
    and 1 section element. To outline this whole widget we may need to 
    wrap it by an outer element which may break the layout.
</section>
  </span>
&#13;
&#13;
&#13;