هل هناك طريقة سهلة لتحويل HTML إلى علامات متعددة
في العلامات المناسبة المحيطة

في JavaScript؟

StackOverflow https://stackoverflow.com/questions/1275250

سؤال

دعنا نقول أن لدي حفنة من HTML مثل أدناه:

bla bla bla long paragraph here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>

هل هناك طريقة سهلة مع جافا سكريبت لتحويلها إلى الدلالية بشكل صحيح <p> العلامات؟ على سبيل المثال:

<p>
  bla bla bla long paragraph here
</p>
<p>
  bla bla bla more paragraph text
</p>

تباعد الإخراج غير مهم، من الناحية المثالية، ستعمل مع أي تباعد مدخلات.

أفكر أنني قد أحاول طهي ريجيكس، ولكن قبل أن أفعل ذلك أردت أن أتأكد من أنني كنت أ) تجنب عالم بالأذى و B) لم يكن هناك شيء آخر هناك - سأحاول القيام به بحث جوجل لكنه لم يتولى بعد أي شيء.

شكرا لأي نصيحة!

هل كانت مفيدة؟

المحلول

مللت. أنا متأكد من وجود تحسينات / القرص. يستخدم القليل من المسج للقيام بسحره. عملت في FF3. والإجابة على سؤالك هي أنه لا توجد طريقة "بسيطة" للغاية :)

$(function() {
  $.fn.pmaker = function() {
    var brs = 0;
    var nodes = [];

    function makeP()
    {
      // only bother doing this if we have nodes to stick into a P
      if (nodes.length) {
        var p = $("<p/>");
        p.insertBefore(nodes[0]);  // insert a new P before the content
        p.append(nodes); // add the children        
        nodes = [];
      }
      brs=0;
    }

    this.contents().each(function() {    
      if (this.nodeType == 3) // text node 
      {
        // if the text has non whitespace - reset the BR counter
        if (/\S+/.test(this.data)) {
          nodes.push(this);
          brs = 0;
        }
      } else if (this.nodeType == 1) {
        if (/br/i.test(this.tagName)) {
          if (++brs == 2) {
            $(this).remove(); // remove this BR from the dom
            $(nodes.pop()).remove(); // delete the previous BR from the array and the DOM
            makeP();
          } else {
            nodes.push(this);
          }
        } else if (/^(?:p)$/i.test(this.tagName)) {
          // these tags for the P break but dont scan within
          makeP();
        } else if (/^(?:div)$/i.test(this.tagName)) {
          // force a P break and scan within
          makeP();
          $(this).pmaker();
        } else {
          brs = 0; // some other tag - reset brs.
          nodes.push(this); // add the node 
          // specific nodes to not peek inside of - inline tags
          if (!(/^(?:b|i|strong|em|span|u)$/i.test(this.tagName))) {
            $(this).pmaker(); // peek inside for P needs            
          }
        } 
      } 
    });
    while ((brs--)>0) { // remove any extra BR's at the end
      $(nodes.pop()).remove();
    }
    makeP();
    return this;
  };

  // run it against something:
  $(function(){ 
    $("#worker").pmaker();
  });

وكان هذا جزء HTML الذي اختبرته ضد:

<div id="worker">
bla bla bla long <b>paragraph</b> here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>
this text should end up in a P
<div class='test'>
  and so should this
  <br/>
  <br/>
  and this<br/>without breaking at the single BR
</div>
and then we have the a "buggy" clause
<p>
  fear the real P!
</p>
and a trailing br<br/>
</div>

والنتيجة:

<div id="worker"><p>
bla bla bla long <b>paragraph</b> here
</p>
<p>
bla bla bla more paragraph text
</p>
<p>
this text should end up in a P
</p><div class="test"><p>
  and so should this
  </p>
  <p>
  and this<br/>without breaking at the single BR
</p></div><p>
and then we have the a "buggy" clause
</p><p>
  fear the real P!
</p><p>
and a trailing br</p>
</div>

نصائح أخرى

مسح كل عنصر من عناصر الطفل + نص العنصر المرفق. في كل مرة تواجه عنصر "BR"، قم بإنشاء عنصر "ع"، وإلحاق جميع الأشياء المعلقة به. رغوة الصابون تكرار شطف.

لا تنس إزالة الأشياء التي تنقلها إلى عنصر جديد "ع".

لقد وجدت هذه المكتبة (prototype.js) أن تكون مفيدة لهذا النوع من الأشياء.

أنا أفترض أنك لست تسمح حقا بأي شيء آخر تحتاج في بعض الأحيان للحفاظ على فترات راحة واحدة (وليس كلها <br /> العناصر سيئة)، وتريد فقط تحويل مثيلات مزدوجة <br /> في فواصل الفقرة.

في القيام بذلك، أود:

  1. إزالة جميع فواصل الأسطر
  2. لف الكثير في الفقرة
  3. يحل محل <br /><br /> مع </p>\n<p>
  4. أخيرا، قم بإزالة أي فارغة <p></p> العناصر التي ربما تم إنشاؤها

لذلك يمكن أن تبدو الكود شيئا مثل:

var ConvertToParagraphs = function(text) {
    var lineBreaksRemoved = text.replace(/\n/g, "");
    var wrappedInParagraphs = "<p>" + lineBreaksRemoved + "</p>";
    var brsRemoved = wrappedInParagraphs.replace(/<br[^>]*>[\s]*<br[^>]*>/gi, "</p>\n<p>");
    var emptyParagraphsRemoved = brsRemoved.replace(/<p><\/p>/g, "");
    return emptyParagraphsRemoved;
}

ملحوظة: لقد كنت مطولا للغاية لإظهار العمليات، وسوف تبسط ذلك بالطبع.

هذا يحول عينتك:

bla bla bla long paragraph here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>

داخل:

<p>bla bla bla long paragraph here</p>
<p>bla bla bla more paragraph text</p>

لكنه يفعل ذلك دون إزالة أي <br /> العناصر التي قد ترغب في الواقع.

سأفعل ذلك في عدة مراحل:

  1. Regexp: تحويل جميع العلامات BR إلى استراحات خط.
  2. Regexp: تجريد جميع المساحات البيضاء.
  3. Regexp: تحويل فواصل خط متعددة إلى تلك الوحيدة.
  4. استخدم Array.Split (' n') على النتيجة.

يجب أن يوفر مجموعة صفيفا مع جميع الفقرات "الحقيقية" (من الناحية النظرية)، ثم يمكنك التكرار من خلالها ولف كل سطر في علامات P.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top