function initDrag(event)
{
var lastOffset = context.getElementTranslation(element);
// Get initial coordinates for (x,y)
initialX = event.pageX;
initialY = event.pageY;
// Determine last offset points for (x,y)
lastOffsetX = lastOffset ? lastOffset[0] : 0;
lastOffsetY = lastOffset ? lastOffset[1] : 0;
startOffsetX = initialX - lastOffsetX;
startOffsetY = initialY - lastOffsetY;
event.stopPropagation();
event.preventDefault();
elem.className = elem.className + ' draggable';
document.documentElement.addEventListener('mousemove', doDrag, false);
document.documentElement.addEventListener('mouseup', stopDrag, false);
}
jQuery('.classname').on('click', function(event)
{
alert(23);
jQuery('.medium-editor-button-first').attr('style','');
if(!event.shiftKey)
{
if(layer.hasClass('layer_selected'))
{
event.stopPropagation();
return false;
}
context.deselectAllLayers();
context.setLayerSelected(layerId);
}
else
{
/*if(jQuery('.layer_selected').length < 1 )
{
context.deselectAllLayers();
}*/
if(layer.hasClass('layer_selected'))
{
layer.removeClass('layer_selected multiSelectLayers');
context.initializeMultiSelect(layer);
event.stopPropagation();
return false;
}
context.selectors.multiSelect.removeClass('layer_selected');
}
layer.find('.tp-caption').focus();
layer.addClass("layer_selected");
context.initializeMultiSelect(layerId);
event.stopPropagation();
});
After each mouse up click function fire. I want to prevent this click event. I tried event.stopPropagation(); and event.preventDefault(); but didn't work.
Thanks in advance.
Related
I'm new to JS so I need help to solve my problem :). I found a codepen that helped me drag one element of my website but the thing is that I would like to drag 4 elements separately. I applied the same class to all of them but it works only on the first one.
Link of the codepen : https://codepen.io/Coding-Artist/pen/zYWbYXV
I'm sure the solution is obvious to you (I would say a var or a for ?) but I'm learning and I really want to progress so if you could explain that would be perfect ! Thanks a lot
JS —
var draggableElem = document.querySelector(".draggable-elem");
let initialX = 0,
initialY = 0;
let moveElement = false;
//events object
let events = {
mouse: {
down: "mousedown",
move: "mousemove",
up: "mouseup"
},
touch: {
down: "touchstart",
move: "touchmove",
up: "touchend"
}
};
let deviceType = "";
//Detect touch device
const isTouchDevice = () => {
try {
//We try to create TouchEvent (it would fail for desktops and throw error)
document.createEvent("TouchEvent");
deviceType = "touch";
return true;
} catch (e) {
deviceType = "mouse";
return false;
}
};
isTouchDevice();
// start(mouse down/touch start)
draggableElem.addEventListener(events[deviceType].down, (e) => {
e.preventDefault();
//initial x and y points
initialX = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
initialY = !isTouchDevice() ? e.clientY : e.touches[0].clientY;
// start movement
moveElement = true;
});
// Move
draggableElem.addEventListener(events[deviceType].move, (e) => {
//if movement==true then set top and left to new X and y while removing any offset
if (moveElement) {
e.preventDefault();
let newX = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
let newY = !isTouchDevice() ? e.clientY : e.touches[0].clientY;
draggableElem.style.top = draggableElem.offsetTop - (initialY - newY) + "px";
draggableElem.style.left =
draggableElem.offsetLeft - (initialX - newX) + "px";
initialX = newX;
initialY = newY;
}
});
//mouse up/touch end
draggableElem.addEventListener(
events[deviceType].up,
(stopMovement = (e) => {
//stop movement
moveElement = false;
})
);
draggableElem.addEventListener("mouseleave", stopMovement);
document.addEventListener(events[deviceType].up, (e) => {
moveElement = false;
});
For it to work with multiple elements you should instantiate variables for each element and then add event listeners to them.
This can be done dynamically like in this codepen fork I made by using document.querySelectorAll and a for loop to iterate through the elements, instantiate variables, and add event listeners to each one.
My modified code (it's not perfect but it gets the job done):
let draggableElems = document.querySelectorAll("#draggable-elem");
let initialX = {},
initialY = {};
let moveElement = {};
//events object
let events = {
mouse: {
down: "mousedown",
move: "mousemove",
up: "mouseup"
},
touch: {
down: "touchstart",
move: "touchmove",
up: "touchend"
}
};
let deviceType = "";
//Detect touch device
const isTouchDevice = () => {
try {
//We try to create TouchEvent (it would fail for desktops and throw error)
document.createEvent("TouchEvent");
deviceType = "touch";
return true;
} catch (e) {
deviceType = "mouse";
return false;
}
};
isTouchDevice();
for (let i = 0; i < draggableElems.length; i++) {
var draggableElem = draggableElems[i];
// start(mouse down/touch start)
draggableElem.addEventListener(events[deviceType].down, (e) => {
e.preventDefault();
//initial x and y points
initialX[this] = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
initialY[this] = !isTouchDevice() ? e.clientY : e.touches[0].clientY;
// start movement
moveElement[this] = true;
});
// Move
draggableElem.addEventListener(events[deviceType].move, (e) => {
//if movement==true then set top and left to new X and y while removing any offset
if (moveElement[this]) {
var elem = e.target;
e.preventDefault();
let newX = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
let newY = !isTouchDevice() ? e.clientY : e.touches[0].clientY;
elem.style.top = elem.offsetTop - (initialY[this] - newY) + "px";
elem.style.left = elem.offsetLeft - (initialX[this] - newX) + "px";
initialX[this] = newX;
initialY[this] = newY;
}
});
//mouse up/touch end
draggableElem.addEventListener(
events[deviceType].up,
(stopMovement = (e) => {
//stop movement
moveElement[this] = false;
})
);
draggableElem.addEventListener("mouseleave", stopMovement);
document.addEventListener(events[deviceType].up, (e) => {
moveElement[this] = false;
});
}
I'm trying to understand how to best do this.
I have a slideshow where I have a div that keep track of what slide it's on.
I need to have keep a consistent count on both clicks of previous and next arrows, and drag on both desktop and mobile.
This question is related to drag on both desktop mobile. Because mousedown doesn't translate to mobile I need to figure how to use touch events too within an event listener and despite 3 attempts and research I don't get it.
My initial attempt is below:
function nextSlideHandler(){
slideCounter = (slideCounter+1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function previousSlideHandler(){
slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
var swipeElement = $('.n2-ss-swipe-element')[0];
var isDown = false;
var direction = '';
swipeElement.addEventListener('mousedown, touchend', function(e) {
isDown = true;
}, true);
document.addEventListener('mouseup, touchstart', function(e) {
isDown = false;
if(direction == 'left'){
nextSlideHandler();
}
if(direction == 'right'){
previousSlideHandler();
}
direction='';
}, true);
document.addEventListener('mousemove, touchmove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
}
}, true);
Thought process - mousedown etc is for desktop while touch events are for mobile and fire if one of those event types happens.
But this does not work. Slide count does not update.
I found https://gomakethings.com/listening-to-multiple-events-in-vanilla-js/ which suggests multiple event listeners
Although pedantic and repetitive I tried spliiting out into multiple event listeners
function nextSlideHandler(){
slideCounter = (slideCounter+1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function previousSlideHandler(){
slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
var swipeElement = $('.n2-ss-swipe-element')[0];
var isDown = false;
var direction = '';
swipeElement.addEventListener('mousedown', function(e) {
isDown = true;
}, true);
swipeElement.addEventListener('touchstart', function(e) {
isDown = true;
}, true);
document.addEventListener('mouseup', function(e) {
isDown = false;
if(direction == 'left'){
nextSlideHandler();
}
if(direction == 'right'){
previousSlideHandler();
}
direction='';
}, true);
document.addEventListener('touchend', function(e) {
isDown = false;
if(direction == 'left'){
nextSlideHandler();
}
if(direction == 'right'){
previousSlideHandler();
}
direction='';
}, true);
document.addEventListener('mousemove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
}
}, true);
document.addEventListener('touchmove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
}
}, true);
This doesn't work either.
I found these answers:
does mousedown /mouseup in jquery work for the ipad?
Does jQuery mouseup event work on touch devices?
Using mousedown event on mobile without jQuery mobile?
So far with this research, it seems like I'm on the right track using touch events.
This answer was the most promising: Binding multiple events to a listener (without JQuery)? so I took the idea here and rolled with it:
function nextSlideHandler(){
slideCounter = (slideCounter+1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function previousSlideHandler(){
slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function addListenerMulti(element, eventNames, listener) {
var events = eventNames.split(' ');
for (var i=0, iLen=events.length; i<iLen; i++) {
element.addEventListener(events[i], listener, false);
}
}
$('.entry-content').append({$slide_top_section}).append({$slide_text});
$('#n2-ss-{$id}-arrow-previous').on('click', $.proxy(function(e){
e.stopPropagation();
previousSlideHandler()}, this));
$('#n2-ss-{$id}-arrow-next').on('click', $.proxy(function(e){
e.stopPropagation();
nextSlideHandler()}, this))
var swipeElement = $('.n2-ss-swipe-element')[0];
var isDown = false;
var direction = '';
swipeElement.addListenerMulti('mousedown touchstart', function(e) {
isDown = true;
}, true);
document.addListenerMulti('mouseup touchend', function(e) {
isDown = false;
if(direction == 'left'){
nextSlideHandler();
}
if(direction == 'right'){
previousSlideHandler();
}
direction='';
}, true);
document.addListenerMulti('mousemove touchmove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
}
}, true);
After this the slide count still does not update.
How do I combine multiple event types in an event listener?
UPDATE Another attempt:
function nextSlideHandler(){
slideCounter = (slideCounter+1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function previousSlideHandler(){
slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
$('#slide-text').replaceWith({$slide_text});
$('#slide-top-section').replaceWith({$slide_top_section});
}
function addListenerMulti(element, eventNames, listener) {
var events = eventNames.split(' ');
for (var i=0, iLen=events.length; i<iLen; i++) {
element.addEventListener(events[i], listener, false);
}
}
$('.entry-content').append({$slide_top_section}).append({$slide_text});
$('#n2-ss-{$id}-arrow-previous').on('click', $.proxy(function(e){
e.stopPropagation();
previousSlideHandler()}, this));
$('#n2-ss-{$id}-arrow-next').on('click', $.proxy(function(e){
e.stopPropagation();
nextSlideHandler()}, this))
var swipeElement = $('.n2-ss-swipe-element')[0];
var isDown = false;
var direction = '';
addListenerMulti(swipeElement, 'mousedown touchstart', function(e) {
isDown = true;
}, true);
addListenerMulti(swipeElement, 'mouseup touchend', function(e) {
isDown = false;
if(direction == 'left'){
nextSlideHandler();
}
if(direction == 'right'){
previousSlideHandler();
}
direction='';
}, true);
addListenerMulti(swipeElement, 'mousemove touchmove', function(event) {
event.preventDefault();
if (isDown) {
var deltaX = event.movementX;
var deltaY = event.movementY;
if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
console.log(direction);
}
}, true);
When we correctly call with the element, it seems to work fine.
const mySampleListener = (event) => {
console.log(`Event occured: ${event.target.innerHTML}`);
}
function addListenerMulti(element, eventNames, listener) {
var events = eventNames.split(' ');
for (var i=0, iLen=events.length; i<iLen; i++) {
element.addEventListener(events[i], listener, false);
}
}
let events = "click keyup";
let divs = document.querySelectorAll('.track');
divs.forEach(d => {
addListenerMulti(d, events, mySampleListener);
})
<div class="track">Div 1</div>
<div class="track">Div 2</div>
<input type="text" class="track" />
i need a little help. i want to make something that you put in console and it press Enter bottom for 2000 times and auto click for 2000 times with no delay ! and a key for stop this action. anyone can help me ? thanks a lot !
With jQuery:
function enter_key(ctrl, alt, shift, which) {
var e = $.Event("keydown");
e.ctrlKey = false;
e.altKey = false;
e.shiftKey = false;
e.which = e.keyCode = 13;
$(document.documentElement || window).trigger(e);
}
var stop = false;
for (var i=0; i<2000; ++i) {
if (!stop) {
enter_key();
}
}
click is simpler:
var stop = false;
for (var i=0; i<2000; ++i) {
if (!stop) {
$('button').click();
}
}
and you can stop the iteration by setting:
stop = true;
i thing about this and i found a code that click on the specific position :
var elem = document.elementFromPoint(x, y);
elem.addEventListener('click', function() {
console.log('clicked')
}, false);
var support = true;
try {
if (new MouseEvent('click', {bubbles: false}).bubbles !== false) {
support = false;
} else if (new MouseEvent('click', {bubbles: true}).bubbles !== true) {
support = false;
}
} catch (e) {
support = false;
}
setInterval(function() {
if (support) {
var event = new MouseEvent('click');
}else{
var event = document.createEvent('Event');
event.initEvent('click', true, true);
}
elem.dispatchEvent(event);
},1000);
and i found this code for get mouse position :
function FindPosition(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
// posx and posy contain the mouse position relative to the document
// Do something with this information
}
so how can i use this code to import mouse position in auto click code ???
i have a auto clicker that work with mouse position . here is the code :
var elem = document.elementFromPoint( x,y );
elem.addEventListener('click', function() {
console.log('clicked')
}, false);
var support = true;
try {
if (new MouseEvent('click', {bubbles: false}).bubbles !== false) {
support = false;
} else if (new MouseEvent('click', {bubbles: true}).bubbles !== true) {
support = false;
}
} catch (e) {
support = false;
}
setInterval(function() {
if (support) {
var event = new MouseEvent('click');
}else{
var event = document.createEvent('Event');
event.initEvent('click', true, true);
}
elem.dispatchEvent(event);
},1000);
and i also have code for get mouse position :
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval("checkCursor()", 1000);
function checkCursor(){
alert( cursorX + ","+ cursorY);
}
and my questions is : how can i put mouse position in document.elementFromPoint(x,y ) ????
i know can put my x and y but i want to x and y update when i move mouse anywhere
Edit
You actually need to initialize elem and cursorX and cursorY first, sorry, didn't test this code.
Declare elem as a variable
var elem = document.elementFromPoint( cursorX,cursorY );
And initialize cursors cursorX = 0; cursorY = 0
Then inside your mousemove function, do this
document.onmousemove = function(e) {
cursorX = e.pageX;
cursorY = e.pageY;
elem = document.elementFromPoint(e.pageX, e.pageY);
}
I use this jquery code (without UI), first time I drag and move the image it's moves smoothly but 2d time it moves slow 3d time more slow and so on... anything wrong with the code? anything to release?
(function($)
{
$.fn.drags = function(opt)
{
opt = $.extend({handle:"",cursor:"pointer"}, opt);
if(opt.handle === "")
{
var $el = this;
}
else
{
var $el = this.find(opt.handle);
}
$(this).css('cursor', opt.cursor).on("mousedown", function(e)
{
if(opt.handle === "")
{
var $drag = $(this).addClass('draggable');
}
else
{
var $drag = $(this).addClass('active-handle').parent().addClass('draggable');
}
var z_idx = $drag.css('z-index'), drg_w = $drag.outerWidth(), pos_x = $drag.offset().left + drg_w - e.pageX;
$drag.css('z-index', 1000).parents().on("mousemove", function(e)
{
if($drag.offset().left<438)
{
pos_x =438 + drg_w - e.pageX;
$('.draggable').offset({left:e.pageX + pos_x - drg_w});
return;
}
else if($drag.offset().left>701)
{
pos_x =701 + drg_w - e.pageX;
$('.draggable').offset({left:e.pageX + pos_x - drg_w});
return;
}
else
{
$('.draggable').offset({left:e.pageX + pos_x - drg_w}).on("mouseup", function() {$(this).removeClass('draggable').css('z-index', z_idx);});
$('#rbba_prgrs').width($drag.offset().left-438);
}
});
e.preventDefault(); // disable selection
}).on("mouseup", function()
{
if(opt.handle === "")
{
$(this).removeClass('draggable');
}
else
{
$(this).removeClass('active-handle').parent().removeClass('draggable');
}
});
}
})(jQuery);
It looks like everytime "mousedown" is being called, it attaches event listener function for mousemove. This is done repeatedly, and after a while, it would have to perform that function multiple times on each mouse pixel movement. Find a way to attach that listener elsewhere.