给打赏弹窗进行美化 教程
改动位置
/fox_reward/oddfox/theme/fox_reward.php
<?php !defined('DEBUG') AND exit('Access Denied.');include _include(APP_PATH.'view/htm/header.inc.htm');?>
<div class="container py-4 d-flex justify-content-center">
<!-- 外层卡片,保持整体框架 -->
<div class="card border shadow-sm" style="max-width: 480px; width: 100%; border-radius: 8px;">
<!-- 卡片头部 -->
<div class="card-header bg-white border-bottom px-4 py-3" style="border-radius: 8px 8px 0 0;">
<h5 class="mb-0 text-primary">投币</h5>
</div>
<!-- 卡片主体 -->
<div class="card-body ajax-body px-4 py-3">
<?php if(!empty($user['uid'])){?>
<form action="<?php echo url("thread-reward-$thread[tid]");?>" method="post" id="mod_reward_form">
<!-- 我的金币(显示在最顶上) -->
<div class="mb-4">
<div class="input-group border rounded" style="border-radius: 6px;">
<div class="input-group-prepend w-25">
<span class="input-group-text w-100 bg-light border-0">我的金币</span>
</div>
<div class="form-control bg-white border-0 text-danger font-weight-medium"><?php echo $user['golds'];?> 枚</div>
</div>
</div>
<!-- 打赏金额卡片区域 -->
<div class="mb-4">
<p class="text-muted mb-2">选择打赏金额</p>
<!-- 第一行:5、20、40(正方形卡片+$图标贴合) -->
<div class="d-flex justify-content-between mb-3">
<?php
$row1Configs = [
['amount' => 5, 'desc' => '鼓励一下'],
['amount' => 20, 'desc' => '内容不错'],
['amount' => 40, 'desc' => '很有帮助']
];
foreach($row1Configs as $config){
$isDisabled = $config['amount'] > $user['golds'];
$disabledClass = $isDisabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';
$dataAttr = $isDisabled ? '' : "data-amount='{$config['amount']}'";
?>
<div class="w-30" style="width: 100px !important;">
<div class="reward-card border rounded-3 d-flex flex-column justify-content-center align-items-center <?php echo $disabledClass;?>"
<?php echo $dataAttr;?>
style="width: 100%; height: 100px; border-radius: 12px; transition: all 0.3s; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
<!-- 修复$图标贴合:移除mr-1,用span包裹确保仅在金额前显示 -->
<span class="font-weight-bold fs-5"><span class="text-primary">$</span><?php echo $config['amount'];?></span>
<div class="text-xs text-muted mt-1"><?php echo $config['desc'];?></div>
</div>
</div>
<?php }?>
</div>
<!-- 第二行:60、80、自定义(正方形卡片+$图标贴合) -->
<div class="d-flex justify-content-between">
<?php
$row2Configs = [
['amount' => 60, 'desc' => '强烈推荐'],
['amount' => 80, 'desc' => '支持作者']
];
foreach($row2Configs as $config){
$isDisabled = $config['amount'] > $user['golds'];
$disabledClass = $isDisabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer';
$dataAttr = $isDisabled ? '' : "data-amount='{$config['amount']}'";
?>
<div class="w-30" style="width: 100px !important;">
<div class="reward-card border rounded-3 d-flex flex-column justify-content-center align-items-center <?php echo $disabledClass;?>"
<?php echo $dataAttr;?>
style="width: 100%; height: 100px; border-radius: 12px; transition: all 0.3s; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
<!-- 修复$图标贴合:移除mr-1,用span包裹确保仅在金额前显示 -->
<span class="font-weight-bold fs-5"><span class="text-primary">$</span><?php echo $config['amount'];?></span>
<div class="text-xs text-muted mt-1"><?php echo $config['desc'];?></div>
</div>
</div>
<?php }?>
<!-- 自定义金额卡片(正方形样式) -->
<div class="w-30" style="width: 100px !important;">
<div class="reward-card border rounded-3 d-flex flex-column justify-content-center align-items-center cursor-pointer"
id="custom-amount-card"
style="width: 100%; height: 100px; border-radius: 12px; transition: all 0.3s; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
<span class="font-weight-bold fs-5">自定义</span>
<div class="text-xs text-muted mt-1">自由打赏</div>
</div>
</div>
</div>
<!-- 自定义金额输入框(修复多次开关弹窗后无法输入的问题) -->
<div class="mt-3" id="custom-amount-input" style="display: none;">
<div class="input-group border rounded-3" style="border-radius: 12px; max-width: 320px; margin: 0 auto;">
<div class="input-group-prepend">
<span class="input-group-text bg-light border-0 text-primary rounded-start-3">$</span>
</div>
<!-- 修复输入问题:移除inline事件,改用JS动态绑定(避免多次渲染冲突) -->
<input type="number" class="form-control border-0 shadow-none rounded-end-3"
id="custom-golds"
name="custom_golds"
placeholder="输入金额(1-<?php echo $user['golds'];?>枚)"
min="1"
max="<?php echo $user['golds'];?>">
<div class="form-text text-danger mt-1" id="custom-gold-tip" style="display: none;"></div>
</div>
</div>
<!-- 隐藏域:存储选中的打赏金额 -->
<input type="hidden" name="golds_num" id="golds_num" value="" required>
</div>
<?php if(!empty($user['uid'])){?>
<!-- 新增:自定义金额输入逻辑(动态绑定事件,解决多次弹窗冲突) -->
<script ajax-eval="true">
// 页面加载/弹窗打开时初始化自定义金额输入事件
function initCustomGoldInput() {
const $customGolds = $('#custom-golds');
const maxGolds = <?php echo $user['golds'];?>;
const $tip = $('#custom-gold-tip');
const $goldsNum = $('#golds_num');
// 先解绑已有事件,避免多次绑定冲突(解决弹窗多次开关问题)
$customGolds.off('keydown input');
// 1. 禁止输入e/E/+/-
$customGolds.on('keydown', function(e) {
const forbiddenKeys = ['e', 'E', '+', '-'];
if (forbiddenKeys.includes(e.key)) {
e.preventDefault();
return false;
}
return true;
});
// 2. 实时过滤非数字+限制最大金额
$customGolds.on('input', function() {
let val = $(this).val().trim();
// 过滤非数字
val = val.replace(/\D/g, '');
// 限制最大金额
if (val && parseInt(val) > maxGolds) {
val = maxGolds.toString();
$tip.text(`金额不能超过${maxGolds}枚`).show();
} else if (val && parseInt(val) < 1) {
val = '1';
$tip.text('金额不能小于1枚').show();
} else {
$tip.hide().text('');
}
// 更新输入框和隐藏域值
$(this).val(val);
$goldsNum.val(val);
});
// 3. 选中自定义卡片时聚焦输入框(确保每次打开都能输入)
$('#custom-amount-card').off('click').on('click', function() {
$customGolds.focus().select(); // 聚焦并选中内容,方便重新输入
});
}
// 页面初始加载时执行
$(document).ready(function() {
initCustomGoldInput();
// 若弹窗是动态加载,需在弹窗显示后重新执行(如之前优化的initRewardEvents中调用)
// 示例:在弹窗shown.bs.modal事件中添加 initCustomGoldInput();
});
</script>
<?php }?>
<!-- 自定义打赏理由(圆润风格同步) -->
<div class="mb-4">
<div class="input-group border rounded-3" style="border-radius: 12px;">
<div class="input-group-prepend w-25">
<span class="input-group-text w-100 bg-light border-0 rounded-start-3">打赏理由</span>
</div>
<input type="text" class="form-control border-0 shadow-none rounded-end-3"
name="reason" id="reason" maxlength="30"
value="<?php echo $default_reason;?>" required
placeholder="请输入打赏理由(最多30字)">
</div>
</div>
<!-- 按钮区域(圆润风格同步) -->
<div class="d-flex justify-content-center gap-3 pt-2">
<button type="button" class="btn btn-primary px-5 py-2 rounded-3"
id="mod_reward_submit" data-loading-text="<?php echo lang('submiting');?>...">
确认
</button>
<button type="button" class="btn btn-secondary px-5 py-2 rounded-3" data-dismiss="modal">
取消
</button>
</div>
</form>
<?php }else{?>
<!-- 未登录状态(圆润风格同步) -->
<div class="text-center py-5 border rounded-3" style="border-radius: 12px;">
<div class="mb-3 text-muted">请先登录后投币</div>
<div class="d-flex justify-content-center gap-3">
<a class="btn btn-primary px-5 py-2 rounded-3" href="<?php echo url('user-login');?>">
<<i class="icon-user"></i> <?php echo lang('login');?>
</a>
<a class="btn btn-success px-5 py-2 rounded-3" href="<?php echo url('user-create');?>">
<<i class="icon-user"></i> <?php echo lang('register');?>
</a>
</div>
</div>
<?php }?>
</div>
</div>
</div>
<?php include _include(APP_PATH.'view/htm/footer.inc.htm');?>
<?php if(!empty($user['uid'])){?>
<script ajax-eval="true">
var globalJmodal = null;
// 初始化样式
$(document).ready(function() {
$('#custom-amount-input').hide();
// 默认选中第一个金额卡片(5金币)
$('.reward-card').first().addClass('border-primary bg-primary bg-opacity-5 shadow-sm');
$('#golds_num').val($('.reward-card').first().data('amount'));
});
function initRewardEvents() {
// 金额卡片点击事件(选中时阴影增强,更有层次感)
$(document).off('click', '.reward-card').on('click', '.reward-card', function() {
var $this = $(this);
var amount = $this.data('amount');
// 重置所有卡片样式
$('.reward-card').removeClass('border-primary bg-primary bg-opacity-5 shadow-sm').addClass('shadow');
// 选中当前卡片:加深边框+背景色+增强阴影
$this.addClass('border-primary bg-primary bg-opacity-5 shadow-sm').removeClass('shadow');
// 处理自定义金额与固定金额的切换
if ($this.attr('id') === 'custom-amount-card') {
$('#custom-amount-input').show();
$('#golds_num').val('');
$('#custom-golds').focus();
} else {
$('#custom-amount-input').hide();
$('#golds_num').val(amount);
}
});
// 自定义金额输入事件
$(document).off('input propertychange', '#custom-golds').on('input propertychange', '#custom-golds', function() {
this.value = this.value.replace(/\D/g, '');
if (this.value.length > 3) this.value = this.value.slice(0, 3);
$('#golds_num').val(this.value);
});
// 确认提交按钮事件
$(document).off('click', '#mod_reward_submit').on('click', '#mod_reward_submit', function() {
var jsubmit = $(this);
if (jsubmit.prop('disabled')) return;
var jmodal = globalJmodal || $('.modal.show').first();
var jform = $("#mod_reward_form");
var jgolds_num = $("#golds_num");
var jreason = $("#reason");
jsubmit.attr("disabled", "disabled");
jsubmit.button('loading');
// 验证金额
var goldsVal = parseInt(jgolds_num.val());
if (isNaN(goldsVal) || goldsVal < 1) {
$.alert('请选择或输入有效的打赏金额(至少1枚)!');
resetButtonState();
return false;
}
// 验证理由
if (jreason.val().trim() === '' || jreason.val().trim().length > 30) {
$.alert('请填写1-30字的打赏理由!');
resetButtonState();
return false;
}
var postdata = jform.serialize();
$.xpost(jform.attr('action'), postdata, function(code, message) {
resetButtonState();
$.alert(message, 1);
if (code === 0) {
setTimeout(function() {
closeModal(jmodal);
$('#fox_reward').load(' #fox_reward_load', function() {
initRewardTrigger();
});
}, 1000);
}
}).fail(function() {
resetButtonState();
$.alert('网络请求失败,请稍后重试', 1);
});
function resetButtonState() {
jsubmit.removeAttr("disabled");
jsubmit.button('reset');
}
});
// 取消按钮事件
$(document).off('click', '.btn-secondary[data-dismiss="modal"]').on('click', '.btn-secondary[data-dismiss="modal"]', function() {
var jmodal = globalJmodal || $(this).closest('.modal');
closeModal(jmodal);
});
}
function initRewardTrigger() {
$(document).off('click', '.reward-trigger').on('click', '.reward-trigger', function() {
var modalUrl = $(this).data('url') || "<?php echo url("thread-reward-$thread[tid]");?>";
$('#modal-container').load(modalUrl, function() {
globalJmodal = $('#modal-container .modal').first();
if (globalJmodal.length) {
globalJmodal.modal('show');
initRewardEvents();
}
});
});
}
function closeModal(jmodal) {
if (jmodal && typeof jmodal.modal === 'function') {
jmodal.modal('hide');
setTimeout(function() {
jmodal.modal('dispose');
globalJmodal = null;
}, 300);
}
$('body').removeClass('modal-open').removeAttr('style');
$('.modal-backdrop').remove();
}
// 页面加载完成后初始化事件
$(document).ready(function() {
initRewardEvents();
initRewardTrigger();
});
</script>
<?php }?>
暂无评论