简体   繁体   English

如何提取 <ul> 从一个 <p> 标签(使用jQuery)?

[英]How to extract an <ul> from a <p> tag (with jQuery)?

I'm playing around with some contenteditable div's and after a while I'm getting the following code: 我正在使用一些可编辑的div,过了一会儿我得到了以下代码:

<p>
some text
<ul>
  <li>A</li>
  <li>2</li>
</ul>
another text
</p>

Now I'd like to get valid HTML. 现在,我想获取有效的HTML。 So I have to extract the ul from the p or in other words close the p tag before the ul and open it again after the ul . 所以我要提取ulp或者换句话说关闭p的标记之前ul和后再次打开它ul Afterwards my code should like like this: 之后,我的代码应如下所示:

<p>some text</p>
<ul>
  <li>A</li>
  <li>2</li>
</ul>
<p>another text</p>

How can I achieve this (with jQuery)? 我如何实现这一点(使用jQuery)?

I already tried this (where elem is the jQuery element containing p): 我已经尝试过了(其中elem是包含p的jQuery元素):

var reg1 = new RegExp('<ul>', 'g');
var reg2 = new RegExp('</ul>', 'g')
elem.html(elem.html().replace(reg1, '</p><ul>').replace(reg2, '</ul><p>'));

This seems to work. 这似乎有效。 But I'm not sure whether this is the best solution. 但是我不确定这是否是最佳解决方案。 Do you have a better idea? 你有更好的主意吗?

You're looking for before / after . 您正在寻找之前 / 之后

DO NOT USE REGEX FOR THIS. 请勿为此使用正则表达式。

Regex is for specialized cases where you need to target a specific set of text for a purpose that most of the time can be avoided in jQuery / Javascript. 正则表达式适用于特殊情况,您需要以一组特定的文本为目标,从而可以在大多数情况下避免使用jQuery / Javascript。

If you just do 如果你只是做

var ul = $('p').find('ul');
ul.closest('p').before(ul);

 $(document).on('ready', function(){ var ul = $('div').find('ul'); ul.closest('div').addClass('red').before(ul); }); 
 .red{ color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <span>some text</span> <ul> <li>List</li> </ul> <span>and more text</span> </div> 

It should be noted that it is illegal to use a ul or a ol tag inside of a p tag. 应当注意,在p标签内使用ulol标签是非法的。 Because of this I changed the p to a div to demonstrate. 因此,我将p更改为div进行演示。 Most browsers should not mess up if you use a p instead of a div with this code. 如果您使用p而不是div使用此代码,则大多数浏览器都不会混乱。

see Should ol/ul be inside <p> or outside? 请参阅ol / ul应该在<p>内部还是外部?

What's happening 发生了什么

The invalid HTML is parsed into a valid DOM by the browser, possibly adding closing tags where necessary. 浏览器会将无效的HTML解析为有效的DOM,并可能在必要时添加结束标记。 In Chrome I see: 在Chrome浏览器中,我看到:

<p>
  before
  <ul>
    <li>item></li>
  </ul>
  after
</p>

appear in the DOM inspector as 在DOM检查器中显示为

<p>
  before
</p>
<ul>
  <li>item></li>
</ul>
after
<p></p>

The solution 解决方案

So, assuming you have the unparsed HTML somewhere in a string, you can use the following (modified) regexes for a tighter match. 因此,假设您在字符串的某处有未解析的 HTML,则可以使用以下(已修改的)正则表达式进行更紧密的匹配。 It might be overkill though. 不过,这可能是过大的。

var beginRegex = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ul>/gi);
var endRegex = new RegExp(/<\/ul>(((?!<p>).|[\r\n])*?)<\/p>/gi);

var content = ...;

$('#target')
    .html(content
        .replace(beginRegex, '<p>$1</p><ul>')
        .replace(endRegex, '</ul><p>$1</p>')
    );

JSFiddle 的jsfiddle

It matches only unclosed <p> tags before <ul> and likewise for afterwards. 它仅匹配<ul>之前未关闭的<p>标签,之后也是如此。 One thing you can take away without using the complicated regex is to use the i modifier for case insensitive , since HTML is case insensitive. 您无需使用复杂的正则表达式就可以使用的一件事是对大小写不敏感使用i修饰符,因为HTML不区分大小写。

Thank to Shadowen I finally took his suggestion and modified it a little bit to get what I need. 感谢Shadowen,我终于接受了他的建议,并对其进行了一些修改,以得到我所需要的。 What I forgot to ask in my origin question - this should work for and also for lists. 我在原籍问题中忘记提出的问题-这应该适用于清单。 So this is the solution that works for me: 所以这是适合我的解决方案:

var content = '...';
var beginRegexUl = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ul>/gi);
var endRegexUl = new RegExp(/<\/ul>(((?!<p>).|[\r\n])*?)<\/p>/gi);
var beginRegexOl = new RegExp(/<p>(((?!<\/p>).|[\r\n])*?)<ol>/gi);
var endRegexOl = new RegExp(/<\/ol>(((?!<p>).|[\r\n])*?)<\/p>/gi);

$('#target')
  .html(content
    .replace(beginRegexUl, '<p>$1</p><ul>')
    .replace(endRegexUl, '</ul><p>$1</p>')
    .replace(beginRegexOl, '<p>$1</p><ol>')
    .replace(endRegexOl, '</ol><p>$1</p>'));

JSFiddle 的jsfiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM