将样式应用于DIV中的纯文本,而不会影响DIV的其他子项

时间:2010-08-29 07:55:15

标签: php css css-selectors

给定具有此一般结构的DIV(class =“post”,来自提取的留言板帖子)


<div class="post" id="1575524">
    I'm not sure why these items in the construction updates caught my eye, but they did...<br />
    <br />
    <div style="margin:20px; margin-top:5px; ">
        <div class="smallfont" style="margin-bottom:2px">Quote:</div>
        <table cellpadding="6" cellspacing="0" border="0" width="100%">
        <tr>
            <td class="alt2" style="border:1px inset">

                    Bay Lake Tower – bathroom modifications.

            </td>
        </tr>
        </table>
    </div>They're already having to do stuff to BLT?<br />
    <div style="margin:20px; margin-top:5px; ">
        <div class="smallfont" style="margin-bottom:2px">Quote:</div>
        <table cellpadding="6" cellspacing="0" border="0" width="100%">
        <tr>
            <td class="alt2" style="border:1px inset">

                    Caribbean Beach Resort – refurbish pool rules and spa rules signs at all pools. <br />
    All Star Resorts – refurbish pool rules and spa rules signs. 

            </td>
        </tr>
        </table>
    </div>I bet there are a lot of jurisdictions out there that would love to get building permit fees from this level of work.
</div>

我需要将CSS样式应用于“post”DIV的纯文本,而不触及其他子元素(Ps,表格,其他DIV等)。在收到之前,我无法改变“post”DIV的构建方式;我可以在收到它之后在必要时输出它之前对其进行更改。我正在使用PHP输出HTML。有一个链接的CSS样式表,如果需要可以采用其他样式。 “post”DIV中可能有任意数量的纯文本块需要进行样式化,以及任何数量的子元素都应该单独存在。

我一直在使用PHP的字符串处理函数(stripos,strripos,substr)。下面的代码确实在第一个子元素(“我不知道为什么这些项目......”)和最后一个(“我打赌有很多管辖权......”)之后成功地将普通纯文本包装在P中标签。问题是访问子元素之间的纯文本(“他们已经不得不......”)。


if ( stripos ( $postMessage, '<div' ) !== FALSE ) {
//  wrap text outside divs, if any
//  start of first div
  $divStartPos = stripos ( $postMessage, '<div' );
//  end of last div
  $divEndPos = strripos ( $postMessage, '/div>' ) + 4;
//  all up to start of first div + <p> tags
  if ( $divStartPos > 0 ) { 
    $textBeforeDiv = "<p class=\"postMessage\">". substr ( $postMessage, 0, $divStartPos -1 ) . "</p>\n";
  } // if
//  all between start of first and end of last div
  $div = substr ( $postMessage, $divStartPos, ($divEndPos - $divStartPos) + 1 );
//  all after end of last div + <p> tags
  $textAfterDiv = "<p class=\"postMessage\">". substr ( $postMessage, $divEndPos + 1, $postMessage->length - 1 ) . "</p>\n";
  $postMessage = $textBeforeDiv . $div . $textAfterDiv;
}   // if

在切换到字符串处理之前,我花了好几个小时敲击PHP的DOMDocument / DOMElement类,如果可能的话,我很乐意留在这里。在DIV的顶层访问纯文本的一些简单的编程方式是我真正需要的。如果存在这样的事情。

提前致谢。

3 个答案:

答案 0 :(得分:0)

如果您只能定位支持CSS3的浏览器(足以支持较新的选择器),那么您可以使用:not negation selector排除所有子项。

这样的事情应该有效:

div.post *:not(div)  
div.post *:not(table)  

:不是选择器没有很好的记录,它更多的试验和错误来自人们尝试它。见这里:http://kilianvalkhof.com/2008/css-xhtml/the-css3-not-selector/

但我认为最好的选择是以这样的方式设置CSS设置,以便明确定义每个子元素及其子元素的样式。这将确保您应用于父div的样式只会影响子项外的文本内容。

例如

div.post { font-family:tahoma }
div.post div { font-famile:arial }
div.post table { font-family:verdana }

答案 1 :(得分:0)

我会使用两个附加索引,startOfValidArea和endOf ...
该区域是您的文本和索引的位置,您应该在哪里放置<p...></p>标签或其他标签

那么你正在移动这些标签,如:
startof ..设置为根<div>的结尾并找到<之后的第一个场景,这是第一个区域
然后当你不在最后时,在提到<之后得到标记(就像<' '>之间的子串一样)并构造此临时结束标记(比如</xxx>),当然要注意里面有多个相同的标签(比如<table><table></table></table>
搜索此临时结束标记,它将是下一个startOf ...索引,再次搜索下一个<,这是第二个区域,依此类推。
希望它清晰易懂。
附:请注意<br />等标记,并检查<的每个开头是否存在此情况 它只是一个算法,我不用PHP编码,但它应该是类似的

编辑:代码,但我不确定它是否正常工作,我没有localserver来测试,希望它会有所帮助

$textStart = stripos($postMessage, '>')+1;            // startig index for the text to highlight
$textEnd = stripos($postMessage, '<', $textStartPos);     // ending index for the text to highlight

while($textStart != false && $textEnd != false){
    // while there is still any text to highlight

    // insert the highlighting code
    $postMessage = substr ($postMessage, 0, $textStart) . '<p class=\"postMessage\">' . substr ($postMessage, $textStart, $textEnd) . '</p>' . substr ($postMessage, $textEnd, strlen($postMessage);

    // get the tag
    $endOfTag = (stripos($postMessage, ' ', $textEnd) < stripos($postMessage, '>', $textEnd)) ? stripos($postMessage, ' ', $textEnd) : stripos($postMessage, '>', $textEnd);
    $tag = substr ($postMessage, $textEnd, $endOfTag); // getting the tag here

    if($tag == '<br' || $tag == '<img'){
        // do smthing with not-paired tag, like check if the tag is ending with the '/>' string and then ignore it and get the next tag
    }

    $closingTag = '</'.substr($tag,1,strlen($tag));           // creating the closing tag like </div or </p    
    $nextSameTag = stripos($postMessage, $tag, $endTag);
    $nextClosingTag = stripos($postMessage, $closingTag, $nextSameTag);

    // loop through the same inner tags like <div>text<div>text</div>text</div>
    while($nextSameTag < $nextClosingTag && $textStart != false && $textEnd != false){  
        $nextSameTag = stripos($postMessage, $tag, $nextClosingTag);
        $nextClosingTag = stripos($postMessage, $closingTag, $nextSameTag);
    }
    $textStart = stripos($postMessage, '>', $nextClosingTag)+1;
    $textEnd = stripos($postMessage, '<', $nextClosingTag);
}

答案 2 :(得分:0)

body {color:blue}    
div.post {color:red}
div.post * {color:blue}

至少在safari中起作用。 你为什么用PHP做这个?