Wiem, że to stary wątek (ale odpowiadać na to dlatego, że również szukamy rozwiązania tego problemu). Utworzyłem łatwą metodę zamiany zawartości za pomocą tylko jednej linii podczas jej używania. Aby lepiej zrozumieć tę metodę, dodałem także funkcje o nazwie kontekstowej.
To jest teraz część mojej biblioteki, więc to jest powodem wszystkich nazw funkcji tutaj, wszystkie funkcje zaczynają się od prefiksu "su".
Jest bardzo łatwy w użyciu i bardzo wydajny (a także zawiera mniej kodu).
Oto kod:
function suSetHtmlElementById(&$oDoc, &$s, $sId, $sHtml, $bAppend = false, $bInsert = false, $bAddToOuter = false)
{
if(suIsValidString($s) && suIsValidString($sId))
{
$bCreate = true;
if(is_object($oDoc))
{
if(!($oDoc instanceof DOMDocument))
{ return false; }
$bCreate = false;
}
if($bCreate)
{ $oDoc = new DOMDocument(); }
libxml_use_internal_errors(true);
$oDoc->loadHTML($s);
libxml_use_internal_errors(false);
$oNode = $oDoc->getElementById($sId);
if(is_object($oNode))
{
$bReplaceOuter = (!$bAppend && !$bInsert);
$sId = uniqid('SHEBI-');
$aId = array("<!-- $sId -->", "<!--$sId-->");
if($bReplaceOuter)
{
if(suIsValidString($sHtml))
{
$oNode->parentNode->replaceChild($oDoc->createComment($sId), $oNode);
$s = $oDoc->saveHtml();
$s = str_replace($aId, $sHtml, $oDoc->saveHtml());
}
else { $oNode->parentNode->removeChild($oNode);
$s = $oDoc->saveHtml();
}
return true;
}
$bReplaceInner = ($bAppend && $bInsert);
$sThis = null;
if(!$bReplaceInner)
{
$sThis = $oDoc->saveHTML($oNode);
$sThis = ($bInsert?$sHtml:'').($bAddToOuter?$sThis:(substr($sThis,strpos($sThis,'>')+1,-(strlen($oNode->nodeName)+3)))).($bAppend?$sHtml:'');
}
if(!$bReplaceInner && $bAddToOuter)
{
$oNode->parentNode->replaceChild($oDoc->createComment($sId), $oNode);
$sId = &$aId;
}
else { $oNode->nodeValue = $sId; }
$s = str_replace($sId, $bReplaceInner?$sHtml:$sThis, $oDoc->saveHtml());
return true;
}
}
return false;
}
// A function of my library used in the function above:
function suIsValidString(&$s, &$iLen = null, $minLen = null, $maxLen = null)
{
if(!is_string($s) || !isset($s{0}))
{ return false; }
if($iLen !== null)
{ $iLen = strlen($s); }
return (($minLen===null?true:($minLen > 0 && isset($s{$minLen-1}))) &&
$maxLen===null?true:($maxLen >= $minLen && !isset($s{$maxLen})));
}
Niektóre funkcje kontekstowe:
function suAppendHtmlById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, true, false); }
function suInsertHtmlById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, false, true); }
function suAddHtmlBeforeById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, false, true, true); }
function suAddHtmlAfterById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, true, false, true); }
function suSetHtmlById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, true, true); }
function suReplaceHtmlElementById(&$s, $sId, $sHtml, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, $sHtml, false, false); }
function suRemoveHtmlElementById(&$s, $sId, &$oDoc = null)
{ return suSetHtmlElementById($oDoc, $s, $sId, null, false, false); }
Jak go używać:
W poniższych przykładach zakładam, że istnieje już zawartość załadowana do zmiennej nazwała się $sMyHtml
, a zmienna $sMyNewContent
zawiera trochę nowego html. Zmienna $sMyHtml
zawiera element o nazwie/o identyfikatorze "example_id
".
// Example 1: Append new content to the innerHTML of an element (bottom of element):
if(suAppendHtmlById($sMyHtml, 'example_id', $sMyNewContent))
{ echo $sMyHtml; }
else { echo 'Element not found?'; }
// Example 2: Insert new content to the innerHTML of an element (top of element):
suInsertHtmlById($sMyHtml, 'example_id', $sMyNewContent);
// Example 3: Add new content ABOVE element:
suAddHtmlBeforeById($sMyHtml, 'example_id', $sMyNewContent);
// Example 3: Add new content BELOW/NEXT TO element:
suAddHtmlAfterById($sMyHtml, 'example_id', $sMyNewContent);
// Example 4: SET new innerHTML content of element:
suSetHtmlById($sMyHtml, 'example_id', $sMyNewContent);
// Example 5: Replace entire element with new content:
suReplaceHtmlElementById($sMyHtml, 'example_id', $sMyNewContent);
// Example 6: Remove entire element:
suSetHtmlElementById($sMyHtml, 'example_id');
@Greg, czy nie powinienem decydować, gdzie trafiają moje składki? A od kiedy mówiłeś o świecie? Postanowiłem przenieść mój wkład do mojego bloga po tym, jak część moich wkładów została usunięta ze StackOverflow i ukryta przed mną. Chciałbym zachować to w ten sposób, więc proszę, cofnij zmianę. – Keyvan
Link do potencjalnego rozwiązania jest zawsze mile widziany, ale proszę dodać kontekst wokół linku, aby inni użytkownicy mieli pojęcie, co to jest i dlaczego tam jest. Zawsze podawaj najważniejszą część ważnego linku, na wypadek, gdyby strona docelowa była nieosiągalna lub stała w trybie offline. Źródło: [* How to answer *] (http://stackoverflow.com/questions/how-to-answer) – Greg
@Greg, znam zasady. Wysłałem tutaj odpowiedź i przeniosłem ją na moją stronę ze względu na sposób, w jaki moje inne komentarze były przetwarzane na tej stronie - jak wspomniałem powyżej, zostały one usunięte i ukryte przede mną. To, czemu tak bardzo się sprzeciwiacie, jest poza mną. Pewne jedzenie do przemyślenia przez jednego z twórców tej strony http://www.codinghorror.com/blog/2009/08/are-you-a-digital-sharecropper.html "Czy Twoje uwagi mogą zostać odwołane, usunięte lub trwale? zrobione offline bez twojej zgody? " On Stackoverflow: tak. Na mojej własnej stronie: nie. – Keyvan