Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Отмена события (https://javascript.ru/forum/events/58923-otmena-sobytiya.html)

artiom4356 18.10.2015 08:58

Отмена события
 
В общем есть такая проблема. То есть при сробатывании события отправки формы скрипт должен проверить какой или какие файлы были загружены(сколько файлов, их тип ну их многое другое). Пытался по разному сделать например так. Но ничего не работает.
<script>
	$('#Otpravka234134').submit(function(e){			  
			   var a=document.getElementById('ava').files;	   
	if (a.length!=1){
e.preventDefault();
		return false;
	alert("Загрузите адин файл. Тип загружаемого файла"+a[0].type);
	
	}
	}
	
			  </script>

laimas 18.10.2015 15:50

Цитата:

Сообщение от artiom4356
Загрузите адин файл.

Правильно пишется - адын файл.

Если a.length != 1, то зачем разрешать загрузку многих соответствующим полем, и зачем "... или какие файлы были загружены(сколько файлов, их тип ну их многое другое)."?

artiom4356 18.10.2015 19:03

Цитата:

Сообщение от laimas (Сообщение 392307)
Правильно пишется - адын файл.

Если a.length != 1, то зачем разрешать загрузку многих соответствующим полем, и зачем "... или какие файлы были загружены(сколько файлов, их тип ну их многое другое)."?

Если a.length != 1 то есть равно любому другом числу кроме одного то я отменяю события. Ну а в проивном случии пользователь загрузил 1 файл и условие не выполнитца..... Только я не понемаю как отменить это самое событие отправки. И на счёт поля. Это HTML и я к нему не имею доступа на прямую. Мне нужно написать скрипт который бы работа не завсимо через какой элемент формы идёт загрузка. А на счёт типов загружаемых фалов и прочего это я поспешил... просто чуть позже хочу добавить проверку на тип вот и всё.

laimas 18.10.2015 19:32

Цитата:

Сообщение от artiom4356
то есть равно любому другом числу кроме одного то я отменяю события. Ну а в проивном случии пользователь загрузил 1 файл и условие не выполнитца.....


Каким образом пользователь сможет загрузить несколько файлов, если ему этого не разрешать? Одним полем file загрузить несколько файлов можно только собственноручно прописав в нем multiple, и только в новых версиях браузеров, для старых с помощью нескольких таких полей?

artiom4356 18.10.2015 22:18

Цитата:

Сообщение от laimas (Сообщение 392329)
Каким образом пользователь сможет загрузить несколько файлов, если ему этого не разрешать? Одним полем file загрузить несколько файлов можно только собственноручно прописав в нем multiple, и только в новых версиях браузеров, для старых с помощью нескольких таких полей?

Даже если убрать это условие.... событие серовно не отменяеца.

laimas 19.10.2015 04:36

Вы где русский учили? :)

Отметь отправку формы:
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script> 
$(function() {
    $('form').submit(function(e) {
        e.preventDefault();
        $('div').text('Value as is not sent')
    })
});
</script>     
</head> 
<body>
<form>
<input name="as" value="1" />
<button>Send</button></form>
<div></div>
</body> 
</html>


Может пояснить конкретней чего вы хотите сделать? Но с учетом того, что проверять загрузку файлов более одного при невозможности загрузить более не имеет смысла. Таковую проверку нужно делать на сервере, и зная, что клиент может отправить только один файл, при их большем количестве делать вывод, что форма левая.

artiom4356 19.10.2015 06:02

Да к стати. Хотелось бы спросить что если мне допустим надо загрузить какую ни будь аватарку ну или просто картинку. Но прежде чем отпровлять на сервер мне надо проверить расширение этого самого изображения и его размер. Размер в смысле ширину и высоту. Как такое можно сделать?? Желательно без cavans

laimas 19.10.2015 06:48

Нужно обрабатывать событие onchange поля ввода:
$(function() {
    $('selector').change(function() {
        var im = new Image(), type = this.files[0].type;
        im.onload = function() {
            alert('Type: '+type+'\n'+'Width: '+this.width+'\n'+'Height: '+this.height)
        }
        im.src = this.value
    })
});

В IE6 тип можно было получить и с помощью свойства mimeType.

artiom4356 19.10.2015 13:28

Не работает. alert не работает.... такое ощущение что события и вовсе нет... Библиотека сразу говорю подключена Вот код
<form id="ka">
<input type="file" id="filess" name="files[]"/>
<button type="submit">
</form>

<script>
$(function() {
    $('#filess').change(function() {
        var im = new Image(), type = this.files[0].type;
        im.onload = function() {
            alert('Type: '+type+'\n'+'Width: '+this.width+'\n'+'Height: '+this.height)
        }
        im.src = this.value
    })
});
</script>

EmperioAf 19.10.2015 14:10

Цитата:

Сообщение от artiom4356
Библиотека сразу говорю подключена

попробуйте обернуть ваш JQuery код:
(function($){
//ваш jQuery код
}(jQuery));

laimas 19.10.2015 14:37

<html> 
<head> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script> 
$(function() {
    $('#filess').change(function() {
        if(window.FileReader) {
            var im = new Image(), r = new FileReader(), f = this.files[0], type = f.type;
            r.onload = function(e) {
                im.onload = function() {
                    alert('Type: '+type+'\n'+'Width: '+this.width+'\n'+'Height: '+this.height)
                }
                im.src = e.target.result;
            }
            r.readAsDataURL(f)
        } else {
            //сорри, только через сервер 
        }
    })
});
</script>     
</head> 

<body>
<form id="ka">
<input type="file" id="filess" name="files"/>
<input type="submit" value="Send"/>
</form>
</body> 
</html>


Вам нужно отправлять один файл, а значит name="files", иначе при name="files[]" лишь усложниться структура массива принятых файлов.

<button type="submit"> - такого быть не может, или input type="submit" или button.

PS. Причина в безопасности - для того чтобы использовать свойство value, изображение должно быть в том же каталоге что и скрипт, что в случае веб-страницы нельзя реализовать. В IE можно добавить сайт в доверенные, тоже будет доступно. Сейчас попробую по иному, если не получится, то нужно нужно будет использовать, например, FileReader.

artiom4356 19.10.2015 15:13

Стоп! Но разве скрипт не должен получить доступ к указаному пользователе файлу? Хотя для такого случая можно пойти на крайность(для меня это так) и воспользоваться AJAX но как то не очень хочется это делать.

laimas 19.10.2015 15:33

Скрипт то получает доступ к файлу, но не раскрывает путь, по которому он получен на машине клиента. Это относится к вопросу по безопасности, и никакой Ajax в этом не поможет. Уж не помню точно, но Ослика точно можно заставить раскрыть этот путь добавив сайт в доверенные. В других браузерах не проверял, не знаю.

В общем не получится "обдурить" браузер, по крайней мере у меня не получилось. Остается только FileReader использовать, код исправлен под него.

artiom4356 19.10.2015 15:39

Ладно спасибо. Я понял что это, ну по крайней в мере в большей части глупая затея. Тема закрыта.

laimas 19.10.2015 15:47

Затея чего, узнать разрешение изображения на клиенте? Чем же она глупая? В старых браузерах это только на сервере корректно можно получить, что впрочем все равно придется на нем делать, если вам необходимо контролировать разрешение.

artiom4356 19.10.2015 17:01

Я просто хотел изначально проверять размер загружаемого изображения.

laimas 19.10.2015 17:21

размер, это сколько вести файл, а разрешение, это ширина на высоту. Если размер, то FileReader не нужен, это можно узнать как files[0].size.

artiom4356 19.10.2015 17:27

Не правильны выразился "Разрешение". И да почему вы говрите что AJAX не поможет? Можноже отправить картинку на сервер а потом просто получить с него всю информацию о данном файле. Разве нет?

laimas 19.10.2015 17:42

Цитата:

Сообщение от artiom4356
И да почему вы говрите что AJAX не поможет?


А чем? Тут уж не разрешение надо возвращать, а ошибку в случае если оно не удовлетворяет требованию, то есть это уже проверка на сервере перед загрузкой файлов, а не забава ради информации. :)
Об это я говорил ранее. Если ошибок нет, перемещаем файл в каталог и возвращаем "Ок". Между прочим, заставлять пользователя загружать картинку под аватарку строго W x H, это вчерашний день - сервер спокойно может уменьшить изображение, вырезать пропорционально и никаких проблем. А ограничения можно на тип файла (не картинка, или не разрешать gif-анимацию, если больше размера аватарки и нечем на сервер работать с такой анимацией), размер файла не позволит уменьшить его (памяти не хватит), и т.п.

artiom4356 19.10.2015 19:16

Я к стаи что то малость не понял что падете вот тут r.onload = function(e) в е и обясните это e.target.result и это r.readAsDataURL(f) а то что то я малость не доконца понимаю эти строчки.

laimas 19.10.2015 19:30

Об этом лучше подробно в сети найти и почитать, о Ajax загрузке файлов доступной в HTML5. Кратко, это следующее - по событию onload объекта FileReader, который получает содержимое файла выбранного для загрузки в формате base64 (readAsDataURL(f)), это содержимое target.result помещается в созданное изображение im (new Image()).

Именно это и используется и при Ajax загрузке файлов, если нужен предпросомтр изображения, а данные формы отправляются с использованием объекта FormData. В браузерах не поддерживающих HTML5 используется iframe. Есть готовые плагины, в том числе и под jQuery для такой загрузки, ищите в сети их.

artiom4356 20.10.2015 19:29

У меня появился ещё один вопрос. Совсем не большой. Как удалить файл?? Скорее всего для этого есть какое то свойстве инпута... конечно вопрос малость глупый но всё же жду ответа на него :) Ну и конечно как я пробовал щас покажу
delete $('#ava').files[0];

Я имею в виду удалить так что бы он на сервер не загружался

laimas 20.10.2015 20:13

Нет, так не удалить :)
А вот удалить поле выбора файла из формы можно, заменив его новым.

artiom4356 21.10.2015 09:31

Я поппытался так сделать но эта работает только 1 раз. То есть вот он выводит сообщение мол файл не тот и пересоздёт вот по такому приципу
$('#ava').remove();

			var	inp2 = document.createElement( 'input' );
			inp2.type = 'file';inp2.name = 'images'; 
			inp2.id = 'ava';inp2.class = 'f_input';
			document.getElementById( 'TdAvaPerent' ).appendChild( inp2 );//TdAvaPerent это див в котором и находиться элемент

А после его пересоздания событие слетает и абсолютно весь код косающийся данного элемента становиться не рабочим. Как это исправить?

laimas 21.10.2015 10:17

Ну так создавая элемент вы совсем не задаете обработку события.
Лучше делегировать обработчик родителю, тогда и забот не будет. Например, родитель поля имеет идентификатор box, тогда на jQ, коли его используете:

$('#box').on('change', 'input:file', function() {
    //обработка загрузки файла
    //если не отвечает условию, то удаляем поле выбора файла
    $(this).remove();
    //создаем новое
    $('#box').append('<input type="file" name="images" class="f_input"/>');     
})

artiom4356 21.10.2015 14:05

Вроде должно быть правильно. Но код всё равно работать не хочет. Раньше работоло хотябы 1 раз после открытия страници... щас же
<div id="TdAvaPerent"><input type="file" name="images" class="f_input" id="ava"/></div>

$('#TdAvaPerent').on('change', 'input:file', function() {
	alert('YYY');// Проверял событие.... однака оно вообще не происходит. Не выводица.
        if(window.FileReader) {
            var im = new Image(), r = new FileReader(), f = this.files[0], type = f.type;
			if(type=='image/jpeg'){
			r.readAsDataURL(f);
            r.onload = function(e) {
                im.onload = function() {
				if(this.width>200 || this.height>200){
				alert('Пожалуйста загрузите картинку приемлемых размеров. В противном слуие вашь файл не будет загружен');
				
$(this).remove();
   
    $('#TdAvaPerent').append('<input type="file" name="images" class="f_input" id="ava"/>');
				}
                    
                }
                im.src = e.target.result;
            }
            }else{
			alert('Вы ошиблись файлом. Загрузите изображение.В противном слуие вашь файл не будет загружен');
			
	$(this).remove();
    $('#TdAvaPerent').append('<input type="file" name="images" class="f_input" id="ava"/>');
			}
        } else {
		alert('Произошла ошибка! Просим вас срочно обратиться к одному из системынх адмнинистраторов проекта с указанием такого индефекатора index653-670');

        }
    });

P.S Вроде не чего сложного а понять не могу :(

laimas 21.10.2015 16:42

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script>
$(function() {
var oP = $('#TdAvaPerent').on('change', 'input:file', function() {
        if(window.FileReader) { //это проверка на поддержку браузером данного объекта
            var im = new Image(), r = new FileReader(), f = this.files[0]; 
            
            //типы загружаемых изборажений указаны в поле file,
            //по его значению готовим рег. выражение для проверки
            if(f.type.match(new RegExp(this.accept.replace(/,/,'|')))){
                r.readAsDataURL(f);
                r.onload = function(e) {
                    im.onload = function() {
                        if(this.width>200 || this.height>200){
                            alert('Пожалуйста загрузите картинку приемлемых размеров. В противном слуие вашь файл не будет загружен');
                            clearFile(oP)
                        }
                    }
                    im.src = e.target.result;
                }
            } else {
                alert('Вы ошиблись файлом. Загрузите изображение. В противном случае вашь файл не будет загружен');
                clearFile(oP)
            }
        } else alert('Ваш браузер устарел, установите ... и ссылки на ресурсы, и срочно обращаться к ... не требуется');
    });
});
//иначе могут плодится поля выбора файла
function clearFile(o) {
    o.html('<input ' + $.map(o.children().get(0).attributes, function(v) {
        return v.name + '="' + v.value + '"'
    }).join(' ') + '>')
}
</script>     
</head> 
<body>
<div id="TdAvaPerent"><input type="file" name="images" class="f_input" accept="image/jpeg,image/png"/></div>
</body> 
</html>


id="ava" - не нужен вообще, если ни где-то более не используется.
accept="image/jpeg,image/png" - разрешенное для выбора в диалоге выбора файла, правда не все браузеры будут отображать именно изображения в папках, но по этому атрибуту производится проверка (см. в скрипте).

PS. Подправил код, чтобы не зависеть хотя бы от изменения атрибутов поля ввода.

artiom4356 21.10.2015 19:00

Спасибо! Очень помогли ))

laimas 21.10.2015 19:16

'Пожалуйста загрузите картинку приемлемых размеров. В противном слуие вашь файл не будет загружен'

Нужно сообщать тогда какое разрешение доступно, как и какие типы изображений разрешены.

artiom4356 21.10.2015 19:30

Да. В этом сообщение будет указана ссылка на FAQ.


Часовой пояс GMT +3, время: 06:03.