İndexOf neden bir dizi IE8 üzerinde çalışmıyor?


294

Aşağıdaki işlev Opera, Firefox ve Chrome'da iyi çalışır. Ancak IE8'de bu if ( allowed.indexOf(ext[1]) == -1)parça başarısız oluyor .

Nedenini bilen var mı? Bariz bir hata var mı?

function CheckMe() {
    var allowed = new Array('docx','xls','xlsx', 'mp3', 'mp4', '3gp', 'sis', 'sisx', 'mp3', 'wav', 'mid', 'amr', 'jpg', 'gif', 'png', 'jpeg', 'txt', 'pdf', 'doc', 'rtf', 'thm', 'rar', 'zip', 'htm', 'html', 'css', 'swf', 'jar', 'nth', 'aac', 'cab', 'wgz');
    var fileinput=document.getElementById('f');
    var ext = fileinput.value.toLowerCase().split('.');
    if ( allowed.indexOf(ext[1]) == -1) 
    {
        document.getElementById('uploadsec').innerHTML = document.getElementById('uploadsec').innerHTML;
        alert('This file type is not allowed!');
    }
}

5
Harika soru, harika cevap. Bana tam olarak ihtiyacım olanı verdiğiniz için teşekkürler.
Hardwareguy

Yanıtlar:


488

IE9 öncesi IE sürümleri, .indexOf()Array için tam bir işlev sürümünü tanımlamak için bir işleve sahip değildir, bunu kullanmaya çalışmadan önce bunu çalıştırın:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Bu sürümüdür MDN Firefox / SpiderMonkey kullanılan. IE gibi diğer durumlarda, .indexOf()eksik olması durumunda ekleyecektir ... temelde IE8 veya aşağı bu noktada.


2
Siz (veya kullandığınız kütüphaneler) dizileri numaralandırmak için for / in sözdizimini (örn. (Arrayname'de idx) stmt;) kullanmanın bu yöntemin de numaralandırılacağını unutmayın. Bunun nedeni, yerleşik özelliklerin for / in tarafından numaralandırılmadığı, ancak kullanıcı tanımlı olanların sayılmasıdır.
İspanya Tren

5
@Mike - Bu farklı bir sorun ... bir diziyi yinelemek için bir for...indöngü kullanmamalısınız , yalnızca numaralandırma için kullanılmalıdır .
Nick Craver

3
@Mike - Bunun için daha fazla nedenden ötürü bir dizi üzerinden yineliyorsunuz ... sonuçlarınızı tarayıcılarda doğru sırada almanız gibi. for..inBir dizide kullanmak sadece sorunlara neden olur, bu sadece bir kongre değildir ... istenmeyen kullanımı ve yanlış bir konudur. Sipariş ve anahtarların her ikisi de tam olarak belirtilmez, uygulamaya bağlıdır ... örneğin IE , dizi öğelerini dizinlerine göre eklendikleri sırayla numaralandırır . Ancak dizine erişerek doğru şekilde yineleyebilirsiniz .
Nick Craver

1
Ve bu, öğeleri numaralandırmak ve yinelemek için bir dizin kullanmak arasındaki farkı gösterir. Bu yüzden her iki kavramımız da var. Bağlantılı bir listedeki değerleri numaralandırabilir veya bağlantılı listeyi tarayabilir ve değerleri birinden diğerine döndürebilirsiniz. Biri matematiksel bir kavram, diğeri yordamsal bir talimattır.
jcolebrand

1
@Pointy Evet! Ve birçok arama beri "neden indexOf bir dizi IE8 üzerinde çalışmıyor?" js'den WRT'ye daha düşük bir sofistike düzeyde olabilir, bunu cevabın sonucu olarak belirtmek yararlı olabilir. Herkes, uygulamalar arasındaki spesifikasyonu ve farklılıkları derinlemesine anlasaydı, bunlar gibi konular mevcut olmazdı. @Nick Doğruluk hakkında güçlü varsayımlar yaparsınız. Sırasının önemli olmadığı birçok işlem vardır (örneğin, farkı ayarlayın.) Ayrıca, orijinal yorum, dizin sırasına göre numaralandırmadan bahsetmedi, sadece / in için kullanıcı def fn'lerini içerir.
İspanya Tren

152

JQuery kullanıyorsanız, bunun yerine $ .inArray () kullanabilirsiniz .


7
Bunun daha faydalı olduğuna katılıyorum. Bu JQuery kullanmanın ana nedenlerinden biridir - tarayıcılar arası uyumsuzlukları hafifletmek için çok şey yapar.
cw24

17

JQuery kullanıyorsanız ve uyumluluk sorunları hakkında endişelenmeden indexOf'u kullanmaya devam etmek istiyorsanız, bunu yapabilirsiniz:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(val) {
        return jQuery.inArray(val, this);
    };
}

Bu, kullanmaya devam etmek istediğinizde, indexOfancak kullanılabilir olmadığında bir yedek sağlamak istediğinizde yararlıdır .


Evet, muhtemelen jQuery ¯_ (ツ) _ / include içermediği için geçerli bir sözdizimidir.


5

Kullanmak istiyorsanız lütfen $ .inArray ile dikkatli olun. Ben sadece $ .inArray sadece "Array" ile çalışır, String ile öğrendim. Bu nedenle bu işlev IE8'de çalışmaz!

JQuery API'sı kafa karışıklığı yaratıyor

$ .İnArray () yöntemi, bir eşleşme bulamadığında -1 döndürmesi nedeniyle JavaScript'in yerel .indexOf () yöntemine benzer. Dizideki ilk öğe değerle eşleşirse, $ .inArray () 0 döndürür

-> "Benzer" dememeliler. İndexOf beri destek "String"!


16
Denir inArray. Bu sadece diziler için oldukça kesin görünüyor. Bu yüzden "benzer" ve "özdeş" değil.
tandrewnichols

İyi not. Komik indexOfbir String nesnesinde IE'de tamamen bulunurken indexOfArray prototipi IE'de bulunamadı <= 8
adi518

Dizeyi prototipe bağlarsınız, böylece dizeleri etkilemez.
kagronick

3

Sorun

IE <= 8 indexOf()dizileri için bir yöntem içermiyor .


Çözüm

Eğer gerekiyorsa indexOfIE <= 8'de, aşağıdaki kullanmayı düşünmelisiniz polyfill edilir MDN de tavsiye :

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(searchElement, fromIndex) {
        var k;
        if (this == null) {
            throw new TypeError('"this" is null or not defined');
        }
        var o = Object(this);
        var len = o.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = +fromIndex || 0;
        if (Math.abs(n) === Infinity) {
            n = 0;
        }
        if (n >= len) {
            return -1;
        }
        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
        while (k < len) {
            if (k in o && o[k] === searchElement) {
                return k;
            }
            k++;
        }
        return -1;
    };
}

Küçültülmüş:

Array.prototype.indexOf||(Array.prototype.indexOf=function(r,t){var n;if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if(0===i)return-1;var a=+t||0;if(Math.abs(a)===1/0&&(a=0),a>=i)return-1;for(n=Math.max(a>=0?a:i-Math.abs(a),0);i>n;){if(n in e&&e[n]===r)return n;n++}return-1});

1

Varsa, işlevi değiştirmek için bunu kullanabilirsiniz:

<script>
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++) {
            if (from in this && this[from] === elt)
                return from;
        }
        return -1;
    };
}
</script>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.