неоконченные события jquery
Доброго времени суток.
Пишу комментарии с ответами, наткнулся на ошибку которую не понимаю и не знаю как решить. Ошибка заключается в дублировании функций либо событий либо неоконченного события. Пример: подгружается комментарий на страницу с помощью события on('click') в html есть кнопка 'ответить' но, она не срабатывает, я думал что при on() должно срабатывает. Далее я добавил после загрузки комментария на страницу функцию для того чтобы срабатывало события для нового комментария. При этом появилась проблема дублировании комментарий и событий, в ajax я это исправил чуть, добавил async:false при этом добавляется один комментарий, а остальные пишутся как ошибки. Чтобы было Вам понятно мой рассказ я сделал тестовую страницу http://test.altme.org.ua/test_comm.php попробуйте добавлять ответы на новых комментариях, потом на старых... короч попробуйте поюзать и поймете в чем дело, сам код js в исходном страницы можно увидеть. Если много раз нажать на 'ответить' - то сколько раз Вы нажали сколько и отправится p.s. смотрите консоль |
Вроде везде комменты добавляются нормально, только немного с анимацией проблемы.
|
комментарии добавляются, но чуть не правильно, в анимации и дело, если смотреть на анимацию и открыть консоль видно сколько раз она запускается. Я сейчас уберу async:false, перейдите еще раз на страницу по нажимайте несколько раз по иконке ответить, и после чего напишите ответ и отправьте..
|
А ну понятно, ты после получения ответа от сервера вешаешь еще один обработчик на все эти элементы. Убери строку после коммента об альтернативе, задай диву, в котором все комменты, класс и делай примерно так:
$(".тот_самый_класс").on('click', ".reply", mat_reply);
|
не совсем понял, в success: вообще не должно быть $('.reply').on('click',mat_reply); ?
и такой тот самы класс ? я просто не понимаю как работает on() читал куча инфы и так и не понял.. |
Добавь класс(например .wrap-comments) диву, который содержит все комментарии(у которого маргин-топ: 40пкс).
И поменяй js примерно так:
$(document).ready(function() {
var template_path = "http://test.altme.org.ua/altme/template/altme_1";
$('.send_new_comment').on('click', function() {
var message = $('.new_comment').val();
var id_mat = $(this).attr('id_mat');
$.ajax({
type: "POST",
url: template_path+"/function_php/all_function.php?page=material&type=send_new_commet",
dataType: "json",
async:false,
data: {
message:message,
id_mat:id_mat
},
success: function (data) {
if(data['status']=='true'){
$('.new_comment').val('');
$('.event_other').removeClass('red').addClass('green').text('Успешно оставлен комментарий!').fadeIn().delay(3000).fadeOut();
$('.new_comment_add').prepend(data['text'])
.children()
.css({backgroundColor:"rgba(255,237,116,0.2)"})
.animate({backgroundColor:"rgba(255,255,255,0)"},4000)
.fadeIn();
$('.reply').on('click',mat_reply);
}else{
$('.event_other').removeClass('green').addClass('red').text(data['text']).fadeIn().delay(3000).fadeOut();
}
}
});
return false;
});
function mat_reply(){
var reply = $(this);
var slide = $(reply).parent().parent().parent().children('.add_commnet');
$(slide).stop().toggleClass('open');
if($(slide).hasClass('open')){
$(slide).slideDown('fast');
console.log("open");
}else{
$(slide).slideUp('fast');
//event.preventDefault();
//event.stopPropagation();
//event.stopImmediatePropagation();
//$(reply).off('click',mat_reply);
console.log("close");
}
$(reply).parent().parent().parent()
.children('.add_commnet')
.children('.send_reply_comment')
.on('click', function() {
var message = $(this).parent().children('.reply_comment').val();
var id_mat = $(reply).attr('id_mat');
var id_mat_id = $(reply).attr('id_mat_id');
$.ajax({
type: "POST",
url: template_path+"/function_php/all_function.php?page=material&type=send_reply_commet",
dataType: "json",
async:false,
data: {
message:message,
id_mat:id_mat,
id_mat_id:id_mat_id
},
success: function (data) {
console.log("ajax done");
if(data['status']=='true'){
$('.reply_comment').val('');
console.log('Успешно оставлен комментарий!');
$('.reply_comment_add[id_mat_id = '+id_mat_id+']').append(data['text'])
.children()
.css({backgroundColor:"rgba(255,237,116,0.1)"})
.animate({backgroundColor:"rgba(255,255,255,0)"},4000)
.fadeIn();
console.log("add: "+id_mat_id);
if($(slide).attr('class').match(/open/)){
$(slide).slideUp('fast');
}
var qw = $('.reply_comment_add[id_mat_id = '+id_mat_id+']').offset();
qw['top']=qw['top']-220;
$('html, body').animate({
scrollTop: qw.top
}, 1000);
//какая альтернатива ?
//------------тут убрал строку-------------
}else{
console.log(data['text']);
console.log("ошибка");
}
}
});
return false;
});
}
//---------И тут поправил---------------
$('.wrap-comments').on('click', '.reply', mat_reply);
});
|
добавил Ваш клас .wrap-comments, но при добавлении нового коммента/ответа, не работает событие
|
Не туда класс добавил, либо поставь куда надо(перечитай что я писал), либо просто убери его и сделай так:
$('.matrial_comments').on('click', '.reply', mat_reply); |
сработала так $('#matrial_comments').on('click', '.reply', mat_reply);
можете объяснить как оно работает и еще , как убрать дублирование комментов. При многократном нажимании на ответить, создаются много ответов ![]() |
Первый вопрос - это делегирование событий. Подробно как это реализуется и работает в нативном js - http://learn.javascript.ru/event-delegation.
А в jQuery это можно реализовать функцией .on(), если ей вторым параметром задать селектор отслеживаемого в родителе элемента при событии. На счет второго - я посмотрю. |
А ну опять дело в том же: при каждом нажатии у тебя соpздается новый обработчик для кнопки отправить (.send_reply_comment). Его нужно создавать не при нажатии на кнопку ответить, а одним обработчиком с делегированием.
Поправил, но особо не вникал,если в обработчике использовались внешние переменные из функции mat_reply, то работать будет криво, так что нужно будет разобраться с ними.
$(document).ready(function() {
var template_path = "http://test.altme.org.ua/altme/template/altme_1";
$('.send_new_comment').on('click', function() {
var message = $('.new_comment').val();
var id_mat = $(this).attr('id_mat');
$.ajax({
type: "POST",
url: template_path+"/function_php/all_function.php?page=material&type=send_new_commet",
dataType: "json",
async:false,
data: {
message:message,
id_mat:id_mat
},
success: function (data) {
if(data['status']=='true'){
$('.new_comment').val('');
$('.event_other').removeClass('red').addClass('green').text('Успешно оставлен комментарий!').fadeIn().delay(3000).fadeOut();
$('.new_comment_add').prepend(data['text'])
.children()
.css({backgroundColor:"rgba(255,237,116,0.2)"})
.animate({backgroundColor:"rgba(255,255,255,0)"},4000)
.fadeIn();
$('.reply').on('click',mat_reply);
}else{
$('.event_other').removeClass('green').addClass('red').text(data['text']).fadeIn().delay(3000).fadeOut();
}
}
});
return false;
});
function mat_reply(){
var reply = $(this);
var slide = $(reply).parent().parent().parent().children('.add_commnet');
$(slide).stop().toggleClass('open');
if($(slide).hasClass('open')){
$(slide).slideDown('fast');
console.log("open");
}else{
$(slide).slideUp('fast');
//event.preventDefault();
//event.stopPropagation();
//event.stopImmediatePropagation();
//$(reply).off('click',mat_reply);
console.log("close");
}
}
function send_reply_comment(){
var message = $(this).parent().children('.reply_comment').val();
var id_mat = $(reply).attr('id_mat');
var id_mat_id = $(reply).attr('id_mat_id');
$.ajax({
type: "POST",
url: template_path+"/function_php/all_function.php?page=material&type=send_reply_commet",
dataType: "json",
async:false,
data: {
message:message,
id_mat:id_mat,
id_mat_id:id_mat_id
},
success: function (data) {
console.log("ajax done");
if(data['status']=='true'){
$('.reply_comment').val('');
console.log('Успешно оставлен комментарий!');
$('.reply_comment_add[id_mat_id = '+id_mat_id+']').append(data['text'])
.children()
.css({backgroundColor:"rgba(255,237,116,0.1)"})
.animate({backgroundColor:"rgba(255,255,255,0)"},4000)
.fadeIn();
console.log("add: "+id_mat_id);
if($(slide).attr('class').match(/open/)){
$(slide).slideUp('fast');
}
var qw = $('.reply_comment_add[id_mat_id = '+id_mat_id+']').offset();
qw['top']=qw['top']-220;
$('html, body').animate({
scrollTop: qw.top
}, 1000);
}else{
console.log(data['text']);
console.log("ошибка");
}
}
});
return false;
}
$('.matrial_comments').on('click', '.reply', mat_reply);
$('.matrial_comments').on('click', '.send_reply_comment', send_reply_comment);
});
|
поправил, все работает как часы, большое Вам спасибо !!
еще вопрос, есть альтернатива return false при <button> или <a href> ? p.s нужно понять делегирование событий |
Про события почитай, чтоб лучше понимать как они работают, плюсы и минусы различных способов их объявления и про return false там же - http://javascript.ru/tutorial/events/intro
|
| Часовой пояс GMT +3, время: 08:15. |