简体   繁体   English

我如何获取jquery .each函数与.on('change')函数一起使用的动态元素

[英]How do I get jquery .each function working with a .on('change') function for dynamic elements

I have a gallery in a page where you click plus and minus to add and remove gallery items to which you then add a file to the input for that newly appended item. 我在页面中有一个图库,您可以在其中单击加号和减号来添加和删除图库项目,然后将文件添加到该新添加项目的输入中。

I have created a file reader to get the files url but it only works on the first element on that page, anything added after that dynamically is not affected. 我创建了一个文件读取器来获取文件的url,但它仅适用于该页面上的第一个元素,在此之后动态添加的任何内容均不受影响。

here is my JS: 这是我的JS:

$('#gallery .gallery-item .file_upload').each(function() {
    var $this = $( this );
    //$('body').on('click', 'input', function() {
    $this.on( 'change', 'input', function(evt){
        var files = evt.target.files;
        var file = files[0];
        console.log(files[0]);
        var reader = new FileReader();
        reader.onload = (function(file) {
            return function(e) {
                console.log(e.target.result);
            };
        })(file);
        reader.readAsDataURL(file);
    });
  });

The append gallery item function: 追加画廊项目功能:

$('#gallery')
    .on('cocoon:before-insert', function(e,image_field) {
        image_field.insertAfter( $(this).next() );
    })
    .on('cocoon:after-remove', function(e, image_field) {
        $(this).data('remove-timeout', 1000);
        image_field.fadeOut('slow');
});

    $('.gallery-item').each(function() {
        $(this).next('a.add_fields').appendTo(this);
        $(this).next('input').appendTo(this);
    });

HTML: HTML:

<div class="image-field">
            <div class="file_upload">
                <input class="image_file" id="gallery_files" name="book[gallery_attributes][images_attributes][1412768497650][file]" type="file">
            </div>
        </div>

Can anyone tell me why the .each function will not work with this .on function for the newer items that are appended. 谁能告诉我为什么对于附加的较新项目,.each函数不能与该.on函数一起使用。 I think it is the top most function thats obviously not working here and not the others below. 我认为这是最主要的功能,显然在这里不起作用,而在下面则不起作用。

You've correctly identified that you need to use event delegation because you have dynamically added elements on your page. 您已正确确定需要使用事件委托,因为已在页面上动态添加了元素。 The problem is that event delegation works on an element that exists when the code runs , and you're using an .each() loop to iterate over a collection that you expect to contain your dynamically added elements (which it won't because they don't currently exist). 问题是事件委托在代码运行时存在的元素上起作用,并且您正在使用.each()循环遍历您希望包含动态添加的元素的集合(它不会,因为它们目前不存在)。

Essentially, the problem is the initial selector $('#gallery .gallery-item .file_upload') . 本质上,问题在于初始选择器$('#gallery .gallery-item .file_upload')

The .gallery-item .file_upload part of that selector is part of what identifies the dynamic elements for event delegation, so you need to use something more like this: 该选择器的.gallery-item .file_upload部分是标识用于事件委派的动态元素的一部分,因此您需要使用以下类似内容:

$('#gallery').on('change', '.gallery-item .file_upload input', function(e) {
    // your code here
});

I've taken out the call to .each() because it's redundant; 我已经取消了对.each()的调用,因为它是多余的; .on() iterates over the set of matched elements already, and your $('#gallery') selector should only match a single element anyway. .on()遍历了匹配的元素集,并且您的$('#gallery')选择器无论如何应该只匹配单个元素。

Note: You've used .gallery-item in the selector, but there's only an image-field class in the HTML you provided. 注意:您在选择器中使用了.gallery-item ,但是您提供的HTML中只有一个image-field类。 That may or may not be an issue depending on exactly what the page looks like, since you haven't provided that information I've had to guess. 取决于页面的确切外观,这可能是问题,也可能不是问题,因为您没有提供我不得不猜测的信息。

Why are you even using .each() ? 为什么还要使用.each() All you need to make it work is using the selector since jQuery already will loop all of the selected items to .on() 您需要做的就是使用选择器,因为jQuery已经将所有选定项循环到.on()

$('#gallery .gallery-item .file_upload').on( 'change', 'input', function(evt){
        var files = evt.target.files;
        var file = files[0];
        console.log(files[0]);
        var reader = new FileReader();
        reader.onload = (function(file) {
            return function(e) {
                console.log(e.target.result);
            };
        })(file);
        reader.readAsDataURL(file);
});

The problem is that each is taking the curently existing inputs from the gallery unless you are looping everytime you are appending new items but then you will bind the handler alot of times on the same element. 问题在于,除非您每次都在添加新项目时都进行循环,否则每个项目都会从图库中获取当前已有的输入,但是您将在同一元素上多次绑定处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM