Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > построчный вывод в броузер


Автор: burakov 20.11.2009, 16:20
Добрый день.
включил у себя activex

написал скрипт сканирования каталогов рекурсивно
хочу теперь чтобы файлы при сканировании построчно выводились в броузер - ну или как в примере в textarea

вот код

Код


<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var Path = 'c:/'; 
    setTimeout ('GetFile(Path)', 1000);


    function GetFile (Path) {
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);
        var Result;

        if (FSO.FolderExists (Path)) {
            var e = new Enumerator (Folder.Files); 
            for (e.moveFirst(); !e.atEnd(); e.moveNext()) { 
                var File = e.item();
                document.qqq.aaa.value += File.Path + '\r\n';
                
            }        
            e = new Enumerator (Folder.subFolders); 
            for (e.moveFirst(); !e.atEnd(); e.moveNext()) { 
                var Dir = e.item();
                if (FSO.FolderExists (Dir)) {
                    GetFile (Dir);
                }
            }        
        }
    }
    
    </script>    
</body>
</html>


поставил вроде и задержку, но страница все равно зависает , пока все файлы не отсканируются

Вопрос, как сделать так, чтобы 
нашел мой GetFile файлик в каталоге и СРАЗУ отобразил его в textarea
не дожидаясь конца сканирования каталога ...

Спасибо...

Автор: Itsys 20.11.2009, 22:25
Пока работает процедура никакого обновления не будет.

Надо за один вызов процедуры ыполнять вывод только одного файла, т.е.:
1. Задал начальный путь
2. Вызвал процедуру
3. Выдал один файл и запомнил в глобальной переменной какой файл выдан
4. В конце процедуры setTimeout
5. Вызвал процедуру
6. Выдал файл, следующий за запомненым и запомнил в глобальной переменной какой файл выдан
и т.д. с пункта 4

Автор: burakov 23.11.2009, 11:19
Добрый день,

ничего у меня не получается...
Такое впечатление , что пока js хоть чуть чуть думает (выполняет процедуру даже запущенную по timeout) никакого постепенного отображения не БУДЕТ!!! Кроме страничка на момент вычислений "зависает", так что допустим элемент select не раскрывается - 
вот пример тому следующий код 

Код


<html>
    <body>
    <select> 
    
    <option> Страничка </option>
    </select>
    
    
    <script type="text/javascript">

    Array = new Array ();
    var i; var Count = 10000; 
    var ForPrint = ''; 
    while (Array.length < Count) {
        Array.push (Count); 
    }
    
    setTimeout ('For ()', 1000);
    
    function For () {
        for (i=0; i < Array.length; i++) {
            ForPrint += Array[i] + '<br>';
            setTimeout ('View (ForPrint)', 1000);
        }    
    }

    function View (Str) {
        document.write (Str);
    }
    
    </script>    
</body>
</html>



Как видно и цикл запускается по setTimeout и само отображение информации запускается по setTimeout. ОДНАКО зависание странички наблюдается КОНКРЕТНОЕ...

Пока цикл for не закончится - ни какое такое мало мальски динамическое (постепенное) отображение document.write не наблюдается!!!!

Друзья!!!
 Я хочу НЕВОЗМОЖНОГО от JS или что то не так делаю?

Напомню таки чего хочется ....

есть скрипт сканирования каталогов (на предмет файлов) рекурсивно для получения списка файлов и последующей его обработки. Но когда файлов много (2000 и более) страница (html) некрасиво зависает до окончания сканирования .... а я не хочу чтобы эффект зависания имел место, да к тому же хочу чтобы на странице динамично отображался результат работы скрипта - т.е. выводились бы имена файлов (ну пусть даже и не поименно, а хотя бы по несколько штук, т.е. за какой то период времени выраженный в миллисекундах т.е. небольшой smile)

Возможно ли такое сделать средствами JS??? Ведь есть же ajax  и т.п. технологии. Как то ж люди добиваются эффекта более менее похожести работы web приложения на работу локальной программы!?


Спасибо...






Автор: burakov 23.11.2009, 13:39
добрый день еще раз smile
Покопался в инете и выяснил, что для того чтобы была динамика в отображении содержимого 
необходимо отказываться от операторов циклов и переносить все это в функции за запуском по setTimeout. И вообщем то заработало.... 
вот например код

Код

<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/windows'; 
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);

        if (FSO.FolderExists (Path)) {
            var f = new Enumerator (Folder.Files); 
            
            getFileFromEnumerator(f); 
            function getFileFromEnumerator(f) {
                if (!f.atEnd()) {
                    f.moveNext();
                    var File = f.item (); 
                    Result += File.Path + '\r\n';
                    document.qqq.aaa.value = Result;
                    setTimeout ('getFileFromEnumerator(f)', MS);
                }
            }
        }

    </script>    
</body>
</html>


делает то что мне надо, НО мне нельзя ведь FSO глобально объявлять - мне рекурсия нужна
но на следующем коде пишет что "не определен параметр f"
понимаю, что дело тут в области видимости объекта - но как правильно написать не пойму.
пример кода

Код

<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/windows'; 
    setTimeout ('GetFile(Path)', MS);


    function GetFile (Path) {
    
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);
        
        
        if (FSO.FolderExists (Path)) {
            var f = new Enumerator (Folder.Files); 
            
            getFileFromEnumerator(f); 
            function getFileFromEnumerator(f) {
                if (!f.atEnd()) {
                    f.moveNext();
                    var File = f.item (); 
                    Result += File.Path + '\r\n';
                    document.qqq.aaa.value = Result;
                    setTimeout ('getFileFromEnumerator(f)', MS);
                }
            }

            
        /*    
            var s = new Enumerator (Folder.subFolders); 
            getDirFromEnumerator (s) {
                if (!s.atEnd()) {
                    s.moveNext(); 
                    var Dir = s.item ();
                    if (FSO.FolderExists (Dir)) {
                    GetFile (Dir);
                }
            }

        */

        }
    }
    
    </script>    
</body>
</html>

Автор: Itsys 23.11.2009, 15:42
Не увидел последнее собщение, но идея такова:
Код

<html>
    <body>
    <div id="dv"></div>
    <script type="text/javascript">

    Array = new Array ();
    var Count = 100; 
    for (i=0; i<Count; ++i) {
        Array.push (i); 
    }
    
    setTimeout (function(){For (0)}, 1000);
    
    function For (end) {
        ForPrint = '';
        for(i = 0; i <= end; ++i){
            ForPrint += Array[i];
        }
        document.getElementById("dv").innerHTML += ForPrint + '<br>';
        ++end;
        if (end < Array.length){
            (function(next){
                setTimeout (function(){For (next)}, 1000);
            })(end);
        }
    }
   
    </script>    
</body>
</html>


Добавлено через 1 минуту и 45 секунд
ЗЫ Обрати внимание на сроки 22-24

Автор: burakov 23.11.2009, 16:36
Спасибо. за ответы.

последний код немного запутан (для меня) но в принципе понятен.
заменить цикл вложенными функциями у меня получилось...

вопрос сейчас в следующем 
Не могу понять... почему 


wsh нормально отрабатывает мой скрипт рекурсивного сканирования каталогов 
(правда если файлов много как например в каталоге windows - говорит "Недостаточно памяти" - отчего такая ошибка - при использовании циклов такой ошибки не возникает!)

Код

    var MS = 500; 
    var Result = '';
    var Path = 'c:/windows'; 

    GetFile (Path);
    
    function GetFile (Path) {
        
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);

        if (FSO.FolderExists (Path)) {

            var f = new Enumerator (Folder.Files); 
            getFileFromEnumerator(f); 
            function getFileFromEnumerator(f) {
                if (!f.atEnd()) {
                    var File = f.item (); 
                    WScript.Echo (File.Path);
                    f.moveNext();
                    getFileFromEnumerator(f); 
                }
            }
            
            var s = new Enumerator (Folder.SubFolders); 
            getDirFromEnumerator (s);
            function getDirFromEnumerator (s) {
                if (!s.atEnd()) {
                    var Dir = s.item ();
                    s.moveNext(); 
                    if (FSO.FolderExists (Dir)) {
                        GetFile (Dir);
                    }
                    getDirFromEnumerator (s);
                }
            }            
        }
    }



а вот в броузере точно такой же код НЕ РАБОТАЕТ
ругается на то что объект s (не имеет определения)
впрочем если убрать s, то тогда точно такое же ругательство говорит на объект f.

подозреваю, что дело в области видимости - но ведь точно такой же код без проблем работает
в WSH!!! Вот этот злополучный код...

Код

<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/111'; 

    GetFile (Path);
    
    function GetFile (Path) {
        
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);

        if (FSO.FolderExists (Path)) {

            var f = new Enumerator (Folder.Files); 
            getFileFromEnumerator(f); 
            function getFileFromEnumerator(f) {
                if (!f.atEnd()) {
                    var File = f.item (); 
                    
                    document.qqq.aaa.value += File.Path + '\r\n';
                    f.moveNext();
                    setTimeout ('getFileFromEnumerator(f)', MS); 
                }
            }
            
            var s = new Enumerator (Folder.SubFolders); 
            getDirFromEnumerator(s);
            function getDirFromEnumerator(s) {
                if (!s.atEnd()) {
                    var Dir = s.item ();
                    s.moveNext(); 
                    if (FSO.FolderExists (Dir)) {
                        GetFile (Dir);
                    }
                    setTimeout ('getDirFromEnumerator(s)', MS);
                }
            }            
        }
    }
    
    </script>    
</body>
</html>


Ну и наконец 
через эксперименты с областью видимости объектов удалось просканировать  каталог с тем эффектом который мне нужен - правда за счет того что объект FSO создаю глобально рекурсивно такое сделать не получится

КОД
Код

<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/windows'; 
    setTimeout ('GetFile(Path)', MS);

        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
    
        if (FSO.FolderExists (Path)) {
        
            var Folder = FSO.GetFolder (Path);
            var f = new Enumerator (Folder.Files); 
        
            f = getFileFromEnumerator(f); 
            function getFileFromEnumerator(f) {
                if (!f.atEnd()) {
                    var File = f.item (); 
                    f.moveNext();
                    Result += File.Path + '\r\n';
                    document.qqq.aaa.value = Result;
                    setTimeout ('getFileFromEnumerator(f)', MS);
                    return f;
                }
            }
        }

    
    </script>    
</body>
</html>



Почему же все таки не получается прочесть файлы рекурсивно???

Автор: Itsys 23.11.2009, 17:55
В этом случае f и s надо вынести в глобальный контекст
Код

<html>
    <body>

    <form name="qqq">
    <textarea name="aaa" rows=10 cols=50></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/111'; 
    var f,s;

    GetFile (Path);
    
    function GetFile (Path) {
        
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);

        if (FSO.FolderExists (Path)) {

            f = new Enumerator (Folder.Files); 
            getFileFromEnumerator(); 
            function getFileFromEnumerator() {
                if (!f.atEnd()) {
                    var File = f.item (); 
                    
                    document.qqq.aaa.value += File.Path + '\r\n';
                    f.moveNext();
                    setTimeout (function(){getFileFromEnumerator()}, MS); 
                }
            }
            
            s = new Enumerator (Folder.SubFolders); 
            getDirFromEnumerator();
            function getDirFromEnumerator() {
                if (!s.atEnd()) {
                    var Dir = s.item ();
                    s.moveNext(); 
                    if (FSO.FolderExists (Dir)) {
                        GetFile (Dir);
                    }
                    setTimeout (function(){getDirFromEnumerator()}, MS);
                }
            }            
        }
    }
    
    </script>    
</body>
</html>

Автор: brother79 24.11.2009, 08:03
Sory, не так вопрос понял smile Удалите сообщение.

Автор: burakov 24.11.2009, 10:20
Добрый день, 

спасибо огромное за участие 
в конце концов все разрешилось....

Если объекты f, s объявить глобально - то скрипт НЕ РАБОТАЕТ.
и вообщем то понятно почему... НО
все дело оказалось в моем написании setTimeout

Я его вызывал вот так 
Код

setTimeout ('getFileFromEnumerator(f)', MS); 


а почему то правильно работает так
Код

setTimeout (function(){getFileFromEnumerator()}, MS); 


хотя я синтаксис из справочника по js вроде бы подсмотрел :(.

вообщем вот рабочий код скрипта
Код

<html>
    <body>
    <form name="qqq">
    <textarea name="aaa" rows=10 cols=120></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'c:/windows'; 
    
    
    GetFile (Path);
    
    function GetFile (Path) {
        
        var FSO = new ActiveXObject ("Scripting.FileSystemObject");
        var Folder = FSO.GetFolder (Path);
        if (FSO.FolderExists (Path)) {
            var f = new Enumerator (Folder.Files); 
            getFileFromEnumerator(); 
            function getFileFromEnumerator() {
                if (!f.atEnd()) {
                    var File = f.item (); 
                    
                    document.qqq.aaa.value += File.Path + '\r\n';
                    f.moveNext();
                    setTimeout (function(){getFileFromEnumerator()}, MS); 
                }
            }
            
            var s = new Enumerator (Folder.SubFolders); 
            getDirFromEnumerator();
            function getDirFromEnumerator() {
                if (!s.atEnd()) {
                    var Dir = s.item ();
                    s.moveNext(); 
                    if (FSO.FolderExists (Dir)) {
                        GetFile (Dir);
                    }
                    setTimeout (function(){getDirFromEnumerator()}, MS);
                }
            }            
        }
    }
    
    </script>    
</body>
</html>


правда из-за этой вот псевдо многопоточности список файлов выходит хитрозадо smile 
но в принципе все заработало
СПАСИБО.

А как программно можно узнать что скрипт закончил работу....
ставлю на textarea onLoad но ничего не происходит? 

Автор: Itsys 24.11.2009, 15:53
Цитата(burakov @  24.11.2009,  10:20 Найти цитируемый пост)
А как программно можно узнать что скрипт закончил работу....
ставлю на textarea onLoad но ничего не происходит?

С таким скриптом у тебя это точно не получится...

Надо менять логику...

Автор: Itsys 24.11.2009, 17:30
Хотя бы так:
Код

<html>
    <body>
    <form name="qqq">
    <textarea name="aaa" rows=10 cols=120></textarea>
    </form>
    
    <script type="text/javascript">
    
    var MS = 500; 
    var Result = '';
    var Path = 'C:/Perl/site/lib'; 
    var Folders= new Array;
    Folders.push(Path);
    var FolderNow = 0;
    var FileNow = "";
    var FSO = new ActiveXObject ("Scripting.FileSystemObject");

    function GetSubFolders(PathNow){
        if (FSO.FolderExists(PathNow)) {
            var Folder = FSO.GetFolder (PathNow);
            var s = new Enumerator (Folder.SubFolders); 
            while (!s.atEnd()) {
                var Dir = s.item ();
                s.moveNext(); 
                if (FSO.FolderExists (Dir)) {
                    Folders.push(Dir);
                    (function(Dir){
                        GetSubFolders(Dir);
                    })(Dir);
                }
            }
        }
    }
    //Сначало получим все подкатеории
    GetSubFolders(Path);
    
    GetFile ();
    
    function GetFile () {
        
        if (FileNow == ""){
            if (Folders.length > FolderNow){
                var Folder = FSO.GetFolder (Folders[FolderNow]);
                FileNow = new Enumerator (Folder.Files); 
                ++FolderNow;
            }
            else{
                alert("Закончили!");
                return;
            }
        }
        if (!FileNow.atEnd()) {
            var File = FileNow.item (); 
            
            document.qqq.aaa.value += File.Path + '\r\n';
            FileNow.moveNext();
            setTimeout (function(){GetFile()}, MS); 
        }
        else{
            FileNow = "";
            setTimeout (function(){GetFile()}, MS); 
        }
    }
    
    </script>    
</body>
</html>

Автор: burakov 25.11.2009, 09:22
огромное спасибо за пример.
очень помогли ...

СПАСИБО.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)