Есть задача: сделать Drag&Drop окно, которое будет принимать картинки с пк пользователя. Нашел классный пример. Но есть проблема: автор использует jquery 1.8, а у меня на проекте 3.1.1 - по этой причине jQuery.event.props.push('dataTransfer');
не срабатывает, так как у event
нет props
.
Подскажите, пожалуйста, что делать?
var $ = jQuery.noConflict();
$(document).ready(function() {
// В dataTransfer помещаются изображения которые перетащили в область div
jQuery.event.props.push('dataTransfer');
// Максимальное количество загружаемых изображений за одни раз
var maxFiles = 6;
// Оповещение по умолчанию
var errMessage = 0;
// Кнопка выбора файлов
var defaultUploadBtn = $('#uploadbtn');
// Массив для всех изображений
var dataArray = [];
// Область информер о загруженных изображениях - скрыта
// $('#uploaded-files').hide();
// Метод при падении файла в зону загрузки
$('#drop-files').on('drop', function(e) {
// Передаем в files все полученные изображения
var files = e.dataTransfer.files;
// Проверяем на максимальное количество файлов
if (files.length <= maxFiles) {
// Передаем массив с файлами в функцию загрузки на предпросмотр
loadInView(files);
} else {
alert('Вы не можете загружать больше '+maxFiles+' изображений!');
files.length = 0; return;
}
});
// При нажатии на кнопку выбора файлов
defaultUploadBtn.on('change', function() {
// Заполняем массив выбранными изображениями
var files = $(this)[0].files;
// Проверяем на максимальное количество файлов
if (files.length <= maxFiles) {
// Передаем массив с файлами в функцию загрузки на предпросмотр
loadInView(files);
// Очищаем инпут файл путем сброса формы
$('#frm').each(function(){
this.reset();
});
} else {
alert('Вы не можете загружать больше '+maxFiles+' изображений!');
files.length = 0;
}
});
// Функция загрузки изображений на предросмотр
function loadInView(files) {
// Показываем обасть предпросмотра
$('#uploaded-holder').show();
// Для каждого файла
$.each(files, function(index, file) {
// Несколько оповещений при попытке загрузить не изображение
if (!files[index].type.match('image.*')) {
if(errMessage == 0) {
$('#drop-files p').html('Эй! только изображения!');
++errMessage
}
else if(errMessage == 1) {
$('#drop-files p').html('Стоп! Загружаются только изображения!');
++errMessage
}
else if(errMessage == 2) {
$('#drop-files p').html("Не умеешь читать? Только изображения!");
++errMessage
}
else if(errMessage == 3) {
$('#drop-files p').html("Хорошо! Продолжай в том же духе");
errMessage = 0;
}
return false;
}
// Проверяем количество загружаемых элементов
if((dataArray.length+files.length) <= maxFiles) {
// показываем область с кнопками
$('#upload-button').css({'display' : 'block'});
}
else { alert('Вы не можете загружать больше '+maxFiles+' изображений!'); return; }
// Создаем новый экземпляра FileReader
var fileReader = new FileReader();
// Инициируем функцию FileReader
fileReader.onload = (function(file) {
return function(e) {
// Помещаем URI изображения в массив
dataArray.push({name : file.name, value : this.result});
addImage((dataArray.length-1));
};
})(files[index]);
// Производим чтение картинки по URI
fileReader.readAsDataURL(file);
});
return false;
}
// Процедура добавления эскизов на страницу
function addImage(ind) {
// Если индекс отрицательный значит выводим весь массив изображений
if (ind < 0 ) {
start = 0; end = dataArray.length;
} else {
// иначе только определенное изображение
start = ind; end = ind+1; }
// Оповещения о загруженных файлах
if(dataArray.length == 0) {
// Если пустой массив скрываем кнопки и всю область
$('#upload-button').hide();
$('#uploaded-holder').hide();
} else if (dataArray.length == 1) {
$('#upload-button span').html("Был выбран 1 файл");
} else {
$('#upload-button span').html(dataArray.length+" файлов были выбраны");
}
// Цикл для каждого элемента массива
for (i = start; i < end; i++) {
// размещаем загруженные изображения
if($('#dropped-files > .image').length <= maxFiles) {
$('#dropped-files').append('<div id="img-'+i+'" class="image" style="background: url('+dataArray[i].value+'); background-size: cover;"> <a href="#" id="drop-'+i+'" class="drop-button">Удалить изображение</a></div>');
}
}
return false;
}
// Функция удаления всех изображений
function restartFiles() {
// Установим бар загрузки в значение по умолчанию
$('#loading-bar .loading-color').css({'width' : '0%'});
$('#loading').css({'display' : 'none'});
$('#loading-content').html(' ');
// Удаляем все изображения на странице и скрываем кнопки
$('#upload-button').hide();
$('#dropped-files > .image').remove();
$('#uploaded-holder').hide();
// Очищаем массив
dataArray.length = 0;
return false;
}
// Удаление только выбранного изображения
$("#dropped-files").on("click","a[id^='drop']", function() {
// получаем название id
var elid = $(this).attr('id');
// создаем массив для разделенных строк
var temp = new Array();
// делим строку id на 2 части
temp = elid.split('-');
// получаем значение после тире тоесть индекс изображения в массиве
dataArray.splice(temp[1],1);
// Удаляем старые эскизы
$('#dropped-files > .image').remove();
// Обновляем эскизи в соответсвии с обновленным массивом
addImage(-1);
});
// Удалить все изображения кнопка
$('#dropped-files #upload-button .delete').click(restartFiles);
// Загрузка изображений на сервер
$('#upload-button .upload').click(function() {
// Показываем прогресс бар
$("#loading").show();
// переменные для работы прогресс бара
var totalPercent = 100 / dataArray.length;
var x = 0;
$('#loading-content').html('Загружен '+dataArray[0].name);
// Для каждого файла
$.each(dataArray, function(index, file) {
// загружаем страницу и передаем значения, используя HTTP POST запрос
$.post('upload.php', dataArray[index], function(data) {
var fileName = dataArray[index].name;
++x;
// Изменение бара загрузки
$('#loading-bar .loading-color').css({'width' : totalPercent*(x)+'%'});
// Если загрузка закончилась
if(totalPercent*(x) == 100) {
// Загрузка завершена
$('#loading-content').html('Загрузка завершена!');
// Вызываем функцию удаления всех изображений после задержки 1 секунда
setTimeout(restartFiles, 1000);
// если еще продолжается загрузка
} else if(totalPercent*(x) < 100) {
// Какой файл загружается
$('#loading-content').html('Загружается '+fileName);
}
// Формируем в виде списка все загруженные изображения
// data формируется в upload.php
var dataSplit = data.split(':');
if(dataSplit[1] == 'загружен успешно') {
$('#uploaded-files').append('<li><a href="images/'+dataSplit[0]+'">'+fileName+'</a> загружен успешно</li>');
} else {
$('#uploaded-files').append('<li><a href="images/'+data+'. Имя файла: '+dataArray[index].name+'</li>');
}
});
});
// Показываем список загруженных файлов
$('#uploaded-files').show();
return false;
});
// Простые стили для области перетаскивания
$('#drop-files').on('dragenter', function() {
$(this).css({'box-shadow' : 'inset 0px 0px 20px rgba(0, 0, 0, 0.1)', 'border' : '4px dashed #bb2b2b'});
return false;
});
$('#drop-files').on('drop', function() {
$(this).css({'box-shadow' : 'none', 'border' : '4px dashed rgba(0,0,0,0.2)'});
return false;
});
});
.content {
margin-top:80px;
padding: 20px;
}
#drop-files {
position:relative;
width: 500px;
height: 140px;
margin: 0 auto;
background: rgba(0,0,0,0.1);
border-radius: 10px;
border: 4px dashed rgba(0,0,0,0.2);
padding-top:80px;
text-align: center;
font-size: 2em;
font-weight: bold;
}
#drop-files p {
clear:none;
padding:0;
margin:0;
}
#uploaded-holder {
display: none;
position:relative;
margin: 0 auto;
}
#dropped-files {
display:block;
margin: 0 auto;
width: 950px;
}
#upload-button {
z-index: 9999;
display: none;
margin: 20px 0;
}
.drop-button {
display: block;
position: absolute;
z-index: 9999;
padding: 5px;
width: 100%;
background: rgba(0,0,0,0.6);
font-size: 1em;
bottom: 0;
text-align: center;
text-decoration: none;
font-weight: 700;
color: #FFF;
}
#dropped-files .image {
position: relative;
height: 200px;
width: 300px;
border: 4px solid #fff;
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
background: #fff;
float: left;
border-radius: 4px;
margin: 0 7px 7px 0;
overflow: hidden;
}
#upload-button .ss-upload {
font-size: 0.7em;
}
#upload-button a {
text-decoration: none;
color: #fff;
font-weight: bold;
box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -35px 40px -10px #0A9FCA;
font-size: 20px;
padding: 10px 20px;
background-color: #4bc1e3;
border-radius: 10px;
}
#upload-button span {
position:relative;
text-align: center;
background: white;
border-radius: 10px;
font-size: 1.1em;
padding: 6px;
margin-right: 8px;
}
#upload-button a:hover {
box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -5px 40px 0px #0A9FCA;
}
#dropped-files #upload-button .delete {
padding: 7px 6px 4px 6px;
border-radius: 100px;
background: rgba(0,0,0,0.6);
box-shadow: none;
font-size: 1em;
margin-left: 8px;
}
#dropped-files #upload-button .delete:hover {
background: rgba(0,0,0,0.8);
}
#loading {
display: none;
width: 100%;
position: relative;
margin: 20px;
}
#loading-bar {
width: 404px;
height: 40px;
background: #fff;
box-shadow: 0 0 15px rgba(0,0,0,0.1);
border-radius: 5px;
padding: 2px;
}
.loading-color {
width: 0%;
height: 100%;
-webkit-transition: all 0.1s ease-in;
-moz-transition: all 0.1s ease-in;
-ms-transition: all 0.1s ease-in;
-o-transition: all 0.1s ease-in;
transition: all 0.1s ease-in;
border-radius: inherit;
background-color: #4edbf1;
}
#loading-content {
position: relative;
top: 15px;
font-size: 1.2em;
font-weight: bold;
text-align: center;
width: 405px;
}
#file-name-holder {
width: 100%;
float: left;
}
#file-name-holder h1 {
text-align: center;
padding: 20px 0;
font-size: 3em;
margin: 0;
}
#uploaded-files {
width:500px;
list-style:none;
margin:0 auto;
padding: 10px;
color: #545454;
}
#uploaded-files li {
padding: 10px;
border-bottom: 1px solid #eee;
font-size: 1.5em;
font-weight: bold;
line-height: 25px;
color: #545454;
}
#uploaded-files a {
color: #1bacbf;
}
.main {
width:900px;
margin:0 auto;
height:100%;
margin-top:100px;
}
.main img {
position:relative;
float:left;
width:280px;
height:180px;
margin:10px;
}
a.nav {
font-family:tahoma;
font-size:20px;
color:#4280af;
text-decoration:none;
margin-bottom:10px;
}
a.nav:hover {
color:#fffb89;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div class="content">
<center><a href="gallery.php" class="nav">Перейти в галерею</a></center>
<!-- Область для перетаскивания -->
<div id="drop-files" ondragover="return false">
<p>Перетащите изображение сюда</p>
<form id="frm">
<input type="file" id="uploadbtn" multiple />
</form>
</div>
<!-- Область предпросмотра -->
<div id="uploaded-holder">
<div id="dropped-files">
<!-- Кнопки загрузить и удалить, а также количество файлов -->
<div id="upload-button">
<center>
<span>0 Файлов</span>
<a href="#" class="upload">Загрузить</a>
<a href="#" class="delete">Удалить</a>
<!-- Прогресс бар загрузки -->
<div id="loading">
<div id="loading-bar">
<div class="loading-color"></div>
</div>
<div id="loading-content"></div>
</div>
</center>
</div>
</div>
</div>
<!-- Список загруженных файлов -->
<div id="file-name-holder">
<ul id="uploaded-files">
<h1>Загруженные файлы</h1>
</ul>
</div>
</div>
Для того, чтобы у вас на новых версиях jQuery работали плагины под старые версии, используйте jQuery Migrate:
var $ = jQuery.noConflict();
$(document).ready(function() {
// В dataTransfer помещаются изображения которые перетащили в область div
jQuery.event.props.push('dataTransfer');
// Максимальное количество загружаемых изображений за одни раз
var maxFiles = 6;
// Оповещение по умолчанию
var errMessage = 0;
// Кнопка выбора файлов
var defaultUploadBtn = $('#uploadbtn');
// Массив для всех изображений
var dataArray = [];
// Область информер о загруженных изображениях - скрыта
// $('#uploaded-files').hide();
// Метод при падении файла в зону загрузки
$('#drop-files').on('drop', function(e) {
// Передаем в files все полученные изображения
var files = e.dataTransfer.files;
// Проверяем на максимальное количество файлов
if (files.length <= maxFiles) {
// Передаем массив с файлами в функцию загрузки на предпросмотр
loadInView(files);
} else {
alert('Вы не можете загружать больше ' + maxFiles + ' изображений!');
files.length = 0;
return;
}
});
// При нажатии на кнопку выбора файлов
defaultUploadBtn.on('change', function() {
// Заполняем массив выбранными изображениями
var files = $(this)[0].files;
// Проверяем на максимальное количество файлов
if (files.length <= maxFiles) {
// Передаем массив с файлами в функцию загрузки на предпросмотр
loadInView(files);
// Очищаем инпут файл путем сброса формы
$('#frm').each(function() {
this.reset();
});
} else {
alert('Вы не можете загружать больше ' + maxFiles + ' изображений!');
files.length = 0;
}
});
// Функция загрузки изображений на предросмотр
function loadInView(files) {
// Показываем обасть предпросмотра
$('#uploaded-holder').show();
// Для каждого файла
$.each(files, function(index, file) {
// Несколько оповещений при попытке загрузить не изображение
if (!files[index].type.match('image.*')) {
if (errMessage == 0) {
$('#drop-files p').html('Эй! только изображения!');
++errMessage
} else if (errMessage == 1) {
$('#drop-files p').html('Стоп! Загружаются только изображения!');
++errMessage
} else if (errMessage == 2) {
$('#drop-files p').html("Не умеешь читать? Только изображения!");
++errMessage
} else if (errMessage == 3) {
$('#drop-files p').html("Хорошо! Продолжай в том же духе");
errMessage = 0;
}
return false;
}
// Проверяем количество загружаемых элементов
if ((dataArray.length + files.length) <= maxFiles) {
// показываем область с кнопками
$('#upload-button').css({
'display': 'block'
});
} else {
alert('Вы не можете загружать больше ' + maxFiles + ' изображений!');
return;
}
// Создаем новый экземпляра FileReader
var fileReader = new FileReader();
// Инициируем функцию FileReader
fileReader.onload = (function(file) {
return function(e) {
// Помещаем URI изображения в массив
dataArray.push({
name: file.name,
value: this.result
});
addImage((dataArray.length - 1));
};
})(files[index]);
// Производим чтение картинки по URI
fileReader.readAsDataURL(file);
});
return false;
}
// Процедура добавления эскизов на страницу
function addImage(ind) {
// Если индекс отрицательный значит выводим весь массив изображений
if (ind < 0) {
start = 0;
end = dataArray.length;
} else {
// иначе только определенное изображение
start = ind;
end = ind + 1;
}
// Оповещения о загруженных файлах
if (dataArray.length == 0) {
// Если пустой массив скрываем кнопки и всю область
$('#upload-button').hide();
$('#uploaded-holder').hide();
} else if (dataArray.length == 1) {
$('#upload-button span').html("Был выбран 1 файл");
} else {
$('#upload-button span').html(dataArray.length + " файлов были выбраны");
}
// Цикл для каждого элемента массива
for (i = start; i < end; i++) {
// размещаем загруженные изображения
if ($('#dropped-files > .image').length <= maxFiles) {
$('#dropped-files').append('<div id="img-' + i + '" class="image" style="background: url(' + dataArray[i].value + '); background-size: cover;"> <a href="#" id="drop-' + i + '" class="drop-button">Удалить изображение</a></div>');
}
}
return false;
}
// Функция удаления всех изображений
function restartFiles() {
// Установим бар загрузки в значение по умолчанию
$('#loading-bar .loading-color').css({
'width': '0%'
});
$('#loading').css({
'display': 'none'
});
$('#loading-content').html(' ');
// Удаляем все изображения на странице и скрываем кнопки
$('#upload-button').hide();
$('#dropped-files > .image').remove();
$('#uploaded-holder').hide();
// Очищаем массив
dataArray.length = 0;
return false;
}
// Удаление только выбранного изображения
$("#dropped-files").on("click", "a[id^='drop']", function() {
// получаем название id
var elid = $(this).attr('id');
// создаем массив для разделенных строк
var temp = new Array();
// делим строку id на 2 части
temp = elid.split('-');
// получаем значение после тире тоесть индекс изображения в массиве
dataArray.splice(temp[1], 1);
// Удаляем старые эскизы
$('#dropped-files > .image').remove();
// Обновляем эскизи в соответсвии с обновленным массивом
addImage(-1);
});
// Удалить все изображения кнопка
$('#dropped-files #upload-button .delete').click(restartFiles);
// Загрузка изображений на сервер
$('#upload-button .upload').click(function() {
// Показываем прогресс бар
$("#loading").show();
// переменные для работы прогресс бара
var totalPercent = 100 / dataArray.length;
var x = 0;
$('#loading-content').html('Загружен ' + dataArray[0].name);
// Для каждого файла
$.each(dataArray, function(index, file) {
// загружаем страницу и передаем значения, используя HTTP POST запрос
$.post('upload.php', dataArray[index], function(data) {
var fileName = dataArray[index].name;
++x;
// Изменение бара загрузки
$('#loading-bar .loading-color').css({
'width': totalPercent * (x) + '%'
});
// Если загрузка закончилась
if (totalPercent * (x) == 100) {
// Загрузка завершена
$('#loading-content').html('Загрузка завершена!');
// Вызываем функцию удаления всех изображений после задержки 1 секунда
setTimeout(restartFiles, 1000);
// если еще продолжается загрузка
} else if (totalPercent * (x) < 100) {
// Какой файл загружается
$('#loading-content').html('Загружается ' + fileName);
}
// Формируем в виде списка все загруженные изображения
// data формируется в upload.php
var dataSplit = data.split(':');
if (dataSplit[1] == 'загружен успешно') {
$('#uploaded-files').append('<li><a href="images/' + dataSplit[0] + '">' + fileName + '</a> загружен успешно</li>');
} else {
$('#uploaded-files').append('<li><a href="images/' + data + '. Имя файла: ' + dataArray[index].name + '</li>');
}
});
});
// Показываем список загруженных файлов
$('#uploaded-files').show();
return false;
});
// Простые стили для области перетаскивания
$('#drop-files').on('dragenter', function() {
$(this).css({
'box-shadow': 'inset 0px 0px 20px rgba(0, 0, 0, 0.1)',
'border': '4px dashed #bb2b2b'
});
return false;
});
$('#drop-files').on('drop', function() {
$(this).css({
'box-shadow': 'none',
'border': '4px dashed rgba(0,0,0,0.2)'
});
return false;
});
});
.content {
margin-top: 80px;
padding: 20px;
}
#drop-files {
position: relative;
width: 500px;
height: 140px;
margin: 0 auto;
background: rgba(0, 0, 0, 0.1);
border-radius: 10px;
border: 4px dashed rgba(0, 0, 0, 0.2);
padding-top: 80px;
text-align: center;
font-size: 2em;
font-weight: bold;
}
#drop-files p {
clear: none;
padding: 0;
margin: 0;
}
#uploaded-holder {
display: none;
position: relative;
margin: 0 auto;
}
#dropped-files {
display: block;
margin: 0 auto;
width: 950px;
}
#upload-button {
z-index: 9999;
display: none;
margin: 20px 0;
}
.drop-button {
display: block;
position: absolute;
z-index: 9999;
padding: 5px;
width: 100%;
background: rgba(0, 0, 0, 0.6);
font-size: 1em;
bottom: 0;
text-align: center;
text-decoration: none;
font-weight: 700;
color: #FFF;
}
#dropped-files .image {
position: relative;
height: 200px;
width: 300px;
border: 4px solid #fff;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
background: #fff;
float: left;
border-radius: 4px;
margin: 0 7px 7px 0;
overflow: hidden;
}
#upload-button .ss-upload {
font-size: 0.7em;
}
#upload-button a {
text-decoration: none;
color: #fff;
font-weight: bold;
box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -35px 40px -10px #0A9FCA;
font-size: 20px;
padding: 10px 20px;
background-color: #4bc1e3;
border-radius: 10px;
}
#upload-button span {
position: relative;
text-align: center;
background: white;
border-radius: 10px;
font-size: 1.1em;
padding: 6px;
margin-right: 8px;
}
#upload-button a:hover {
box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -5px 40px 0px #0A9FCA;
}
#dropped-files #upload-button .delete {
padding: 7px 6px 4px 6px;
border-radius: 100px;
background: rgba(0, 0, 0, 0.6);
box-shadow: none;
font-size: 1em;
margin-left: 8px;
}
#dropped-files #upload-button .delete:hover {
background: rgba(0, 0, 0, 0.8);
}
#loading {
display: none;
width: 100%;
position: relative;
margin: 20px;
}
#loading-bar {
width: 404px;
height: 40px;
background: #fff;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 2px;
}
.loading-color {
width: 0%;
height: 100%;
-webkit-transition: all 0.1s ease-in;
-moz-transition: all 0.1s ease-in;
-ms-transition: all 0.1s ease-in;
-o-transition: all 0.1s ease-in;
transition: all 0.1s ease-in;
border-radius: inherit;
background-color: #4edbf1;
}
#loading-content {
position: relative;
top: 15px;
font-size: 1.2em;
font-weight: bold;
text-align: center;
width: 405px;
}
#file-name-holder {
width: 100%;
float: left;
}
#file-name-holder h1 {
text-align: center;
padding: 20px 0;
font-size: 3em;
margin: 0;
}
#uploaded-files {
width: 500px;
list-style: none;
margin: 0 auto;
padding: 10px;
color: #545454;
}
#uploaded-files li {
padding: 10px;
border-bottom: 1px solid #eee;
font-size: 1.5em;
font-weight: bold;
line-height: 25px;
color: #545454;
}
#uploaded-files a {
color: #1bacbf;
}
.main {
width: 900px;
margin: 0 auto;
height: 100%;
margin-top: 100px;
}
.main img {
position: relative;
float: left;
width: 280px;
height: 180px;
margin: 10px;
}
a.nav {
font-family: tahoma;
font-size: 20px;
color: #4280af;
text-decoration: none;
margin-bottom: 10px;
}
a.nav:hover {
color: #fffb89;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/3.0.0/jquery-migrate.min.js"></script>
<div class="content">
<center><a href="gallery.php" class="nav">Перейти в галерею</a></center>
<!-- Область для перетаскивания -->
<div id="drop-files" ondragover="return false">
<p>Перетащите изображение сюда</p>
<form id="frm">
<input type="file" id="uploadbtn" multiple />
</form>
</div>
<!-- Область предпросмотра -->
<div id="uploaded-holder">
<div id="dropped-files">
<!-- Кнопки загрузить и удалить, а также количество файлов -->
<div id="upload-button">
<center>
<span>0 Файлов</span>
<a href="#" class="upload">Загрузить</a>
<a href="#" class="delete">Удалить</a>
<!-- Прогресс бар загрузки -->
<div id="loading">
<div id="loading-bar">
<div class="loading-color"></div>
</div>
<div id="loading-content"></div>
</div>
</center>
</div>
</div>
</div>
<!-- Список загруженных файлов -->
<div id="file-name-holder">
<ul id="uploaded-files">
<h1>Загруженные файлы</h1>
</ul>
</div>
</div>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Привет друзья! Раньше пользовался Sublime и расширением LiveReload, что позволяло вносить правки в HTML/CSS файлы как со стороны редактора, так и со стороны...
Здравствуйте! Пишу простое приложение для отображения, добавления и удаления компаний и их пользователей, и никак не могу понять, как привязать...
Делаю свою реализацию коллекции на основе массиваНаследуюсь от шаблонного интерфейса Collection
Как вставить данные в поля страницы и их отсабмитить, но без селениума