How to simulate mouse click along with mouse move using javascript - javascript

I am using simulation for mouse click operation using element.click() in js file, but mouse cursor is some where else and action is performing on correct element, i want to have mouse cursor on element while performing the simulate mouse click.Does anyone know using javascript code, how can i get this?

You cannot move the mousepointer with javascript, because of the security implications that it incurs.

As already pointed out in other answers, you can't change the real mouse position with JavaScript... but... do you need to do that? No!
You can add a image of a mouse cursor and place that on any position you want on top of your content, relative to the browser window top-left.
You can hide the real cursor by applying css 'cursor: none;' class to the zone of the screen you want the cursor to disappear.
So to simulate what you want you can get the position of the element you want to click, hide real mouse cursor, show fake mouse cursor and move that one to the position of the element you want to click, then click it.
To make it user friendly: please notify the user to not move his mouse anymore when you start the simulation, simulate mouse move and click, when user moves his mouse hide the fake mouse and show real mouse and notify user that simulation is over.

You can't change mouse cursor postion in browser. see this.
But you can use javascript click() method to simulate click event. To do this work you must use elementFromPoint() to select click position. In my bottom example when you click on first button, javascript simulate second button click.
var first = document.getElementById("first");
var second = document.getElementById("second");
first.addEventListener("click", function(){
var xPos = second.offsetLeft;
var yPos = second.offsetHeight;
document.elementFromPoint(xPos, yPos).click();
});
second.addEventListener("click", function(){
alert("Second button clicked!");
});
<button id="first">First</button>
<button id="second">Second</button>

I found a git-repository that simulates a mouse-drag event:
link to git-repository
SEE CODEPEN EXAMPLE HERE
useful article
HTML
<!--
author: kemokid
github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<!-- https://ghostinspector.com/blog/simulate-drag-and-drop-javascript-casperjs/ -->
<p>Drag the W3Schools image into the rectangle:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="https://www.w3schools.com/html/img_logo.gif" ondragstart="drag(event)" >
<br/>
<button onClick="autodrag();">Auto-drag</button>
<br/>
<br/>
Reload the page to reset the image.
<script src="app.js"></script>
</body>
</html>
CSS
/*
author: kemokid
github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
*/
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
#drag1 {
width: 336px;
height: 69px;
}
JS
/*
author: kemokid
github: https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd_more_general.js
*/
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var id = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(id));
}
function autodrag() {
return triggerDragAndDrop('#drag1', '#div1');
}
// Originally from https://ghostinspector.com/blog/simulate-drag-and-drop-javascript-casperjs/
// trimmed down and modified by #kemokid (Martin Baker) to work with Sortable.js
///
// Probably not going to work with dragging from one list to another
// This has been made more general, to work with other drag-and-drop elements besides a
// Sortable list, but is not as complete as the Casper example above.
// Call with DOM selectors, eg `triggerDragAndDrop('#drag', '#drop');`
// Returns false if unable to start.
// callback, if present, will be called with true if able to finish, false if not.
// If you receive "false" on the callback, the list is likely not in the beginning state.
var triggerDragAndDrop = function (selectorDrag, selectorDrop, callback) {
var DELAY_INTERVAL_MS = 10;
var MAX_TRIES = 10;
var dragStartEvent;
// fetch target elements
var elemDrag = document.querySelector(selectorDrag);
var elemDrop = document.querySelector(selectorDrop);
if (!elemDrag || !elemDrop) {
console.log("can't get elements");
return false;
}
var startingDropRect = elemDrop.getBoundingClientRect();
function rectsEqual(r1, r2) {
return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left;
}
// function for triggering mouse events
function fireMouseEvent(type, elem, dataTransfer) {
var evt = document.createEvent('MouseEvents');
evt.initMouseEvent(type, true, true, window, 1, 1, 1, 0, 0, false, false, false, false, 0, elem);
if (/^dr/i.test(type)) {
evt.dataTransfer = dataTransfer || createNewDataTransfer();
}
elem.dispatchEvent(evt);
return evt;
};
function createNewDataTransfer() {
var data = {};
return {
clearData: function(key) {
if (key === undefined) {
data = {};
} else {
delete data[key];
}
},
getData: function(key) {
return data[key];
},
setData: function(key, value) {
data[key] = value;
},
setDragImage: function() {},
dropEffect: 'none',
files: [],
items: [],
types: [],
// also effectAllowed
}
};
// trigger dragging process on top of drop target
// We sometimes need to do this multiple times due to the vagaries of
// how Sortable manages the list re-arrangement
var counter = 0;
function dragover() {
counter++;
console.log('DRAGOVER #' + counter);
var currentDropRect = elemDrop.getBoundingClientRect();
if (rectsEqual(startingDropRect, currentDropRect) && counter < MAX_TRIES) {
if (counter != 1) console.log("drop target rect hasn't changed, trying again");
// mouseover / mouseout etc events not necessary
// dragenter / dragleave events not necessary either
fireMouseEvent('dragover', elemDrop, dragStartEvent.dataTransfer);
setTimeout(dragover, DELAY_INTERVAL_MS);
} else {
if (rectsEqual(startingDropRect, currentDropRect)) {
console.log("wasn't able to budge drop target after " + MAX_TRIES + " tries, aborting");
fireMouseEvent('drop', elemDrop, dragStartEvent.dataTransfer);
if (callback) callback(false);
} else {
setTimeout(drop, DELAY_INTERVAL_MS);
}
}
}
function drop() {
console.log('DROP');
// release dragged element on top of drop target
fireMouseEvent('drop', elemDrop, dragStartEvent.dataTransfer);
fireMouseEvent('mouseup', elemDrop); // not strictly necessary but I like the symmetry
if (callback) callback(true);
}
// start dragging process
console.log('DRAGSTART');
fireMouseEvent('mousedown', elemDrag);
dragStartEvent = fireMouseEvent('dragstart', elemDrag);
// after a delay, do the first dragover; this will run up to MAX_TRIES times
// (with a delay between each run) and finally run drop() with a delay:
setTimeout(dragover, DELAY_INTERVAL_MS);
return true;
};

Related

How can I have a slot machine effect using jQuery and CSS

I want to make a slot machine. I am taking random index from array and populating it inside my div. But the only issue is that I want to have a slot machine effect. I mean that the effect should be like numbers are dropping from top to bottom. This is my code so far.
var results = [
'PK12345',
'IN32983',
'IH87632',
'LK65858',
'ND82389',
'QE01233'
];
// Get a random symbol class
function getRandomIndex() {
return jQuery.rand(results);
}
(function($) {
$.rand = function(arg) {
if ($.isArray(arg)) {
return arg[$.rand(arg.length)];
} else if (typeof arg === "number") {
return Math.floor(Math.random() * arg);
} else {
return 4; // chosen by fair dice roll
}
};
})(jQuery);
// Listen for "hold"-button clicks
$(document).on("click", ".wheel button", function() {
var button = $(this);
button.toggleClass("active");
button.parent().toggleClass("hold");
button.blur(); // get rid of the focus
});
$(document).on("click", "#spin", function() {
// get a plain array of symbol elements
var symbols = $(".wheel").not(".hold").get();
if (symbols.length === 0) {
alert("All wheels are held; there's nothing to spin");
return; // stop here
}
var button = $(this);
// get rid of the focus, and disable the button
button.prop("disabled", true).blur();
// counter for the number of spins
var spins = 0;
// inner function to do the spinning
function update() {
for (var i = 0, l = symbols.length; i < l; i++) {
$('.wheel').html();
$('.wheel').append('<div style="display: none;" class="new-link" name="link[]"><input type="text" value="' + getRandomIndex() + '" /></div>');
$('.wheel').find(".new-link:last").slideDown("fast");
}
if (++spins < 50) {
// set a new, slightly longer interval for the next update. Makes it seem like the wheels are slowing down
setTimeout(update, 10 + spins * 2);
} else {
// re-enable the button
button.prop("disabled", false);
}
}
// Start spinning
setTimeout(update, 1);
});
// set the wheels to random symbols when the page loads
$(function() {
$(".wheel i").each(function() {
this.className = getRandomIndex(); // not using jQuery for this, since we don't need to
});
});
.wheel {
width: 25%;
float: left;
font-size: 20px;
text-align: center;
}
.wheel .fa {
display: block;
font-size: 4em;
margin-bottom: 0.5em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<div id="wheels">
<div class="wheel clearfix">
</div>
<!-- add more wheels if you want; just remember to update the width in the CSS -->
</div>
<p class="text-center">
<button id="spin" type="button" class="btn btn-default">Spin</button>
</p>
I managed to create a similar effect by using prepend() rather than append(), and adding a set height and hiding the overflow of the wheel.
CSS:
.wheel {
...
height: 34.4px;
overflow: hidden;
}
JS:
$('.wheel').prepend('<div style="display: none;" class="new-link" name="link[]"><input type="text" value="' + getRandomIndex() + '" /></div>');
//Using "first-of-type" rather than "last"
$('.wheel').find(".new-link:first-of-type").slideDown("fast");
See it working here.
Like so many animations it's a lot easier to fake this animation by reversing what appears to be happening, rather than making it work "correctly".
Use the code you have now to generate a result. Then create an animation for a "spinning wheel", you could shuffle divs, or you could make a 3d wheel in css. While the faces are spinning, do some calculations to decide where the wheel should stop to match your results. Then work backwards from there: You'll want to trigger your "stopping" animation so that the face is showing. Your stopping animation would be a predetermined amount of rotation and speed so that a face can be reliably shown. Depending on how fast your wheel spins, the user may lose track, if this is acceptable it may not matter when you trigger as no one could see the wheel jump.
A simulation on the other hand would use a physics model...

toggle function that gradientifies background color

Basically I'm trying to toggle a function that gradually change background color of div. There's a separate script.js file that is responsible for function gradientify() to run.
I'm just not sure what is the logic to toggle a function...
index.html
<body>
<button type="button" id="btn"></button>
<div style="width: 100px; height: 100px;"></div>
</body>
script.js
$('#btn').click(function() {
$('div').toggle(function() {
$(this).gradientify({
gradients: [
{ start: [49,76,172], stop: [242,159,191] },
{ start: [255,103,69], stop: [240,154,241] },
{ start: [33,229,241], stop: [235,236,117] }
]
});
});
});
The Jquery toggle function toggles the visibility of an element. It basically sets the css property display to display: none. If you want the content inside the "gradientifyied" element to still be visible when you toggle the gradients then you can't use Jquery.toggle.
Sadly the gradientify API doesn't provide any way to cancel the gradients once they are set on an element so the only way to toggle the gradients on an element is to remove it from the DOM all together.
We can create a copy of the clean element before the gradiants are applied and when we want to remove the gradients, we remove the old element from the DOM and insert the copy we kept.
function toggleGradients() {
var gradientTargetCopy = $( ".gradientTarget" ).clone()
var gradientsOff = true;
return function() {
if (gradientsOff) {
$('.gradientTarget').gradientify({
gradients: [
{ start: [49,76,172], stop: [242,159,191] },
{ start: [255,103,69], stop: [240,154,241] },
{ start: [33,229,241], stop: [235,236,117] }
]
});
} else {
$('.gradientTarget').remove()
$('body').append(gradientTargetCopy)
gradientTargetCopy = $( ".gradientTarget" ).clone()
}
gradientsOff = !gradientsOff
}
}
$('#btn').click(toggleGradients());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://codefog.github.io/jquery-gradientify/jquery.gradientify.min.js"></script>
<body>
<button type="button" id="btn">Toggle gradients</button>
<div class="gradientTarget" style="width: 100px; height: 100px;">Hello!</div>
</body>
Just use plain JavaScript.
var x = 3; //Length of amount of color options you want
var bgcolor_num = Math.floor((Math.random() * x) + 1);
setInterval(function () {
if (bgcolor_num === 1) {
bgcolor = "#FF0000";
bgcolor_num = 2;
} else if (bgcolor_num === 2) {
bgcolor = "#00FF00";
bgcolor_num = 3;
} else {
bgcolor = "#0000FF";
bgcolor_num = 1;
}
document.getElementById('whatever').style.backgroundColor = bg_color;
}, 12000);
What happens is that it defines a variable, x, and randomizes a number from 1 to x. Then, an interval (which runs every 12 seconds; 12,000 milliseconds) determines whether the number, bgcolor_num, is 1, 2, 3, or something else. Remember, the amount of options you have has to equal x. If it doesn't, it will run as "else" and will start back at color option #1.
Make sure you have an ID set for your div and reconfigure the part that actually triggers the change!
If you want an example of this happening, you can always go to my website typrograms.com/RGB.html and right-click, view-source! I use a similar method, and it slowly changes the color.

Store, change, and update opacity using JavaScript

I am new here and new to programming, so apologies in advance if this question is very basic and the answer is already here. I've done a lot of searching, but I've been unable to find the information I need.
What JavaScript code could I use to pull the current opacity value of a div, update that value, and reapply the updated value to that same div? In essence, I'm doing an exercise that involves gradually increasing the opacity of individual divs in a large grid on the mouseover event. Each individual div in the grid should have a 0.1 increase in opacity every time the mouse enters that div, up to the point of having an opacity of 1.
I already know how to do this in jQuery, I'm just trying to expand my knowledge of JavaScript at the moment.
So this is how you'd set opacities and events with jQuery:
// `elem` is the element you want to affect
// get opacity
var oldOpacity = $(elem).css('opacity');
// set opacity
$(elem).css('opacity', 0.5);
// add mouseover event
$(elem).on('mouseover', function onMouseOver(e) {
// do stuff with opacities
});
And here's how you'd do the above with vanilla DOM methods:
// `elem` is the element you want to affect
// get opacity
var oldOpacity = window.getComputedStyle(elem).getPropertyValue('opacity');
// set opacity
elem.style.setPropertyValue('opacity', 0.5);
// add mouseover event
elem.addEventListener('mouseover', function onMouseOver(e) {
// do stuff with opacities
}, false);
To get the element, you can use old DOM methods like document.getElementById or the new methods document.querySelectorAll and document.querySelector which are very much like jQuery in that they take a CSS selector and return a Node or list of Nodes.
To, say, retrieve all of the li elements with the class list-item, and iterate over them, you would do this:
var elems = document.querySelectorAll('li.list-item');
var i, l = elems.length, elem;
for (i = 0; i < l; i += 1) {
elem = elems[i];
// do stuff with elem
}
Here's the 'vanilla' JS way to check and update opacity, with the caveat that this only works in browsers; it won't work in NodeJS because there's no document in node. You can try it on this page by opening dev tools (right-click, inspect, console in Chrome).
var div = document.querySelector('.post-text')
console.log(div.style.opacity) // ""
div.style.opacity = 0.5
console.log(div.style.opacity) // "0.5"
So for your exercise, you'll want to assign the mouseover function like so:
function changeOpacity (element, delta) {
element.style.opacity = Number(element.style.opacity) + Number(delta)
}
var element = document.querySelector('.post-text')
var opacityDelta = -0.1
document.onmouseover = function () { changeOpacity(element, opacityDelta) }
I got it to work with these lines of code.
with vanilla Js.
I commented too.
// Vanilla Js.
//Getting elements.
var box = document.querySelector('.box');
var refresh = document.querySelector('.refresh');
// Assigning opacity
var defaultOpacity = 0.2;
box.style.opacity = defaultOpacity;
// Events.
// Opacity adding event on hover
box.addEventListener('mouseover', function(e){
var oldOp = e.target.style.opacity;
oldOp = Number.parseFloat(oldOp);
oldOp += defaultOpacity;
e.target.style.opacity = oldOp;
}, false);
//Refresh Evet.
refresh.addEventListener('click', function(e){
box.style.opacity = defaultOpacity;
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.box {
background: #48A64C;
height: 100px;
width: 100px;
margin-bottom: 20px;
}
</head>
<body>
<div class="box"></div>
<p> Yeah you can refresh too </p>
<button class = "refresh">refresh</button>
</body>
</html>

Allow more scroll (slack) before firing actual scroll further event

I have a box which has an overflow scroll on it. When you reach the end of the box; I want to fire an event (scroll to the next section of the page).
Below code works, however, I want some "slack" in it. So it does not needs to fire directly when you reach the end of your box, but only when you persist on scrolling downwards.
Any help on improving below code to reach this effect?
function whiteboxscroll (){
$('.white-box-inner').on("DOMContentLoaded scroll",function(){
var myDiv = $('.white-box-inner');
myDiv.each(function(){
el = this;
if(isElementInViewport(el) === true) { // current white box is in view
if (this.offsetHeight + this.scrollTop >= this.scrollHeight ) { //current box is at end of scroll
//define the current section 'this' belongs to
var current_section = $(this).parents().eq(1);
// define the next section
var next_section = $(current_section).next('.cd-section');
// smoothscroll to this next section
if(next_section.attr('id') !== undefined){ // only perform scroll if next section is defined
smoothScroll($('#' + next_section.attr('id')));
}
}
else if(this.scrollTop === 0){ // current box is at top of scroll
//define the current section 'this' belongs to
var current_section = $(this).parents().eq(1);
// define the prev section
var prev_section = $(current_section).prev('.cd-section');
// smoothscroll to this next section
if(prev_section.attr('id') !== undefined) { // only perform scroll if prev section is defined
smoothScroll($('#' + prev_section.attr('id')));
}
}
}
});
});
}
I tried to add a buffer of 50 pixels ie, but then the events never fires, since we will never reach that point.
You can set a variable to true when you reach the end of scrolling and check if that variable is true on mousewheel.
var enable_scroll = false;
$(".container").scroll(function(e){
$('p.info').html(this.scrollTop);
if(this.offsetHeight + this.scrollTop >= this.scrollHeight ) {
$('p.info').html("End of scroll. Flag enabled.");
enable_scroll = true;
}
})
.on('mousewheel DOMMouseScroll',function(e){ //DOMMouseScroll for FF
if(enable_scroll){
$('p.info').html("<strong>Event fired</strong>");
}
});
.container { height: 250px; overflow:auto;}
.inner {height: 1000px;}
p.info{ padding: 10px; color: #fff; background: orange;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="info">Start scrolling</p>
<div class="container">
<div class="inner">Scroll down</div>
</div>
<p class="bottom"></p>

Fire JavaScript Event When a DIV is in View

Is it possible to fire a specific JavaScript event when a certain DIV comes into view on the page?
Say, for example, I have a very large page, like 2500x2500 and I have a 40x40 div that sits at position 1980x1250. The div is not necessarily manually positioned, it could be there due to the content pushing it there. Now, is it possible to run a function when the user scrolls to a point where the div becomes visible?
Not automatically. You would have to catch scroll events and check for it being in view each time by comparing the co-ordinates of the div rectangle with the visible page rectangle.
Here's a minimal example.
<div id="importantdiv">hello</div>
<script type="text/javascript">
function VisibilityMonitor(element, showfn, hidefn) {
var isshown= false;
function check() {
if (rectsIntersect(getPageRect(), getElementRect(element)) !== isshown) {
isshown= !isshown;
isshown? showfn() : hidefn();
}
};
window.onscroll=window.onresize= check;
check();
}
function getPageRect() {
var isquirks= document.compatMode!=='BackCompat';
var page= isquirks? document.documentElement : document.body;
var x= page.scrollLeft;
var y= page.scrollTop;
var w= 'innerWidth' in window? window.innerWidth : page.clientWidth;
var h= 'innerHeight' in window? window.innerHeight : page.clientHeight;
return [x, y, x+w, y+h];
}
function getElementRect(element) {
var x= 0, y= 0;
var w= element.offsetWidth, h= element.offsetHeight;
while (element.offsetParent!==null) {
x+= element.offsetLeft;
y+= element.offsetTop;
element= element.offsetParent;
}
return [x, y, x+w, y+h];
}
function rectsIntersect(a, b) {
return a[0]<b[2] && a[2]>b[0] && a[1]<b[3] && a[3]>b[1];
}
VisibilityMonitor(
document.getElementById('importantdiv'),
function() {
alert('div in view!');
},
function() {
alert('div gone away!');
}
);
</script>
You could improve this by:
making it catch onscroll on all ancestors that have overflow scroll or auto and adjusting the top/left co-ords for their scroll positions
detecting overflow scroll, auto and hidden cropping putting the div off-screen
using addEventListener/attachEvent to allow multiple VisibilityMonitors and other things using the resize/scroll events
some compatibility hacks to getElementRect to make the co-ords more accurate in some cases, and some event unbinding to avoid IE6-7 memory leaks, if you really need to.
Here is a solution that is ideal in 2022. The current top answer only allows you to observe one item, and has performance issues because it fires many times every time the page scrolls.
var observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting === true) {
console.log('Item has just APPEARED!');
} else {
console.log('Item has just DISAPPEARED!');
}
}, { threshold: [0] });
observer.observe(document.querySelector("#DIV-TO-OBSERVE"));
This fires as soon as the item is partially on screen. Changing threshold to 1 will require the item to be fully on screen (so it will never fire if the item is bigger than the viewport). You can do values in between for example 0.25 to fire when at least 1/4 of the item is in view.
Here's an starter example using jQuery:
<html>
<head><title>In View</title></head>
<body>
<div style="text-align:center; font-size:larger" id="top"></div>
<fieldset style="text-align:center; font-size:larger" id="middle">
<legend id="msg"></legend>
<div> </div>
<div id="findme">Here I am!!!</div>
</fieldset>
<div style="text-align:center; font-size:larger" id="bottom"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var $findme = $('#findme'),
$msg = $('#msg');
function Scrolled() {
var findmeOffset = $findme.offset(),
findmeTop = findmeOffset.top,
scrollTop = $(document).scrollTop(),
visibleBottom = window.innerHeight;
if (findmeTop < scrollTop + visibleBottom) {
$msg.text('findme is visible');
}
else {
$msg.text('findme is NOT visible');
}
}
function Setup() {
var $top = $('#top'),
$bottom = $('#bottom');
$top.height(500);
$bottom.height(500);
$(window).scroll(function() {
Scrolled();
});
}
$(document).ready(function() {
Setup();
});
</script>
</body>
</html>
It only notifies once the div comes into view from the bottom. This example does not notify when the div scrolls out of the top.

Categories