使用repentwith()方法来定位ID和变量



因此,我的jQuery代码工作如下:当单击默认图标并加载图像时,它替换了单击的默认图标。(有2个默认图标,带有隐藏的文件输入(。我能够通过针对默认图标的class名称.border来实现此功能,但是由于某种原因,我无法用父级的ID名称 [整数变量] -#bd1#bd2来定位。您能帮我让我的代码工作,以便我能够按ID名称 [整数变量]定位?

在JSFiddle中运行代码,看来这里有两个单独的问题:

问题#1:事件传播

您的点击事件有一个事件冒泡的问题(与您的jQuery选择器无关(。

单击父 .border时,它会触发一个单击孩子.imginp。当您触发单击子元素时,再次触发了父级的事件侦听器。这会创建一个无限的循环,在该循环中,单击事件侦听器在父母上触发一个单击的孩子,该孩子触发父母点击事件侦听器等...这会导致RangeError: Maximum call stack size exceeded

这是您在控制台中也看到的行为吗?

这是由于JavaScript中的事件冒泡而发生的。首先,单击.imginp是由该元素处理的,然后由其父母处理,然后由祖父母等,依此类推,直到到达window元素为止。这意味着,即使目标是.imginp元素,也会在.border元素上点击。这就是将代码变为循环状态的原因。

您可以通过在孩子上添加听众来将事件的传播停止给父母:

$('#inp'+a).click(function (e) {
   e.stopPropagation();
});

问题2:变量范围

这与您的jQuery选择器有关。具体来说,您使用循环变量a和执行change事件回调的选择器使用。

这里发生的事情的快速示例。

for (var i = 0; i < 3; i++){
    setTimeout(function() {
        console.log(i)
    }, 100)
}

乍一看看到此代码时,您可能希望它可以记录0, 1,2。相反,它将记录3,3,3。这是因为到超时函数运行时,a的值为3。

这正是代码$('#bd'+a).replaceWith(template);中此行的情况。如果您在此处添加console.log,则可以在行动中看到此行为。在执行时,这里的a的值不是1或2,而是3。这是因为它使用了a的最新值,而不是定义函数时a的值。

这与JavaScript中事件循环的行为有关。当执行change回调并评估#bd + a时,a的值是3。我们可以使用闭合来解决此问题,该封闭使我们能够在 a的值中"关闭"函数声明时的 CC_24值。循环。这是一个很好的示例,说明如何与循环中定义的异步函数一起使用闭合。

es6提供了如何防止此问题的另一种选择。关键字let使我们能够对变量具有块级别范围。这意味着,我们可以在循环中使用它来定义每个循环的a,并在其中定义的块级别范围范围范围范围范围范围范围范围。您会这样使用:

for (let a = 1; a < 3; a++) {...}

这具有额外的好处,还可以修复当前编写的循环方式:以a作为全局变量。这通常是不可取的,如果您在代码中其他地方定义或使用可变的a,可能会产生意外的后果。

最终代码:

for (let a = 1; a < 3; a++) {
    $("#bd"+a).click(function(e) {
        $(this).children(".imginp").click()
    });
    $('#inp'+a).click(function (e) {
       e.stopPropagation();
    });
    $('#inp'+a).on('change', function(e){
      var files = e.target.files;
      $.each(files, function(i, file){
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e){
            template = 
            '<div class="border">'+
                '<input id="inp'+a+'" class="imginp" type="file" hidden>'+
            '<img class="blah" src="'+e.target.result+'">'+
            '</div>';
            $('#bd'+a).replaceWith(template);
        };
      });
    });
}

最新更新