как найти ближайший следующий тег img с помощью jquery

#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() работает только для следующего родственного. Я обновляю свой ответ, чтобы отразить это.