PHP DOM - 如何在特定位置插入元素?

时间:2014-02-27 10:24:18

标签: php html dom

简而言之,这就是我要做的事情:

  1. 从文档中获取所有<img>标记
  2. 设置data-src属性(延迟加载)
  3. 清空他们的来源(延迟加载)
  4. 在此图片后注入<noscript>标记
  5. 1-3很好。我无法将创建的<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技能非常生疏,所以我很感激任何澄清或建议。

    更新

    刚刚意识到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>
    

1 个答案:

答案 0 :(得分: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中运行此代码。之后有些钩子正在运行,这弄乱了我的标记。