Mengapa saya tidak bisa mengubah kursor untuk maju sebelum menjalankan beberapa skrip di jQuery?

Saya telah berjuang untuk mencari tahu apa yang saya lakukan salah di sini. Saya hanya mencoba mengubah kursor menjadi "kemajuan" menggunakan fungsi .css() jQuery setelah pengguna mengklik tombol tetapi sebelum mengulang serangkaian di HighStock (yang memerlukan beberapa detik untuk dieksekusi) dan menampilkan/menyembunyikan beberapa baris (32 di antaranya !).

Saya telah mencoba banyak hal tetapi apa pun yang saya coba, tombolnya hanya dibekukan di posisi "turun" (tidak mengubah kursor, tetapi Anda masih dapat memindahkannya) hingga kode selesai.

Inilah yang saya coba (secara berurutan):

Catatan: Semua upaya saya menghasilkan hasil yang sama persis (yaitu, tidak ada kesalahan yang dihasilkan, kode dieksekusi, tetapi saya tidak pernah menampilkan kursor "kemajuan" saat kode sedang sibuk dieksekusi.

$("#onAllOverall").click(function () {
    $("body").css("cursor", "progress");

    for (var s = 0; s < series.length; s++) {
        series[s].hide();
    }

    $("body").css("cursor", "default");
});

Jadi, saya mencoba:

$("#onAllOverall").click(function () {
    $("body").css("cursor", "progress");
}

$("#onAllOverall").click(function () {
    for (var s = 0; s < series.length; s++) {
        series[s].hide();
    }

    $("body").css("cursor", "default");
});

Saya bahkan mencoba lebih jauh:

function progressCursor() {
    $("body").css("cursor", "progress");
}

$("#onAllOverall").click(function () {

    $.when(progressCursor).done(function () { //also tried $.when.then(), but I admit I don't know much about these methods;
        for (var s = 0; s < series.length; s++) {
            series[s].show();
        }
    });

    $("body").css("cursor", "default");
});

Saya ingat mencoba beberapa hal lainnya tetapi saya tidak dapat mengingat dengan jelas apa hal tersebut, namun hal tersebut mendasar dan tidak membantu.

Saya merasa agak konyol karena tidak ada yang berhasil di sini. Apa yang saya lakukan salah?


person VoidKing    schedule 27.03.2014    source sumber
comment
sepertinya utas ui terkunci saat mengulang. Anda harus membuat for async menggunakan timeInterval   -  person Warlock    schedule 27.03.2014
comment
apa seri di sini? Apakah objek yang valid untuk menjalankan show & hide?   -  person TheMohanAhuja    schedule 27.03.2014
comment
@TheMohanAhuja ini adalah fungsi dari plugin HighStock   -  person VoidKing    schedule 27.03.2014


Jawaban (1)


Anda perlu "menghasilkan" perulangan peristiwa ke browser sehingga dapat merender halaman (termasuk perubahan kursor) selama perulangan for Anda.

Cara termudah untuk menghasilkan di browser adalah dengan setTimeout 0 ms. (Nodejs memiliki fungsi bernama nextTick yang sebenarnya sesuai dengan keinginan Anda, namun browser belum mengimplementasikannya.)

$("#onAllOverall").click(function () {
    $("body").css("cursor", "progress");
    var s = 0;
    function next(){
        series[s].hide();
        s++;
        if(s < series.length){
            setTimeout(next, 0);
        } else {
            $("body").css("cursor", "default");
        }
    }
    if(series.length){
        next();
    }           
});

Pustaka https://github.com/caolan/async sangat bagus untuk hal ini.

Perhatikan bahwa implementasi ini menghasilkan setelah setiap kejadian hide(). Anda mungkin menemukan bahwa ini hanya berfungsi dengan satu set-timeout yang membungkus loop for. Menghasilkan setelah setiap operasi akan membuat halaman lebih responsif saat loop terjadi, tetapi juga mungkin membuat halaman terlihat aneh karena setiap elemen akan hilang satu per satu.

Agar tidak menyerah setelah setiap tindakan:

$("#onAllOverall").click(function () {
    $("body").css("cursor", "progress");

    function action(){
       for (var s = 0; s < series.length; s++) {
          series[s].hide();
       }

       $("body").css("cursor", "default");
    }
    setTimeout(action, 0);       
});
person Will Shaver    schedule 27.03.2014
comment
Oke, saya mencobanya dan berhasil, tetapi saya tidak 100% yakin saya tahu persis alasannya. Setelah melihatnya beraksi, saya tahu bahwa saya lebih suka tidak menyerah setelah setiap hide() peristiwa. Bisakah Anda menunjukkan contoh di mana ia bekerja hanya dengan satu set-timeout yang membungkus loop for? - person VoidKing; 27.03.2014
comment
Jika series.length adalah nol, Anda tidak ingin menjalankan loop. if(series.length) memastikannya lebih besar dari nol. - person Will Shaver; 27.03.2014
comment
Iya maaf, saya baru melihatnya setelah saya posting, lalu menghapus komentarnya :) Terima kasih atas penjelasannya dan terima kasih banyak untuk contoh lainnya. Anda berhasil melakukannya, namun yang sangat saya hargai adalah belajar dari contoh Anda dan mengapa contoh tersebut berhasil. Terima kasih lagi! - person VoidKing; 27.03.2014
comment
Jadi efektifnya, yang Anda lakukan di sini hanyalah mengubah action menjadi fungsi asinkron? Apakah itu benar? - person VoidKing; 27.03.2014
comment
Oh, tidak, Anda tidak akan mempercayainya, tetapi contoh kedua Anda (yang saya perlukan) tidak berhasil. Itu masih mengunci antarmuka dan tidak menampilkan kursor kemajuan. - person VoidKing; 27.03.2014
comment
Saya sangat menyarankan Anda membaca tentang loop acara javascript. Anda harus menyerah pada browser agar dapat merender. Dibutuhkan giliran bersama dengan semua kode javascript Anda. - person Will Shaver; 27.03.2014
comment
Coba sesuaikan batas waktunya. - person Will Shaver; 27.03.2014
comment
Oke, ini aneh, tetapi ini hanya berfungsi jika saya menggerakkan mouse dalam jumlah milidetik yang ditentukan dalam batas waktu. Jika saya memegang mouse tetap, mouse akan tetap membeku, bahkan jika saya memindahkannya setelah peristiwa batas waktu diaktifkan. Apakah ada solusi untuk ini? - person VoidKing; 27.03.2014
comment
Sayangnya tidak. stackoverflow.com/questions/1718415/ Saya sarankan mengubah sesuatu yang lain di halaman daripada kursor. - person Will Shaver; 27.03.2014
comment
Saya kira Anda benar, itu mungkin yang terbaik, tetapi pilihan pertama Anda terlihat lebih menarik sekarang karena saya tahu upaya apa yang harus saya lakukan untuk pilihan kedua, haha. - person VoidKing; 27.03.2014