"Prevent" Programatic Click on Element - javascript

Found this site the other day. You click on a DIV (button) and it increments getting you points.
http://clickingbad.nullism.com/
I thought to myself I'll just inject jQuery and write a loop to click for me use the Chrome developer console and run code similar to the following:
for (var i=0;i<10;i++)
{
$('#make_btn').click();
}
However it doesn't seem to be working like I'd think. It will at like it increments the first hit, but past that nothing. Also you'll see when you acutally use your mouse to click, it floats the points given. Programatically clicking does not. What's going on here?

You can use setInterval() and use trigger('click')
setInterval(function () {
$('#make_btn').trigger('click')
}, 1);

what using either the trigger() method:
Execute all handlers and behaviors attached to the matched elements for the given event type.
for (var i=0;i<10;i++)
{
$('#make_btn').trigger('click');
}
or use triggerHandler() method
Execute all handlers attached to an element for an event.
for (var i=0;i<10;i++)
{
$('#make_btn').triggerHandler('click');
}

Simply the original function manipulate some event property that a simple trigger('click') do not pass.
Try this
var e = jQuery.Event("click");
e.pageX = e.pageY = 140;
for (var i=0;i<100;i++)
{
setTimeout(function() {$('#make_btn').trigger(e)},100*i);
}
setTimeout for a nice effect and in order to prevent this check by site developer(from page source)
this.do_make_click = function() {
var nw = (new Date).getTime();
if((nw - last_click) < 70) {
return false;
}
//...
}

Related

removeEventListener doesn't work, and no error's are returned

As you can see in the code below I'm trying to remove an mouse move event listener however this listener doesn't get removed, and no errors are returned, as you can see the first time you double click on the menu the listener gets added, this works fine. the second time you double click it should get removed..
but it does not. I'm I removing it the wrong way ? can someone please help me with this problem I would really appreciate it..
function DragMenus()
{
ClickedSoManyTimes = 0;
Menu = document.getElementsByClassName("Box1");
AllMns = [Menu[1], Menu[2], Menu[3], Menu[4]];
var i;
for (i = 0; i < AllMns.length; i++)
{
AllMns[i].addEventListener("dblclick", function(i)
{
function MouseMove()
{
// Do Something
};
ClickedSoManyTimes = ClickedSoManyTimes + 1;
if(Number.isInteger(ClickedSoManyTimes/2))
{
console.log("Stop");
// delete Listener
document.removeEventListener("mousemove", MouseMove); // Fails
}
else
{
console.log("Start");
document.addEventListener("mousemove", MouseMove);
};
});
};
};
As described in this answer, the event listener can only be removed by using a reference to the original function that you referenced when you created it. In your code, multiple event listeners are created on the document, and each gets its own function MouseMove. When you then double-click another one of the items, it tries to remove an event listener related to its copy of MouseMove, but that may not be the copy that was originally used.
The best remedy is to take the definition of MouseMove out of your double-click-eventhandler, so it is one function instead of many that have the same name but are not the same function.

Modifying inserted element inside DOMNodeInserted event produces "too much recursion"

I'm writing code for a message board and when the user is writing a post and clicks "preview" it creates a new DIV element that contains the parsed post. I need to detect when this preview element is created and modify its contents. The following code creates infinite recursion in Chrome, Firefox halts after 5 recursions.
$('#c_post').on('DOMNodeInserted', function(){
var $preview = $('#c_post-preview');
if($preview.length) {
$preview.html(applyForEach(funcs, $preview.html()));
}
});
It's not related to applyForEach because I just added that code and I was getting the recursion error before that but here's the code for that anyway:
function applyForEach(arr, s) {
for(var i = 0; i < arr.length; ++i) {
s = arr[i](s);
}
return s;
}
var funcs = [createGifvVideo, createGfycatVideo, createHtml5Video];
The functions simply take a string, call replace on it, and returns the string.
You may break the infinite recursion by unbinding and binding event . so it would not go into infinite call.Try following-
$('#c_post').on('DOMNodeInserted',DomInsCallback);
function DomInsCallback(){
var $preview = $('#c_post-preview');
if($preview.length) {
$('#c_post').off('DOMNodeInserted');//here unbind first
$preview.html(applyForEach(funcs, $preview.html()));
$('#c_post').on('DOMNodeInserted',DomInsCallback);//bind again
}
}
I suppose #c_post-preview is inside #c_post. So when you modify #c_post-preview, the event DOMNodeInserted is triggered again. And you catch it again, and you modify #c_post-preview, and so on ...
Most probably you have nested #c_post-preview inside of #c_post, but i can't tell for sure, since you didn't post the HTML source. Of course this would lead to an infinite loop of triggering and catching events. But besides that, i don't think you want to applyForEach the content of the post preview, but the one of the post itself.
Consider the following: http://jsfiddle.net/wpb18pyu/
compared to: http://jsfiddle.net/wpb18pyu/1/

Javascript, click, doubleclick and drag in the same element

I'm in need of a function that figures out if the user is clicking, double-clicking or dragging the mouse.
Since it's all happening in the same canvas using the normal events doesn't work. I found this through google:
It is inadvisable to bind handlers to both the click and dblclick
events for the same element. The sequence of events triggered varies
from browser to browser, with some receiving two click events and
others only one. If an interface that reacts differently to single-
and double-clicks cannot be avoided, then the dblclick event should be
simulated within the click handler. We can achieve this by saving a
timestamp in the handler, and then comparing the current time to the
saved timestamp on subsequent clicks. If the difference is small
enough, we can treat the click as a double-click.
How could I achieve this in a good way?
First see if the click is pressed (for drag)? When it is released treat it as a click? and then if clicked again doubleclick?
How can I translate this to code? Help appreciated.
Something like the following should get you started, I'm using jQuery just to make it easier to show, this can be implemented with straight JS, it's just a lot of noise
$(function() {
var doubleClickThreshold = 50; //ms
var lastClick = 0;
var isDragging = false;
var isDoubleClick = false;
$node = ("#mycanvas");
$node.click(function(){
var thisClick = new Date().getTime();
var isDoubleClick = thisClick - lastClick < doubleClickThreshold;
lastClick = thisClick;
});
$node.mousedown(function() {
mouseIsDown = true;
});
$node.mouseUp(function() {
isDragging = false;
mouseIsDown = false;
});
// Using document so you can drag outside of the canvas, use $node
// if you cannot drag outside of the canvas
$(document).mousemove(function() {
if (mouseIsDown) {
isDragging = true;
}
});
});
I would probably work around this by putting a timer in the click event to check for another click.
time = 0
if(new Date().getTime() < time + 400) {
// Double click
throw new Error("Stop execution");
}
if(!!time)
throw new Error("Stop execution");
time = new Date().getTime();
// Single click
Something like that. Untested, and I can't think right now for some odd reason.

How to call touch or click event from a function for an element which was generated dynamically

EDIT:
I've made the changes Matthew and Yossi suggested and it still doesn't seem to work. Those changes I've edited in the post below too.
It now works!
I have a question for a particular problem I can't solve. If you know this question has been answered please send me the link as an answer. I'm trying not to use a framework in this case, but can use jQuery if necessary.
I have found answers on how to attach listeners via functions but I need something so as I wouldn't have to refactor all the code I already have. I'm a freelancer and am working on somebody else's code.
What happens is that I want to detect a touch event for a touch device. This code should work for a PC too so I need to detect clicks. There's this DIV which is created programatically to which I need to add the click or touch, depending on the device. Originally the function was called from an onmousedown event like this:
arrDivAnswers[c].onmousedown = onQuestionDown;
And this is the function it calls:
function onQuestionDown(e)
{
if(!itemSelected)
{
if(this.getAttribute('data-isCorrect') == 'true')
setStyleQCorrect(this, true);
else
setStyleQIncorrect(this);
this.querySelector('.answerText').style.color = '#ffffff';
this.querySelector('.isCorrect').style.visibility = 'visible';
}
itemSelected = true;
}
This was working fine. Now I've made this one which would try and select the correct event for a click or touch (I need a function because I have to use this more than once - and the isTouchDevice is working fine. I use that on some other apps so that code is pretty short and has been tested):
function detectEventClickOrTouch(element, functionToCall){
//detectEventClickOrTouch(arrDivAnswers[c], 'onQuestionDown');
if(isTouchDevice()){
element.addEventListener("touchend", functionToCall, false);
} else{
element.addEventListener("click", functionToCall, false);
}
}
The DIV element gets created like this on some loop:
arrDivAnswers[c] = document.createElement('div');
console.log( "Answer object #" + c + " = " + arrDivAnswers[c] );
arrDivAnswers[c].className = 'autosize';
arrDivAnswers[c].style.textAlign = 'left';
arrDivAnswers[c].setAttribute('data-isCorrect',false);
arrDivAnswers[c].setAttribute('data-isSelected',false);
divAnswerContainer.appendChild(arrDivAnswers[c]);
And then the events get attached to it like this (the older method has been commented out):
for(c;c < arrQuestions[index].arrAnswers.length;c++)
{
var curAnswer = arrQuestions[index].arrAnswers[c];
arrDivAnswers[c].onmouseover = function (e){setStyleQHover(e.currentTarget)};
arrDivAnswers[c].onmouseout = function (e){setStyleQUp(e.currentTarget)};
// Detect touch here *************************
detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);
//arrDivAnswers[c].onmousedown = onQuestionDown;
// Detect touch here *************************
arrDivAnswers[c].style.visibility = 'visible';
arrDivAnswers[c].querySelector('.answerText').innerHTML = curAnswer.strAnswer;
arrDivAnswers[c].setAttribute('data-isCorrect',curAnswer.isCorrect);
if(curAnswer.isCorrect)
{
//arrDivAnswers[c].classList.add("correctAnswer");
arrDivAnswers[c].className = "correctAnswer";
}
else
{
//arrDivAnswers[c].classList.remove("correctAnswer");
arrDivAnswers[c].className = "autosize";
}
arrDivAnswers[c].setAttribute('data-isSelected',false);
setStyleQUp(arrDivAnswers[c]);
itemSelected = false;
}
[...]
The debugger is throwing this error:
Uncaught TypeError: Object [object DOMWindow] has no method 'getAttribute'
I'm sure I'm messing up the "this" because I'm not calling the function properly.
I agree the "this" variable is getting messed up. The problem is that you are attaching an anonymous function as the callback that then calls eval on another method. This seems unnecessary.
Could you just do this:
function detectEventClickOrTouch(element, functionToCall){
//detectEventClickOrTouch(arrDivAnswers[c], 'onQuestionDown');
if(isTouchDevice()){
element.addEventListener("touchend", functionToCall, false);
} else{
element.addEventListener("click", functionToCall, false);
}
}
And then when you attach the event just do:
detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);
Since you now call the onQuestionDown function indirectly by the eval the this context seen by the onQuestionDown is the global namespace and not the the element which fired the event.
You don't need the eval anyway... you can pass the function it self
detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);
and:
element.addEventListener("touchend", functionToCall, false);

Jquery if its the first time element is being clicked

I need my script to do something on the first time an element is clicked and continue to do something different on click 2,3,4 and so on
$('selector').click(function() {
//I would realy like this variable to be updated
var click = 0;
if (click === 0) {
do this
var click = 1;
} else {
do this
}
});//end click
really I think it should rely on the variables but I can't think of how to update the variable from here on out any help would be awesome.
Have a look at jQuery's .data() method. Consider your example:
$('selector').click(function() {
var $this = $(this),
clickNum = $this.data('clickNum');
if (!clickNum) clickNum = 1;
alert(clickNum);
$this.data('clickNum', ++clickNum);
});
See a working example here: http://jsfiddle.net/uaaft/
Use data to persist your state with the element.
In your click handler,
use
$(this).data('number_of_clicks')
to retrieve the value and
$(this).data('number_of_clicks',some_value)
to set it.
Note: $(this).data('number_of_clicks') will return false if it hasn't been set yet
Edit: fixed link
Another alternative might be to have two functions, and bind one using the one function in $(document).ready() (or wherever you are binding your handlers), and in that function, bind the second function to be run for all subsequent clicks using bind or click.
e.g.
function FirstTime(element) {
// do stuff the first time round here
$(element.target).click(AllOtherTimes);
}
function AllOtherTimes(element) {
// do stuff all subsequent times here
}
$(function() {
$('selector').one('click', FirstTime);
});
This is super easy in vanilla Js. This is using proper, different click handlers
const onNextTimes = function(e) {
// Do this after all but first click
};
node.addEventListener("click", function onFirstTime(e) {
node.addEventListener("click", onNextTimes);
}, {once : true});
Documentation, CanIUse
If you just need sequences of fixed behaviors, you can do this:
$('selector').toggle(function(){...}, function(){...}, function(){...},...);
Event handlers in the toggle method will be called orderly.
$('#foo').one('click', function() {
alert('This will be displayed only once.');
});
this would bind click event to Corresponding Html element once and unbind it automatically after first event rendering.
Or alternatively u could the following:
$("#foo").bind('click',function(){
// Some activity
$("#foo").unbind("click");
// bind it to some other event handler.
});

Categories