มี jQuery ที่ไม่คำนึงถึงขนาดตัวพิมพ์: ประกอบด้วยตัวเลือกหรือไม่?


145

มีรุ่นที่ไม่ตรงตามตัวพิมพ์: ประกอบด้วยตัวเลือก jQuery หรือฉันควรทำงานด้วยตนเองโดยการวนลูปมากกว่าองค์ประกอบทั้งหมดและเปรียบเทียบ. text () กับสตริงของฉันหรือไม่


2
สำหรับ jQuery 8.1 + ตรวจสอบคำตอบ
Praveen

1
^ นั่นคือ 1.8.1 ไม่ใช่ 8.1
TylerH

ตัวอย่างที่ดีที่นี่
劉鎮瑲

คำตอบ:


125

สิ่งที่ฉันทำเพื่อ jQuery 1.2 คือ:

jQuery.extend(
    jQuery.expr[':'], { 
        Contains : "jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0" 
});

สิ่งนี้จะขยาย jquery ให้มี: ประกอบด้วย selector ที่ไม่คำนึงถึงขนาดตัวพิมพ์และ: contain selector ยังคงไม่เปลี่ยนแปลง

แก้ไข: สำหรับ jQuery 1.3 (ขอบคุณ @ user95227) และใหม่กว่าที่คุณต้องการ

jQuery.expr[':'].Contains = function(a,i,m){
     return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

แก้ไข: เห็นได้ชัดว่าเข้าถึง DOM โดยตรงโดยใช้

(a.textContent || a.innerText || "") 

แทน

jQuery(a).text()

ในนิพจน์ก่อนหน้านั้นเพิ่มความเร็วได้มากดังนั้นลองเสี่ยงเองถ้าความเร็วเป็นปัญหา (ดูคำถามของ@John )

แก้ไขล่าสุด: สำหรับ jQuery 1.8 ควรเป็น:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

เพียงแค่ต้องการให้ผู้คนรู้ว่าวิธีการแก้ปัญหาตามที่อธิบายโดย @Pat และอื่น ๆ สำหรับ jQuery 1.3 นั้นใช้งานได้สำหรับ 1.4.3
Jim Ade

ลิงก์ไปที่คำถาม / คำตอบของ @ John เนื่องจากลิงก์ที่นี่ถูกลบ: stackoverflow.com/questions/1407434/…
Mottie

สิ่งนี้ใช้ไม่ได้กับ jQuery 1.8 ดูคำตอบของ seagullJS ด้านล่างเพื่อรับการอัปเดต - stackoverflow.com/a/12113443/560114
Matt Browne

105

หากต้องการทำให้เป็นตัวพิมพ์เล็กหรือตัวพิมพ์เล็กก็ได้: http://bugs.jquery.com/ticket/278

$.extend($.expr[':'], {
  'containsi': function(elem, i, match, array)
  {
    return (elem.textContent || elem.innerText || '').toLowerCase()
    .indexOf((match[3] || "").toLowerCase()) >= 0;
  }
});

จากนั้นใช้:containsiแทน:contains


3
การเพิ่มฟังก์ชั่นใหม่ดีกว่าเขียนทับฉันตอนนี้ฉันใช้ตัวเลือกนี้ (ทำงานเหมือนมีเสน่ห์)
GôTô

22
ควรเพิ่มสิ่งนี้ลงในไลบรารี jquery มาตรฐาน
user482594

41

ตั้งแต่ jQuery 1.3 วิธีนี้เลิกใช้แล้ว หากต้องการให้สิ่งนี้ทำงานได้จะต้องกำหนดเป็นฟังก์ชัน:

jQuery.expr[':'].Contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

38

ถ้ามีคน (เช่นฉัน) มีความสนใจในสิ่งที่ทำและม. [3]ในหมายถึงมีความหมาย


KEY / LEGEND: params จัดทำโดย jQuery สำหรับใช้ในคำจำกัดความของตัวเลือก:

r = jQuery อาร์เรย์ขององค์ประกอบที่กำลังพิจารณา (เช่น: r.length = จำนวนองค์ประกอบ)

ฉัน = ดัชนีขององค์ประกอบในปัจจุบันภายใต้การตรวจสอบข้อเท็จจริงภายในอาร์เรย์R

= องค์ประกอบในปัจจุบันภายใต้การตรวจสอบข้อเท็จจริง คำสั่งตัวเลือกจะต้องส่งคืนจริงเพื่อรวมไว้ในผลลัพธ์ที่ตรงกัน

m [2] = nodeName หรือ * ที่เรามองหา (ด้านซ้ายของลำไส้ใหญ่)

m [3] = param ส่งผ่านไปยัง: selector (param) โดยปกติหมายเลขดัชนีในขณะที่: ที่ n ของประเภท (5)หรือสตริงในขณะที่สี (สีฟ้า)


31

ใน jQuery 1.8 คุณจะต้องใช้

jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {                                                                                                                                                                
    return function (elem) {                                                            
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;        
    };                                                                                  
});

2
ทำงานได้อย่างสมบูรณ์ขอบคุณ! เพิ่งอัปเดตเป็น 1.8 และสิ่งนี้หยุดทำงาน
Andreas

3
ขอบคุณสำหรับการอัพเดท เพิ่งอัปเดตเป็น JQuery 1.8 และหยุดทำงาน
Wasim

15

รูปแบบที่ดูเหมือนว่าจะทำงานได้เร็วขึ้นเล็กน้อยและยังอนุญาตให้มีการแสดงออกปกติคือ:

jQuery.extend (
    jQuery.expr[':'].containsCI = function (a, i, m) {
        //-- faster than jQuery(a).text()
        var sText   = (a.textContent || a.innerText || "");     
        var zRegExp = new RegExp (m[3], 'i');
        return zRegExp.test (sText);
    }
);



ไม่เพียง แต่ตรงตามตัวพิมพ์เล็กและใหญ่เท่านั้น แต่ยังช่วยให้การค้นหามีประสิทธิภาพเช่น:

  • $("p:containsCI('\\bup\\b')") (ตรงกับ "ขึ้น" หรือ "ขึ้น" แต่ไม่ใช่ "สูง", "ปลุก" ฯลฯ )
  • $("p:containsCI('(?:Red|Blue) state')") (ตรงกับ "สถานะสีแดง" หรือ "สถานะสีน้ำเงิน" แต่ไม่ใช่ "สถานะขึ้น" ฯลฯ )
  • $("p:containsCI('^\\s*Stocks?')") (ตรงกับ "หุ้น" หรือ "หุ้น" แต่เฉพาะที่จุดเริ่มต้นของย่อหน้า (ไม่สนใจช่องว่างนำหน้า))

11

อาจจะสาย .... แต่

ฉันชอบที่จะไปทางนี้ ..

$.extend($.expr[":"], {
"MyCaseInsensitiveContains": function(elem, i, match, array) {
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});

ด้วยวิธีนี้คุณจะไม่ยุ่งเกี่ยวกับ'.contain'. jQuery ของ' ... คุณอาจต้องใช้ค่าเริ่มต้นในภายหลัง ... หากดัดแปลงด้วยคุณอาจพบว่าตัวเองกลับไปที่stackOverFlow ...


6
jQuery.expr[':'].contains = function(a,i,m){
    return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

รหัสการอัปเดตนั้นใช้งานได้ดีใน 1.3 แต่ควรมีตัวพิมพ์เล็กในตัวอักษรตัวแรกซึ่งต่างจากตัวอย่างก่อนหน้า


1
ฉันคิดว่าเขาต้องการฟังก์ชั่นที่แตกต่างเพื่อให้ทั้งสอง:containsและ:Containsจะทำงานพร้อมกัน
joshperry

"ตัว: ประกอบด้วยตัวเลือกยังคงไม่เปลี่ยนแปลง"
แฮร์รี่ B

4

อ้างอิงด้านล่างเพื่อใช้ ": มี" เพื่อค้นหาข้อความที่ไม่สนใจขนาดตัวพิมพ์เล็กและใหญ่จากรหัส HTML

 $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function( elem ) {
                return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
            };
        });
        $("#searchTextBox").keypress(function() {
          if($("#searchTextBox").val().length > 0){
            $(".rows").css("display","none");
            var userSerarchField = $("#searchTextBox").val();
            $(".rows:contains('"+ userSerarchField +"')").css("display","block");
          } else {
            $(".rows").css("display","block");
          }              
        });

นอกจากนี้คุณยังสามารถใช้ลิงก์นี้เพื่อค้นหาโค้ดที่ไม่สนใจขนาดตัวพิมพ์ตามรุ่น jquery ของคุณ Make jQuery: มีตัวพิมพ์เล็กและตัวพิมพ์ใหญ่


2

เวอร์ชันที่เร็วกว่าโดยใช้นิพจน์ทั่วไป

$.expr[':'].icontains = function(el, i, m) { // checks for substring (case insensitive)
    var search = m[3];
    if (!search) return false;

    var pattern = new RegExp(search, 'i');
    return pattern.test($(el).text());
};

ยอดเยี่ยมมาก! ขอบคุณมาก. ฉันเชื่อว่านี่เป็นคำตอบที่ดีที่สุดและทันสมัยที่สุดสำหรับคำถามนี้
mavrosxristoforos

0

ฉันมีปัญหาคล้ายกันกับสิ่งต่อไปนี้ไม่ทำงาน ...

// This doesn't catch flac or Flac
$('div.story span.Quality:not(:contains("FLAC"))').css("background-color", 'yellow');

สิ่งนี้ใช้ได้และไม่จำเป็นต้องมีส่วนขยาย

$('div.story span.Quality:not([data*="flac"])').css("background-color", 'yellow');

วิธีนี้ใช้ได้เช่นกัน แต่อาจอยู่ในหมวดหมู่ "การวนซ้ำด้วยตนเอง" ...

$('div.story span.Quality').contents().filter(function()
{
  return !/flac/i.test(this.nodeValue);
}).parent().css("background-color", 'yellow');

0

ใหม่ตัวแปรฉันให้ชื่อ subString และใส่สตริงที่คุณต้องการค้นหาในข้อความองค์ประกอบบางอย่าง จากนั้นใช้ jQuery เลือกเลือกองค์ประกอบที่คุณต้องการเช่นตัวอย่างของฉันและกรองตาม$("elementsYouNeed") .filter()ใน.filter()มันจะเปรียบเทียบแต่ละองค์ประกอบใน$("elementsYouNeed")ด้วยฟังก์ชั่น

ในฟังก์ชั่น i ที่ใช้.toLowerCase()สำหรับข้อความองค์ประกอบนอกจากนี้ยังมี subString ที่สามารถหลีกเลี่ยงเงื่อนไขเล็ก ๆ น้อย ๆ และตรวจสอบว่ามี subString อยู่หรือไม่ หลังจากนั้น.filter()วิธีการสร้างวัตถุ jQuery ใหม่จากชุดย่อยขององค์ประกอบที่ตรงกัน

ตอนนี้คุณสามารถรับองค์ประกอบการแข่งขันใน matchObjects และทำสิ่งที่คุณต้องการ

var subString ="string you want to match".toLowerCase();

var matchObjects = $("elementsYouNeed").filter(function () {return $(this).text().toLowerCase().indexOf(subString) > -1;});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.