2014-02-27 70 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中運行這段代碼。之後有些鉤子正在運行,這正在搞亂我的標記。