多个使用ajax动态创建的同名按钮
Posted
技术标签:
【中文标题】多个使用ajax动态创建的同名按钮【英文标题】:multiple dynamically created buttons with same name using ajax 【发布时间】:2018-05-22 07:12:07 【问题描述】:我正在尝试实现一个评论部分,按下按钮后我想用 ajax 更新评论部分,这样页面就不必刷新......
在这个评论部分,我有 1 个文本区域 + 1 个按钮 + 每个评论的几个隐藏字段,因此用户可以回答特定的 cmets...
因此,如果有 50 个 cmets,则还有 50 个答案字段,每个字段 1 个...
除了 1 件事之外,所有的事情都有效... - 要么我将按钮和字段的所有 id 命名为相同的名称(即 id="sendAnswer" 和 id="answer", id="userID", ...),然后只有第一个有效... - 或者我动态地将它们全部命名(即 id="sendAnswer(echo $i) ),从而将它们全部命名为 id="sendAnswer0", "sendAnswer1", "sendAnswer2", ... 然后我为 textarea 和隐藏字段(即 id="answer(echo $i), id="userID(echo $i), ...)
这也很好用......除了现在我必须为每个人制作一个 jQuery 脚本......而且由于它们是动态创建的,这很困难 - 因为随着更多 cmets 的加入,会有多少变化......
方法 1 的代码:将它们命名相同...
$(document).ready(function()
"use strict";
$("#sendAnswer").click(function()
var comment = $("#comment").val();
var userID = $("#userID").val();
var randomStringVideo = $("#randomStringVideo").val();
var commentID = $("#commentID").val();
$.ajax(
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function()
$("#commentDiv").load(location.href + " #commentDiv>*", "");
$("#commentsDiv").load(location.href + " #commentsDiv>*", "");
$("#comment").val('');
);
);
);
正如我所说...这对第一个很好,其余的都是哑弹...
方法 2 的代码:我动态命名所有值...
$(document).ready(function()
"use strict";
$("#sendAnswer"+$(this).val()).click(function() // this +$(this).val() doesn't work, only if I put #sendAnswer3 - then the 4th works and the rest are duds etc.
var comment = $("#comment"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var userID = $("#userID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var randomStringVideo = $("#randomStringVideo"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var commentID = $("#commentID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
$.ajax(
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function()
$("#commentDiv").load(location.href + " #commentDiv>*", "");
$("#commentsDiv").load(location.href + " #commentsDiv>*", "");
$("#comment"+$(this).val()).val(''); // this +$(this).val() doesn't work, only if I put #comment3 (matching the #sendAnswer)- then the 4th works and the rest are duds etc.
);
);
);
有了这个,我必须命名每一个可能的#sendAnswer-number + #comment-number 才能让它工作......并且有一组无限的数字可以从 0-(无限)中选择 - 这是不可行的.. .
如果有任何兴趣... 动态创建相关按钮和字段的 PHP
.
.
.
<?php if ($_SESSION[numberOfComments] != 0)
for ($i=0; $i<$_SESSION[numberOfComments]; $i++) ?> // run through all comments that aren't answers to other comments
// show comment info
<div class="media">// answer comment box starts here
<img class="mr-3 rounded" src="<?php $file = USER . $_SESSION['randomString'] . THUMBNAIL; if ( file_exists ( $file ) ) echo $file; else echo USER . "default" . THUMBNAIL; ?>" data-toggle="tooltip" data-placement="left" title="<?php echo $_SESSION['username']; ?>">
<div class="media-body">
<textarea class="form-control" rows="2" type="text" name="comment<?php echo $i; ?>" id="comment<?php echo $i; ?>" value="" placeholder="Great video!"></textarea>
<input type="hidden" name="userID<?php echo $i; ?>" id="userID<?php echo $i; ?>" value="<?php if ( isset ( $_SESSION['id'] ) ) echo $_SESSION['id']; ?>">
<input type="hidden" name="randomStringVideo<?php echo $i; ?>" id="randomStringVideo<?php echo $i; ?>" value="<?php echo $_GET['v']; ?>">
<input type="hidden" name="commentID<?php echo $i; ?>" id="commentID<?php echo $i; ?>" value="<?php echo $_SESSION['commentID_getComment']; ?>">
<button type="button" class="btn btn-primary float-right margin-top-5" id="sendComment<?php echo $i; ?>" value="<?php echo $i; ?>">
Answer
</button>
</div>
</div> // answer comment box ends here
<?php if ($_SESSION[numberOfAnswers][$i] != 0)
for ($j=0; $j<$_SESSION[numberOfAnswers][$i]; $j++) ?> // run through all answer to this comment
// show answer info
<?php
?>
.
.
.
【问题讨论】:
那么button
和#commentDiv
是什么关系?
按钮'调用' ajax...和#commentDiv id 包含所有 cmets 的 div - - 显示所有 cmets - ajax 正在刷新它...
【参考方案1】:
两种方式 .. 第一种使用类而不是 ids .OR。第二次使用选择器 id 以 [id^="something"]
开头 .. 在这两种方式上,您都需要使用 $(this)
来引用同一部分.. 对我来说,使用 .load()
刷新整个评论部分是不好的做法,您可以直接获取特定评论并将其附加到#commentDiv
在这种情况下,通过使用 $("#sendAnswer"+$(this).val())
$(this)
来引用任何内容/窗口或其他内容,但不要引用您的元素
$(document).ready(function()
"use strict";
$('button[id^="sendAnswer"]').on('click',function()
var ThisIs = $(this);
var ClosestDiv = ThisIs.closest('.media-body');
var comment = ClosestDiv.find('textarea').val();
var userID = ClosestDiv.find('[id^="userID"]').val();
var randomStringVideo = ClosestDiv.find('[id^="randomStringVideo"]').val();
var commentID = ClosestDiv.find('[id^="commentID"]').val();
$.ajax(
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function()
var commentDiv = ThisIs.closest('.BigDiv').find('[id^="commentDiv"]'); // change `.BigDiv` with the div id/class which hold both commentDiv and comment section
commentDiv.load(location.href + " #commentDiv>*", "");
ClosestDiv.find('textarea').val('');
);
);
);
注意: 将
.BigDiv
更改为同时包含两者的 div id/class commentDiv 和评论部分
【讨论】:
@mohammed-Yousef - 谢谢你这行得通……唯一的事……comment.val('');不清除文本区域(评论)...但更改为 $("#comment").val('');它有效(在您的答案中更改它以获取您的投票和复选标记以及我永恒的感激,呵呵)......唯一的事情是......在我发布了一个答案(这就像一个魅力)之后,我必须刷新整个页面以发布另一个答案...有没有办法避免这种情况? @APM 和关于刷新整个页面 .. 正如我在回答中所说,为您的评论/答案提供参考,然后使用 ajaxdata:
发送它以获取特定的评论/答案,然后将其附加到它的部分
@APM 您需要将其更改为 ClosestDiv.find('textarea').val('') 而不是 $("#comment").val('');
@Mohammed-Yousef 成功了... tnx... 答案被接受并且赞成票是你的 :) - tnx 一堆...
不客气@APM 我也赞成你的问题祝你有美好的一天:)【参考方案2】:
使用您当前的方法,其中所有内容都用id
s 标识,最好的选择是使用event delegation。在页面加载时存在的某个父元素上仅创建一个事件处理程序,通过委托将处理您的任何按钮 - 现有的和未来的。处理程序触发后,您可以确定您正在使用哪一组元素,然后照常继续。
这是一个示例,使用body
作为父级,但您可以使用包含所有当前和未来按钮/输入的任何元素,例如,也许您有一个父级<div id="something">
。这也假设您的按钮输入是实际的 button
元素,如果不是这种情况,您将不得不进行调整:
$(document).ready(function()
"use strict";
// A single event handler on body, which handles any child button
$("body").on('click', 'button', function(event)
// $(this) will be the button that was clicked. We can find its id,
// and if your buttons all have ids like sendAnswer1, sendAnswer2,
// sendAnswerX, we can find the X
var id = $(this).attr('id').replace('sendAnswer', '');
// Now we can use the X to access each of this button's matching
// inputs etc. Again this assumes your other elements have ids like
// commentX.
var comment = $("#comment" + id).val(),
userID = $("#userID" + id).val(),
// ... etc, rest of your code
与上面链接的the article 一样,the jQuery .on()
docs 对事件委托有很好的描述(请参阅“直接和委托事件”)。
更新
另一个我觉得更简洁的选择是将每个评论部分包装在一个 div 中(或任何标识元素,这样每个评论/输入/按钮集都嵌套在其中),并且每个元素只使用类。再次使用事件委托,您可以找到包含被单击按钮的部分,从而确定您正在使用哪些输入元素。
例如,您的 html 可能如下所示:
<div id="all-comments">
<div class="comment-section">
<textarea class="comment" name="whatever"> ... </textarea>
<button name="button" type="submit">Post!</button>
<!-- your hidden fields, etc -->
</div>
<div class="comment-section">
...
</div>
<!-- ... etc, many comment sections -->
</div>
现在你的 JS 看起来像这样:
$(document).ready(function()
"use strict";
// A single event handler on the parent div, which handles any child button
$("#all-comments").on('click', 'button', function(event)
// $(this) will be the button that was clicked. We need to find the
// .comment-section containing that button
var div = $(this).closest('div.comment-section');
// Now we can find all elements inside that particular section
var comment = $(".comment", div).val(),
userID = $(".userID", div).val(),
// ... etc, rest of your code
【讨论】:
以上是关于多个使用ajax动态创建的同名按钮的主要内容,如果未能解决你的问题,请参考以下文章
使用 ImageView 动态创建多个 EditText 并将 ImageView 点击值设置为 EditText 并从 EditText 获取值