在createElement()中克隆并插入节点

时间:2017-11-14 16:44:52

标签: php dom domdocument

我正在处理一些代码,这些代码会更改图片代码以支持延迟加载,我想在每张图片之前插入一个包含原始图像节点的<noscript>标记。

我卡在<noscript>标签内插入图片节点副本的部分。我是DomDocument的新手,所以我确定我一定做错了。如何克隆图像标记并将其插入到我创建的新<noscript>元素中?

function lazy_load_images($content) {
    if ($content) {
        $DOM = new DOMDocument();
        $DOM->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

        $images = $DOM->getElementsByTagName("img");

        foreach ($images as $image) {
            $existing_src    = $image->getAttribute("src");
            $existing_srcset = $image->getAttribute("srcset");

            // add noscript before images (here's where the hang-up is)
            $DOM->documentElement->insertBefore($DOM->createElement("noscript", $image->cloneNode(false)), $image->nextSibling);

            // change src to data-normal
            if ($existing_src) {
                $image->removeAttribute("src");
                $image->setAttribute("data-normal", $existing_src);
            }

            // change srcset to data-srcset
            if ($existing_srcset) {
                $image->removeAttribute("srcset");
                $image->setAttribute("data-srcset", $existing_srcset);
            }

            // add _js class
            $image->setAttribute("class", "_js {$image->getAttribute("class")}");
        }

        return $DOM->saveHTML();
    }
}

1 个答案:

答案 0 :(得分:2)

根据评论。 createElement具有名称和值的字符串参数,因此创建<noscript>节点并将克隆节点附加到该节点,然后插入它。

$noscript = $DOM->createElement("noscript");
$noscript->appendChild($image->cloneNode());
$image->parentNode->insertBefore($noscript, $image->nextSibling);

我注意到如果你使用$images = $DOM->getElementsByTagName("img");,循环似乎永远不会结束。如果您改用$images = $xp->query('//img');,它似乎可以正常工作。

$xp = new DOMXPath($DOM);

$images = $xp->query('//img');