2014-02-27 49 views
1

简单地说,这就是我想要做的事:PHP DOM - 如何在特定位置插入元素?

  1. 获取所有<img>标签从文档
  2. 设置一个data-src属性(延迟加载)
  3. 清空其源(懒装载)
  4. 这个图像

1-3是细后注入<noscript>标签。我无法正确地将创建的<noscript>标签放在图像旁边。

我与insertBefore努力,但我开放的建议:

// Create a DOMDocument instance 
$dom = new DOMDocument; 

$dom->formatOutput = true; 
$dom->preserveWhiteSpace = false; 

// Loads our content as HTML 
$dom->loadHTML($content); 

// Get all of our img tags 
$images = $dom->getElementsByTagName('img'); 

// How many of them 
$len = count($images); 

// Loop through all the images in this content 
for ($i = 0; $i < $len; $i++) { 

    // Reference this current image 
    $image = $images->item($i); 

    // Create our fallback image before changing this node 
    $fallback_image = $image->cloneNode(); 

    // Add the src as a data-src attribute instead 
    $image->setAttribute('data-src', $src); 

    // Empty the src of this img 
    $image->setAttribute('src', ''); 

    // Now prepare our <noscript> markup 
    // E.g <noscript><img src="foobar.jpg" /></noscript> 
    $noscript = $dom->createElement("noscript"); 
    $noscript->appendChild($fallback_image); 

    $image->parentNode->insertBefore($noscript, $image); 
} 

return $dom->saveHTML(); 

有在页面两个图像,这是(简称为清晰起见)结果:

之前:

<div> 
    <img /> 
    <p /> 
</div> 
<p> 
    <img /> 
</p> 

后:

<div> 
    <img /> <!-- this should be the fallback wrapped in <noscript> that is missing --> 
    <p> 
     <img /> 
    </p> 
</div> 
<p> 
    <img /> <!-- nothing happened here --> 
</p> 

使用$dom->appendChild工程,但<noscript>标记应位于图像旁边,而不是位于文档末尾。

我的PHP技巧非常生疏,所以我会很感激任何澄清或建议。

UPDATE

刚刚意识到saveHTML()也加入<DOCTYPE><html><body>标签,所以我添加了一个preg_replace(直到我找到一个更好的解决方案)采取移除的照顾。

此外,我之前粘贴的输出是基于Chrome开发人员工具的检查员。

我检查了viewsoure,看看究竟发生了什么(因此发现了有关标签)。

这是什么真正发生: https://eval.in/114620

<div> 
    <img /> </noscript> <!-- wha? just a closing noscript tag --> 
    <p /> 
</div> 
<p> 
    <img /> <!-- nothing happened here --> 
</p> 
+0

为什么你不使用[simplehtmldom](http://simplehtmldom.sourceforge.net/)类来解析dom ?????? – ops

+0

@yonessafari使用第三方库将是最后的手段 – MarcoBarbosa

+1

如果您想将''包装在'

回答

0

解决

所以这是我如何固定它: https://eval.in/117959

我认为这是一个工作的好主意新节点它们被插入到DOM中:

$noscript = $dom->createElement("noscript"); 
$noscriptnode = $image->parentNode->insertBefore($noscript, $image); 

// Only now work with noscript by adding it's contents etc... 

此外,当插入“insertBefore”时 - 最好保存它的引用。

$noscriptnode = $image->parentNode->insertBefore($noscript, $image); 

另一件事:我在Wordpress中运行这段代码。之后有些钩子正在运行,这正在搞乱我的标记。