草庐IT

PHP dom 在链接中包装图片并在图片标签前添加 span

coder 2024-04-08 原文

所以我已经这样做了很长一段时间,我得到的最好的结果是将图像包装在一个链接中,并在图像标签后加上一个跨度:

<a href="">
  <img src="">
  <span></span>
</a>

但我想要的是:

<a href="">
  <span></span>
  <img src="">
</a>

我尝试了各种变体和位置

$img->parentNode->appendChild($dom->createElement('span'), $img);

以及在我的代码中的各种地方使用 insertBefore() 并且我完全没有想法,因为我对 php DOM 东西还很陌生。我的来源:

foreach($dom->getElementsByTagName('img') as $img)
{
$fancyHref = $dom->createElement('a');

                        $clone = $fancyHref->cloneNode();
                        $img->parentNode->replaceChild($clone, $img);
                        $clone->appendChild($img);  
                        $img->parentNode->appendChild($dom->createElement('span'));
};

更新: 为了阐明我的目标:我在 html 中有一个 img 标签。在它通过 php dom 之后,我希望将 img 标签包裹在一个带有 span 标签的标签中,该标签位于图像标签之前:

之前

<img src="" />

之后

<a href="">
   <span class=""></span>
   <img src="" />
</a>

我目前执行此操作的代码(没有跨度)

foreach($dom->getElementsByTagName('img') as $img)
            {               
                $src = $img->getAttribute('src');
                $filename = substr(strrchr($src , '/') ,1); 
                $filename = preg_replace('/^[.]*/', '', $filename);
                $filename = explode('.', $filename); 
                $filename = $filename[0];

                if($this->imagesTitles[$this->currentLanguage][$filename] !== '')
                {
                    $img->setAttribute('title', $this->imagesTitles[$this->currentLanguage][$filename]);
                    $img->setAttribute('alt', $this->imagesTitles[$this->currentLanguage][$filename]);
                }
                else
                {
                    $img->removeAttribute('title');
                    $img->removeAttribute('alt');
                }

                $classes = explode(' ', $img->getAttribute('class'));
                if(!in_array('no-enlarge', $classes))
                {
                    $fancyHref = $dom->createElement('a');
                    $span = $dom->createElement('span');
                    $span->setAttribute('class', 'magnifier');
                    $fancyHref->setAttribute('class', 'enlarge');
                    $fancyHref->setAttribute('rel', 'enlarge');
                    $fancyHref->setAttribute('href', $img->getAttribute('src'));
                    if($img->getAttribute('title') !== '')
                    {
                        $fancyHref->setAttribute('title', $img->getAttribute('title'));
                        $fancyHref->setAttribute('alt', $img->getAttribute('title'));
                    }
                    $clone = $fancyHref->cloneNode();

                    $img->parentNode->replaceChild($clone, $img);   
                    $clone->appendChild($img);
                    $img->parentNode->insertBefore($span, $img);                        
                }

                $img->setAttribute('class', trim(str_replace('no-enlarge', '', $img->getAttribute('class'))));

                if($img->getAttribute('class') === '')
                {
                    $img->removeAttribute('class');
                }
            }

最佳答案

您可以使用 DOMNode->insertBefore() 方法 ( docs )。它的形式为 $parentNode->insertBefore( $nodeToBeInserted, $nodeToInsertBefore )。您的代码将是:

$img->parentNode->insertBefore( $dom->createElement('span'), $img );

DOMNode->appendChild() ( docs ) 只有 1 个参数(插入的节点),并且该节点将始终插入到最后一个 childNode 之后。

编辑:

我现在已经测试了我的代码,如果您在测试中用我的行替换 $img->parentNode->appendChild($dom->createElement('span'));在这种情况下,它将以正确的格式结束。但是,您正在以一种非常困惑的方式操纵元素。除此之外,如果我测试你更新后的代码,我要么以你想要的格式结束,要么根本没有 span 元素......

您要替换的元素是图像,因为它是文档中最初存在的唯一元素。因此,您应该克隆那个元素。虽然您当前的代码消除了层次结构错误,但您正在复制所有更改的代码,而不仅仅是冲突的元素,这是浪费内存和时间。当您复制冲突元素时,这很容易。您按照希望它们出现的顺序将元素附加到您的 a 中。当您附加图像时,请改为附加克隆。不要操纵 $img。如果您需要操纵图像,则必须操纵克隆。然后,您只需将 $img 替换为您操作的元素(在您的情况下为 $fancyHref)。

$html = '<img src="">';
$dom = new DOMDocument();
$dom->loadHTML($html);

foreach($dom->getElementsByTagName('img') as $img) {
  $fancyHref = $dom->createElement('a');
  $clone = $img->cloneNode();
  $span = $dom->createElement( 'span' );
  #... do whatever you need to do to this span, the clone and the a element ...

  #... when you are done, you can simply append all elements you have been manipulating ...
  $fancyHref->appendChild( $span );
  $fancyHref->appendChild( $clone );

  $img->parentNode->replaceChild( $fancyHref, $img );
};

echo $dom->saveHTML();

关于PHP dom 在链接中包装图片并在图片标签前添加 span,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18316527/

有关PHP dom 在链接中包装图片并在图片标签前添加 span的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  3. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  4. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  5. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  6. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  7. ruby - 可以通过多少种方法将方法添加到 ruby​​ 对象? - 2

    当谈到运行时自省(introspection)和动态代码生成时,我认为ruby​​没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby​​的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资

  8. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  9. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  10. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

随机推荐