You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Blade循环渲染场景下JavaScript动态复制对应输入框值异常问题求助

问题分析

你遇到的问题核心是循环中重复定义同名JavaScript函数导致的覆盖问题:每次Blade循环都会输出一个copy()函数,后面的函数会完全覆盖前面的,所以不管点击哪个区块的复制按钮,最终执行的都是最后一次循环生成的copy()函数,自然只会复制最后一个输入框的值。

虽然你给每个输入框设置了唯一的id,但重复定义函数的问题才是触发bug的关键。

解决方案

下面提供几种简洁可靠的解决办法,按推荐度排序:

方法1:将函数移出循环,通过参数传递目标ID

把copy()函数从循环里抽出来(放到页面的<head>或者页面底部,只定义一次),然后在按钮的onclick里传入当前区块输入框的唯一ID:

修改后的Blade代码:

{{-- 把函数放在循环外,比如页面底部 --}}
<script>
function copy(walletId) {
    const copyText = document.getElementById(walletId);
    copyText.select();
    copyText.setSelectionRange(0, 99999); // 适配移动端选中文本
    navigator.clipboard.writeText(copyText.value);
    alert("Copied the text: " + copyText.value);
}
</script>

{{-- 循环内的代码 --}}
@foreach($methods as $method)
<form action="{{ route('user.account.deposit') }}" method="post">
    @csrf
    <p>Please input amount USD worth of {{ Cryptocap::getSingleAsset(strtolower($method->name))->data->symbol }} to deposit and send the exact same amount to the wallet address below, before clicking submit.</p>
    <div class="input-group">
        <input type="number" class="form-control" name="amount">
    </div>
    <div class="input-group">
        <input type="text" class="form-control" value="{{ $method->wallet_address }}" id="{{ $method->name }}" name="wallet_address" readonly>
    </div>
    <input type="hidden" value="{{ $method->id }}" name="payment_method_id">
    <br>
    <button type="submit" class="btn green">Deposit</button>
    {{-- 这里把当前输入框的ID传给copy函数 --}}
    <a href="javascript:void(0)" class="btn btn-primary btn-xs" onclick="copy('{{ $method->name }}')">Copy to Clipboard</a>
</form>
@endforeach

方法2:利用DOM关系,无需ID(更灵活)

如果不想依赖ID,可以通过按钮的DOM上下文找到对应的输入框,比如找按钮所在表单里的readonly输入框,或者通过父元素定位:

修改后的代码:

{{-- 同样把函数放在循环外 --}}
<script>
function copyBtnClick(btn) {
    // 找到当前按钮所在表单里的钱包地址输入框
    const copyText = btn.closest('form').querySelector('input[name="wallet_address"]');
    copyText.select();
    copyText.setSelectionRange(0, 99999);
    navigator.clipboard.writeText(copyText.value);
    alert("Copied the text: " + copyText.value);
}
</script>

{{-- 循环内的按钮修改 --}}
<a href="javascript:void(0)" class="btn btn-primary btn-xs" onclick="copyBtnClick(this)">Copy to Clipboard</a>

这种方法的好处是不用维护唯一ID,即使后续HTML结构调整,只要按钮和输入框在同一个表单里,就能正常工作。

方法3:事件委托(最优雅,适合大量区块)

如果页面上有很多这样的区块,推荐用事件委托,只绑定一次事件,性能更好,后续动态添加的区块也能自动生效:

<script>
document.addEventListener('DOMContentLoaded', function() {
    // 给整个文档绑定点击事件
    document.addEventListener('click', function(e) {
        // 判断点击的是复制按钮
        if (e.target.classList.contains('btn-primary') && e.target.textContent.includes('Copy to Clipboard')) {
            const copyText = e.target.closest('form').querySelector('input[name="wallet_address"]');
            copyText.select();
            copyText.setSelectionRange(0, 99999);
            navigator.clipboard.writeText(copyText.value);
            alert("Copied the text: " + copyText.value);
        }
    });
});
</script>

{{-- 循环内的按钮可以去掉onclick属性 --}}
<a href="javascript:void(0)" class="btn btn-primary btn-xs">Copy to Clipboard</a>
为什么原来的代码不行?

在Blade循环中,每次都会输出一个function copy() {...},而JavaScript中同名的函数会被后面的覆盖。比如循环生成3个区块,最终页面上只会保留最后一个copy()函数,它里面的{{ $method->name }}是最后一个方法的名称,所以不管点哪个按钮,都会去找最后一个输入框的值。

内容的提问来源于stack exchange,提问作者Morri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:47:36