Как избежать срабатывания события click после перетаскивания виджета gridster.js с интерактивным контентом?
Я использую Gridster ( http://gridster.net/), который может перетаскивать содержимое внутри li
, В моем li
есть кликабельный div.
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
<a href=' '>
<div>
content
</div>
</a>
</li>
Итак, вот проблема, с которой я сталкиваюсь, когда я останавливаю и отпускаю перетаскивание, он вызывает щелчок в div, как я могу просто перетащить div, но не вызывать щелчок после остановки и отпускания перетаскивания. Я не хочу, чтобы он перенаправлял на другую страницу после перетаскивания (пользователь перетаскивает и отпускает. Так как при перетаскивании необходимо щелкнуть элемент div, при этом элемент div можно щелкнуть, поэтому при остановке и отпускании перетаскивания он вызовет щелчок)
$(function(){ //DOM Ready
var gridster = $(".gridster ul").gridster(
{
widget_margins: [5, 5],
widget_base_dimensions: [128, 130],
max_size_y: 2,
max_size_x: 2,
extra_cols: 6
}
).data('gridster');
//which i tried but failed
gridster.draggable.stop(){
onclick = "false";
}
// gridster.resize_widget($('.gridster li').eq(0), 1,1);
});
или кто-то может дать подсказки о том, как вызвать или использовать функцию, предоставленную gridster
draggable.stop: function (event, ui) {} Обратный вызов, когда перетаскивание останавливается.
Я предполагаю, что здесь будет некоторая реализация.
первоначальное решение, но все еще не работает
var gridster ,draggable ;
$(function () {
gridster = $(".gridster > ul").find("> li ").click(function(e){
!draggable && alert(1) //ipad2 ,not show alert
draggable=0;
alert(draggable);
}).end()
.gridster({widget_margins: [5, 5],
widget_base_dimensions: [128, 130],min_cols: 10,min_rows: 20
,serialize_params: function($w, wgd) {
return {
id: wgd.el[0].id
//,col: wgd.col
//,row: wgd.row
};
}
,draggable: {
start:function(event, ui){
// alert("hekio);");
draggable=1; }
}
}).data('gridster');
//gridster.disable();
// gridster.resize_widget($('.gridster li').eq(0), 1,1);
if(!dragged){
$("a#blue.grid").click(function(){
window.location = '../yokotachi/category_list.php?category=yokosmart';
});
}
// RESET DRAGGED SINCE CLICK EVENT IS FIRED AFTER drag stop
dragged = 0
});
6 ответов
Я исправил это с помощью триггерной переменной: var dragged = 0 Добавьте следующее к вашей инициализации гридстера, которая устанавливает переменную равной 1 при начале перетаскивания:
...
draggable: {
start: function(event, ui) {
dragged = 1;
// DO SEOMETHING
}
}
....
В вашем событии клика на тот же объект, проверьте:
...
if(!dragged){
// DO SOMETHING
}
// RESET DRAGGED SINCE CLICK EVENT IS FIRED AFTER drag stop
dragged = 0
....
Проблема в том, что click
событие происходит после mouseup
событие, которое передается draggable.stop
,
Поэтому вам необходимо на короткое время перехватить это событие клика и остановить его распространение, а затем снять его, как только вы закончите, чтобы впоследствии люди могли щелкнуть по элементу.
Вы можете сделать это так ( нажмите для работы JSFiddle):
$(document).ready(function () {
// Basic event handler to prevent event propagation and clicks
var preventClick = function (e) { e.stopPropagation(); e.preventDefault(); };
$(element).gridster({
draggable: {
start: function (event, ui) {
// Stop event from propagating down the tree on the capture phase
ui.$player[0].addEventListener('click', preventClick, true);
},
stop: function (event, ui) {
var player = ui.$player;
setTimeout(function () {
player[0].removeEventListener('click', preventClick, true);
});
}
}
});
})
Это гораздо лучшее решение, чем принятый в настоящее время ответ, поскольку оно позволяет избежать установки / проверки переменной с состоянием для нескольких компонентов / обработчиков.
Вы должны попробовать это:
var gridster = $(".gridster ul").gridster().data('gridster');
gridster.disable();
Для тех, кто сталкивался с этой веткой, ищущей решение в Gridster2 с использованием Angular, нижеследующее основано на ответе Аластера Мо, но обновлено для работы с Gridster2 с помощью опции initCallBack.
ngOnInit() {
const preventClick = (e) => { e.stopPropagation(); e.preventDefault(); };
this.gridsterOptions = {
initCallback: (gridster: GridsterComponentInterface) => {
gridster.options = {
draggable: {
delayStart: 100,
start: (event, ui) => {
// Stop event from propagating down the tree on the capture phase
setTimeout(() => {
ui.el.addEventListener('click', preventClick, true);
}, 100);
},
stop: (event, ui) => {
setTimeout(() => {
ui.el.removeEventListener('click', preventClick, true);
});
}
}
}
}
};
}
Теперь есть встроенная поддержка для отключения операции перетаскивания в Gridster.
$(".gridster ul").gridster().data('gridster').disable();
Не копаясь в JS, добавляя onclick = "return false;"
на ваш <a>
тег должен остановить клик от срабатывания.
Чтобы остановить только перетаскивание, попробуйте:
gridster.draggable.stop(){
return false;
}
или же
gridster.draggable.stop(e){
e.preventDefault();
}