检查元素是否具有相同的父代(JS)

时间:2020-06-05 09:48:44

标签: javascript

我正在使用一个将所有图像放入段落标签中的系统,例如:

<p>
  <img src="..." />
</p>

因此,我编写了一个将图像移出段落标签的函数。看起来像这样:

moveImagesOutOfPtags() {
  let images = document.querySelectorAll('p > img');

  Object.entries(images).forEach(entry => {
    let value = entry[1];

    if( value.parentNode.nodeName === 'P' || value.parentNode.nodeName === 'p' ){
      value.parentNode.outerHTML = value.parentNode.innerHTML;
    }
  });
}

但是,如果在同一个p标签中有两个图像,则这样是不起作用的:

<p>
  <img src="..." />
  <img src="..." />
</p>

...由于父级已被value.parentNode.outerHTML = ...行删除/重写/覆盖,因此对于第一张图像。因此,当它到达该p标签中的第二张图片时,就会引发错误:

无法在“元素”上设置“ outerHTML”属性:该元素没有父节点。

有什么建议可以解决此问题吗?

3 个答案:

答案 0 :(得分:1)

使用DOM操纵方法而不是像这样设置HTML字符串很容易实现:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="MyApp.Views.PageWithCustomView"
             xmlns:templates="clr-namespace:MyApp.Views.Templates"
             x:Name="MyContentPage"
             >
    <ContentPage.Content>
        <StackLayout>
            <templates:HeaderTemplate
                HeightRequest="60"
                TemplateImageSource="upload.png"
                TemplateTapCommand="{{Binding Path=BindingContext.NavigateToCommand, Source={x:Reference MyContentPage}}}" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
function moveImagesOutOfPtags() {
  let images = document.querySelectorAll('p > img');
  images.forEach(img => {
    const parent = img.parentElement;
    // Insert the image as a previous sibling to the paragraph
    parent.parentElement.insertBefore(img, parent);
    if (parent.children.length === 0) {
      // Remove the empty paragraph
      parent.remove();
    }
  });
}
moveImagesOutOfPtags();

您不必检查父级,因为查询将仅选择包装在段落中的图像,只需将图像作为父级的前一个兄弟插入即可。然后检查父级是否为空,并在需要时将其删除。

答案 1 :(得分:0)

为每个段落标签使用id,并使用当前的id检查先前修改的id。我认为这不是最好的方法,但这会让工作完成。

html内容

<p id = "p_id_1">
  <img src="..." />
  <img src="..." />
</p>
<p id = "p_id_2">
  <img src="..." />
  <img src="..." />
</p> 

脚本将是

moveImagesOutOfPtags() {
  let images = document.querySelectorAll('p > img');
  var p_id='';
  Object.entries(images).forEach(entry => {
    let value = entry[1];

    if(p_id != value.parentNode.id && (value.parentNode.nodeName === 'P' || value.parentNode.nodeName === 'p' )){
      value.parentNode.outerHTML = value.parentNode.innerHTML;
      p_id = value.parentNode.id;
    }
  });
}

答案 2 :(得分:0)

您可能只是捕获了错误而没有这样进行:

尝试一下:

moveImagesOutOfPtags() {
  document.querySelectorAll('p > img').forEach(entry => {
    const value = entry && entry[0]; // catches error if p has been replaced and doesn't continue.
    if(value){ // you don't have to test if parent is p tag, you've already determined that with your direct child selector p > img
      value.parentNode.outerHTML = value.parentNode.innerHTML;
    }
  });
}