#jquery #image #find #src #next
#jquery #изображение #Найти #Src #Далее
Вопрос:
У меня есть пара таких html-блоков в цикле foreach:
<label class="">Replace video:</label>
<input type="file" name="replaced_main_video" class="input-video-preview" />
<!-- replaced main video -->
<video class="video" controls>
<source type="video/mp4">
</video>
<canvas></canvas>
<label class="">Preview replaced video:</label><br />
<img class="video-preview" width="100" src="#" />
Для отображения предварительного просмотра из загруженного выбранного видео используйте этот код js:
$(function() {
var video = $('.video');
var thumbnail = $('canvas');
var input_video_preview = $('.input-video-preview');
var ctx = thumbnail.get(0).getContext("2d");
var duration = 0;
var img = $('.video-preview');
input_video_preview.on('change', function(e) {
var file = e.target.files[0];
// Set video source
video.find('source').attr('src', URL.createObjectURL(file));
// Load the video
video.get(0).load();
// Load metadata of the video to get video duration and dimensions
video.on('loadedmetadata', function(e) {
duration = video.get(0).duration;
// Set canvas dimensions same as video dimensions
thumbnail[0].width = video[0].videoWidth;
thumbnail[0].height = video[0].videoHeight;
// Set video current time to get some random image
video[0].currentTime = Math.ceil(duration / 2);
// Draw the base-64 encoded image data when the time updates
video.one("timeupdate", function() {
ctx.drawImage(video[0], 0, 0, video[0].videoWidth, video[0].videoHeight);
//$('.video-preview').attr("src", thumbnail[0].toDataURL());// THIS WORKS, but all imgs get src
$('.input-video-preview').next('.video-preview').attr("src", thumbnail[0].toDataURL()); // bind to the next img with class 'video-preview'
});
});
});
});
Это работает нормально, но поскольку блоки html повторяются foreach, каждый img
получает исходный код. и я хочу только следующий img
тег после input type="file"
Я попытался добиться этого с помощью этой строки ниже в функции:
$('.input-video-preview').next('.video-preview').attr("src", thumbnail[0].toDataURL()); // get input with class 'input-video-preview', take the next img with class '.video-preview' and bind it to the `src` attribute
Но, к сожалению, это не работает….
Как я могу этого добиться?
Ответ №1:
Для ссылки на конкретное input
, обычно мы используем $(this)
внутри функции:
$(this).next('.video-preview')
вместо
$('.input-video-preview').next('.video-preview')
Редактировать
Поскольку у вас много вложенных вызовов on()
, команда $(this)
может изменить контекст и не предназначаться <input>
для компонента. Поэтому вам может потребоваться сделать что-то вроде этого:
input_video_preview.on('change', function(e) {
var selectedInput = $(this);
//...
//...
selectedInput.nextAll('.video-preview').eq( 0 ).attr("src", thumbnail[0].toDataURL());
});
Редактировать 2
Помимо темы вашего вопроса, есть и другие аспекты вашего кода, которые могут помешать его работе.
Вы не должны заранее определять video
, thumbnail
и img
переменные. Эти переменные зависят от выбранного ввода.
Итак, вы должны определить, чем внутри on()
, используя nextAll()
также, вот так:
$(function() {
var input_video_preview = $('.input-video-preview');
var duration = 0;
input_video_preview.on('change', function(e) {
var selectedInput = $(this);
var video = selectedInput.nextAll('.video');
var thumbnail = selectedInput.nextAll('canvas');
var ctx = thumbnail.get(0).getContext("2d");
var img = selectedInput.nextAll('.video-preview');
var file = e.target.files[0];
//...
});
})
Комментарии:
1. я пробовал это, но я больше не получаю предварительный просмотр…
2. Я повозился с этим, но до сих пор нет предварительного просмотра: jsfiddle.net/son4uqfa
3. вы определяете
video
img
иthumbnail
не в том месте, см. Мое редактирование 2 выше4. Извините, я обновил свою скрипку точно с вашим отредактированным кодом, но не могу заставить ее работать: jsfiddle.net/son4uqfa/3
5. Теперь он работает, следует использовать nextAll() вместо next(), поскольку next() работает только для следующего родственного. Я обновляю свой ответ, чтобы отразить это.