5

所以我已经做了很长一段时间了,我得到的最好的是将图像包装在一个链接中,并在图像标签之后加上一个跨度:

<a href="">
  <img src="">
  <span></span>
</a>

但我想要的是:

<a href="">
  <span></span>
  <img src="">
</a>

我尝试了各种变体和位置

$img->parentNode->appendChild($dom->createElement('span'), $img);

以及在我的代码中的各种地方使用 insertBefore() ,我完全没有想法,因为我对 php DOM 的东西还很陌生。我的来源:

foreach($dom->getElementsByTagName('img') as $img)
{
$fancyHref = $dom->createElement('a');

                        $clone = $fancyHref->cloneNode();
                        $img->parentNode->replaceChild($clone, $img);
                        $clone->appendChild($img);  
                        $img->parentNode->appendChild($dom->createElement('span'));
};

更新: 澄清我的目标:我在 html 中有一个 img 标签。在它通过 php dom 之后,我希望将 img 标签包裹在一个带有 span 标签的 a 标签中,并在 image 标签之前:

<img src="" />

<a href="">
   <span class=""></span>
   <img src="" />
</a>

我目前执行此操作的代码(没有跨度)

foreach($dom->getElementsByTagName('img') as $img)
            {               
                $src = $img->getAttribute('src');
                $filename = substr(strrchr($src , '/') ,1); 
                $filename = preg_replace('/^[.]*/', '', $filename);
                $filename = explode('.', $filename); 
                $filename = $filename[0];

                if($this->imagesTitles[$this->currentLanguage][$filename] !== '')
                {
                    $img->setAttribute('title', $this->imagesTitles[$this->currentLanguage][$filename]);
                    $img->setAttribute('alt', $this->imagesTitles[$this->currentLanguage][$filename]);
                }
                else
                {
                    $img->removeAttribute('title');
                    $img->removeAttribute('alt');
                }

                $classes = explode(' ', $img->getAttribute('class'));
                if(!in_array('no-enlarge', $classes))
                {
                    $fancyHref = $dom->createElement('a');
                    $span = $dom->createElement('span');
                    $span->setAttribute('class', 'magnifier');
                    $fancyHref->setAttribute('class', 'enlarge');
                    $fancyHref->setAttribute('rel', 'enlarge');
                    $fancyHref->setAttribute('href', $img->getAttribute('src'));
                    if($img->getAttribute('title') !== '')
                    {
                        $fancyHref->setAttribute('title', $img->getAttribute('title'));
                        $fancyHref->setAttribute('alt', $img->getAttribute('title'));
                    }
                    $clone = $fancyHref->cloneNode();

                    $img->parentNode->replaceChild($clone, $img);   
                    $clone->appendChild($img);
                    $img->parentNode->insertBefore($span, $img);                        
                }

                $img->setAttribute('class', trim(str_replace('no-enlarge', '', $img->getAttribute('class'))));

                if($img->getAttribute('class') === '')
                {
                    $img->removeAttribute('class');
                }
            }
4

2 回答 2

1

您可以使用该DOMNode->insertBefore()方法(docs)。它有形式$parentNode->insertBefore( $nodeToBeInserted, $nodeToInsertBefore )。您的代码将是:

$img->parentNode->insertBefore( $dom->createElement('span'), $img );

DOMNode->appendChild()( docs ) 只有 1 个参数(插入的节点),并且该节点将始终插入到最后一个 childNode 之后。

编辑:

我现在已经测试了我的代码,如果你$img->parentNode->appendChild($dom->createElement('span'));在测试用例中用我的行替换,它最终会得到正确的格式。但是,您正在以一种非常混乱的方式操作元素。除此之外,如果我测试你更新的代码,我要么得到你想要的格式,要么根本没有 span 元素......

您要替换的元素是图像,因为它是文档中最初存在的唯一元素。因此,您应该克隆 -that- 元素。虽然您当前的代码消除了层次结构错误,但您正在复制所有更改的代码,而不仅仅是冲突的元素,这是对内存和时间的浪费。当您复制冲突元素时,这很容易。您可以按照您希望它们出现的顺序将元素附加到您的 a 中。附加图像时,请改为附加克隆。不要操纵$img. 如果您需要操纵图像,则必须改为操纵克隆。然后你只需用$img你操作的元素替换($fancyHref在你的情况下)。

$html = '<img src="">';
$dom = new DOMDocument();
$dom->loadHTML($html);

foreach($dom->getElementsByTagName('img') as $img) {
  $fancyHref = $dom->createElement('a');
  $clone = $img->cloneNode();
  $span = $dom->createElement( 'span' );
  #... do whatever you need to do to this span, the clone and the a element ...

  #... when you are done, you can simply append all elements you have been manipulating ...
  $fancyHref->appendChild( $span );
  $fancyHref->appendChild( $clone );

  $img->parentNode->replaceChild( $fancyHref, $img );
};

echo $dom->saveHTML();
于 2013-08-31T12:36:55.930 回答
0

嗯。我知道这可能不会归类为答案,但你不是已经有了它吗?我的意思是..我试过你的代码:

$dom = new DOMDocument;
$dom->loadHTMLFile("data.html");

foreach($dom->getElementsByTagName('img') as $img){
    $src = $img->getAttribute('src');

    $filename = substr(strrchr($src , '/') ,1);
    $filename = preg_replace('/^[.]*/', '', $filename);
    $filename = explode('.', $filename);
    $filename = $filename[0];

    $classes = explode(' ', $img->getAttribute('class'));

    if(!in_array('no-enlarge', $classes))
    {
        $fancyHref = $dom->createElement('a');
        $span = $dom->createElement('span');
        $span->setAttribute('class', 'magnifier');
        $fancyHref->setAttribute('class', 'enlarge');
        $fancyHref->setAttribute('rel', 'enlarge');
        $fancyHref->setAttribute('href', $img->getAttribute('src'));
        if($img->getAttribute('title') !== '')
        {
            $fancyHref->setAttribute('title', $img->getAttribute('title'));
            $fancyHref->setAttribute('alt', $img->getAttribute('title'));
        }
        $clone = $fancyHref->cloneNode();

        $img->parentNode->replaceChild($clone, $img);
        $clone->appendChild($img);
        $img->parentNode->insertBefore($span, $img);
    }

    $img->setAttribute('class', trim(str_replace('no-enlarge', '', $img->getAttribute('class'))));

    if($img->getAttribute('class') === ''){
        $img->removeAttribute('class');
    }
}

echo "<pre>" . htmlentities($dom->saveHTML()) . "</pre>";

以此(data.html)作为源数据:

<!doctype html>
<html>
    <head>
    </head>
    <body>
        <img src="http://lorempixel.com/g/400/200/" alt="alts" title="tits">
    </body>
</html>

结果是这样的:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <a class="enlarge" rel="enlarge" href="http://lorempixel.com/g/400/200/" title="tits" alt="tits">
            <span class="magnifier">
            </span>
            <img src="http://lorempixel.com/g/400/200/" alt="alts" title="tits"></a>
    </body>
</html>

所以..这不是你想要的吗?:D

于 2013-09-02T22:35:41.223 回答