jquery innerhtml - باستخدام.text()لاسترداد النص فقط غير متداخل في العلامات التابعة




append tags (19)

إذا كان لدي أتش تي أم أل مثل هذا:

<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

أحاول استخدام .text() لاسترداد السلسلة فقط "هذا هو بعض النص" ، ولكن إذا كان لي أن أقول $('#list-item').text() ، أحصل على "This is some textFirst span textSecond span text ".

هل هناك طريقة للحصول على (وربما إزالة ، عبر شيء مثل .text("") ) فقط النص الحر داخل علامة ، وليس النص داخل علامات الطفل؟

لم يتم كتابة HTML من قبل لي ، لذلك هذا هو ما يجب أن أعمل معه. وأنا أعلم أنه سيكون من السهل مجرد التفاف النص في العلامات عند كتابة أتش تي أم أل ، ولكن مرة أخرى ، يتم كتابة أتش تي أم أل مسبقا.


Answers

$($('#listItem').contents()[0]).text()

البديل القصير لإجابة ستيوارت.

أو مع get()

$($('#listItem').contents().get(0)).text()

تمامًا مثل السؤال ، كنت أحاول استخلاص النص من أجل إجراء بعض التعديلات على النص ، لكنني كنت أتلقى بعض المشاكل حيث كانت عناصر داخليتي (أي: <i> ، <div> ، <span> ، إلخ) إزالة.

يبدو أن التعليمة البرمجية التالية تعمل بشكل جيد وتحل جميع مشاكلي.

ويستخدم بعض الإجابات المقدمة هنا ولكن على وجه الخصوص ، لن يؤدي إلا إلى استبدال النص عندما يكون العنصر هو nodeType === 3 .

$(el).contents().each(function() { 
  console.log(" > Content: %s [%s]", this, (this.nodeType === 3));

  if (this.nodeType === 3) {
    var text = this.textContent;
    console.log(" > Old   : '%s'", text);

    regex = new RegExp("\\[\\[" + rule + "\\.val\\]\\]", "g");
    text = text.replace(regex, value);

    regex = new RegExp("\\[\\[" + rule + "\\.act\\]\\]", "g");
    text = text.replace(regex, actual);

    console.log(" > New   : '%s'", text);
    this.textContent = text;
  }
});

ما يحدث أعلاه هو حلقة عبر جميع عناصر el المعطى (الذي تم الحصول عليه ببساطة بـ $("div.my-class[name='some-name']"); عنصر داخلي ، فإنه يتجاهلها بشكل أساسي لكل جزء من النص (كما هو محدد في if (this.nodeType === 3) ) فإنه سيتم تطبيق استبدال regex فقط على هذه العناصر.

إن this.textContent = text ببساطة يحل محل النص المستبدل ، والذي في حالتي ، كنت أبحث عن رموز مثل [[min.val]] ، [[max.val]] ، إلخ.

سيساعد مقتطف الرمز القصير هذا أي شخص يحاول القيام بما يطرحه السؤال ... وأكثر قليلاً.


فقط ضعه في <p> أو <font> واستخرج هذا $ ('# listItem font'). text ()

أول شيء خطر في بالي

<li id="listItem">
    <font>This is some text</font>
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

إجابة بسيطة:

$("#listItem").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0].nodeValue = "The text you want to replace with" 

jQuery.fn.ownText = function () {
    return $(this).contents().filter(function () {
        return this.nodeType === Node.TEXT_NODE;
    }).text();
};

أكثر سهولة وسرعة:

$("#listItem").contents().get(0).nodeValue

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

document.getElementById("listItem").childNodes[0];

ستحتاج إلى تقليص ذلك ، لكنه سيحصل على ما تريد في سطر واحد سهل.

تصحيح

ما ورد أعلاه سوف تحصل على عقدة النص . للحصول على النص الفعلي ، استخدم هذا:

document.getElementById("listItem").childNodes[0].nodeValue;

هذا سؤال قديم لكن الإجابة العليا غير فعالة. وإليك حلًا أفضل:

$.fn.myText = function() {
    var str = '';

    this.contents().each(function() {
        if (this.nodeType == 3) {
            str += this.textContent || this.innerText || '';
        }
    });

    return str;
};

وفعل هذا:

$("#foo").myText();

استخدم شرطًا إضافيًا للتحقق مما إذا كان innerHTML و innerText هما نفس الشيء. فقط في تلك الحالات ، استبدل النص.

$(function() {
$('body *').each(function () {
    console.log($(this).html());
    console.log($(this).text());
    if($(this).text() === "Search" && $(this).html()===$(this).text())  {
        $(this).html("Find");
    }
})
})

http://jsfiddle.net/7RSGh/


توصلت إلى حل محدد يجب أن يكون أكثر فاعلية من استنساخ وتعديل الاستنساخ. لا يعمل هذا الحل إلا مع التحفظين التاليين ، ولكن يجب أن يكون أكثر كفاءة من الحل المقبولة حاليًا:

  1. أنت تحصل على النص فقط
  2. النص الذي تريد استخراجه هو قبل العناصر التابعة

مع ذلك ، هنا هو الرمز:

// 'element' is a jQuery element
function getText(element) {
  var text = element.text();
  var childLength = element.children().text().length;
  return text.slice(0, text.length - childLength);
}

أنا لست خبيرة مسجِّلة ، لكن ماذا عن

$('#listItem').children().first().text()

هذه طريقة جيدة بالنسبة لي

   var text  =  $('#listItem').clone().children().remove().end().text();

على غرار الإجابة المقبولة ، ولكن دون الاستنساخ:

$("#foo").contents().not($("#foo").children()).text();

وهنا ملحق jQuery لهذا الغرض:

$.fn.immediateText = function() {
    return this.contents().not(this.children()).text();
};

إليك كيفية استخدام هذا المكون الإضافي:

$("#foo").immediateText(); // get the text without children

أفترض أن هذا سيكون حلاً جيدًا أيضًا - إذا كنت تريد الحصول على محتويات جميع العقد النصية التي تمثل أطفالًا مباشرين للعنصر المحدد.

$(selector).contents().filter(function(){ return this.nodeType == 3; }).text();

ملاحظة: يستخدم توثيق jQuery تعليمات برمجية مشابهة لشرح وظيفة المحتويات: https://api.jquery.com/contents/

PS هناك أيضا طريقة أكثر قبيحة للقيام بذلك ، ولكن هذا يظهر بشكل أكثر عمقا كيف تعمل الأشياء ، ويسمح للفاصل بين العقد المخصصة (ربما تريد كسر خط هناك)

$(selector).contents().filter(function(){ return this.nodeType == 3; }).map(function() { return this.nodeValue; }).toArray().join("");

أقترح استخدام createTreeWalker للعثور على جميع عناصر النصوص غير المتصلة بعناصر html (يمكن استخدام هذه الوظيفة لتوسيع jQuery):

function textNodesOnlyUnder(el) {
  var resultSet = [];
  var n = null;
  var treeWalker  = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, function (node) {
    if (node.parentNode.id == el.id && node.textContent.trim().length != 0) {
      return NodeFilter.FILTER_ACCEPT;
    }
    return NodeFilter.FILTER_SKIP;
  }, false);
  while (n = treeWalker.nextNode()) {
    resultSet.push(n);
  }
  return resultSet;
}



window.onload = function() {
  var ele = document.getElementById('listItem');
  var textNodesOnly = textNodesOnlyUnder(ele);
  var resultingText = textNodesOnly.map(function(val, index, arr) {
    return 'Text element N. ' + index + ' --> ' + val.textContent.trim();
  }).join('\n');
  document.getElementById('txtArea').value = resultingText;
}
<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>
<textarea id="txtArea" style="width: 400px;height: 200px;"></textarea>


أعجبني هذا التنفيذ القابل لإعادة الاستخدام استنادًا إلى طريقة clone() الموجودة here للحصول على النص داخل العنصر الرئيسي فقط.

رمز المقدمة لسهولة الرجوع إليها:

$("#foo")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .text();

ليس الرمز:

var text  =  $('#listItem').clone().children().remove().end().text();

مجرد أن تصبح jQuery من أجل jQuery؟ عندما تنطوي العمليات البسيطة على العديد من الأوامر المتسلسلة والكثير من المعالجة (غير الضرورية) ، ربما حان الوقت لكتابة ملحق jQuery:

(function ($) {
    function elementText(el, separator) {
        var textContents = [];
        for(var chld = el.firstChild; chld; chld = chld.nextSibling) {
            if (chld.nodeType == 3) { 
                textContents.push(chld.nodeValue);
            }
        }
        return textContents.join(separator);
    }
    $.fn.textNotChild = function(elementSeparator, nodeSeparator) {
    if (arguments.length<2){nodeSeparator="";}
    if (arguments.length<1){elementSeparator="";}
        return $.map(this, function(el){
            return elementText(el,nodeSeparator);
        }).join(elementSeparator);
    }
} (jQuery));

للإتصال:

var text = $('#listItem').textNotChild();

تكون الحجج في حالة مواجهة سيناريو مختلف ، مثل

<li>some text<a>more text</a>again more</li>
<li>second text<a>more text</a>again more</li>

var text = $("li").textNotChild(".....","<break>");

سيكون للنص قيمة:

some text<break>again more.....second text<break>again more

جرب هذا:

$('#listItem').not($('#listItem').children()).text()

بترتيب النشاط ، تتوفر العروض التوضيحية / الأمثلة ، والبساطة:

ذات صلة:





jquery text tags