Using CAAT I can bind an event to adding a behavior to an actor. However I cannot figure out how to repeat the behavior effect on consequent event trigger.
Here is the code:
circle.mouseDown = function(e){
circle.emptyBehaviorList();
circle.addBehavior(circle_jump);
}
http://jsfiddle.net/S4frL/1/
Clicking on the circle makes it jump once, then clicking again does nothing, although BehaviorList should be empty before adding the same behavior again.
Am I missing something?
Thanks in advance!
That's because you have to declare/apply the behaviour once, then when you need the actor (ball) to move you just have to say "when".
Basically you have to change your code to something like this:
circle.addBehavior(circle_jump);
scene.addChild(circle);
circle.mouseDown = function(e){
circle_jump.setFrameTime(scene.time,2000);
}
setFrameTime( ) tells the actor when [scene.time -> now] and how long [2000 ms] the actor has to follow his behaviour.
I hope I've been clear enough.
ps. The ball now takes a jump at page load, that's because you have to comment this line:
var circle_jump = new CAAT.PathBehavior().
setPath(path_jump).
/* THIS ONE setFrameTime(0,2000). */
setCycle(false).
setAutoRotate(false);
Related
My problem is not a double click on same button but on 2 buttons.
User make a double click on a button.
The first click is detected by a first button
the controller do the action
the UI is refreshed, another button is display at same position
the second click is catched by the second button
=> user don't want click on the second button
How can I avoid this ?
I have tested :
To disable all UI buttons during action
but if action is really quick, buttons are enable before the second click
To not put 2 buttons on same place in the UI
not always possible and with responsive UI it's not possible to manage all cases
To add a global timestamp on click, and test during the second click if we have 500ms
_click: function(args)
{
// to avoid double click user need wait 500ms between each click
if(window.paperbutton_timestamp)
{
var diff = new Date() - window.paperbutton_timestamp;
if(diff < 500)
{
window.paperbutton_timestamp = new Date();
return;
}
}
window.paperbutton_timestamp = new Date();
if(scope.click)
{
scope.click(args);
}
},
Ok it does the job.
Now my problem is I have many protractor end to end tests, with more 2000 clicks.
Some protractor click are done in less 500ms.
Which solution can I have ?
1. Add a wait after each click
(more 2000 wait to add manually)
2. Set the 500ms in a global variable and override this value to 0ms
how to override on each test and each page refresh ?
3. Override protractor click ?
Seam is the better solution but I don't know how to do this.
Do you have another better idea :) ?
This is usually solved using good old human-computer interaction. Try using a style of button that visually reacts to hover, mousedown and mouseup events. This is usually enough to the user understand that a double click is not necessary. Stackoverflow itself has an awesome example:
Iddle button:
Hover button:
Mousedown button:
Mouseup button:
But if you really wish to prevent undesired clicks, maybe the best approach would be to disable buttons during actions and when you are about to re-enable then, put this action in a timeout, so the disabled buttons will last a little longer.
Another suggestion
You could implement a global function to spawn an invisible div covering the whole screen when required. This would prevent everything onscreen from working.
<div style="position:fixed; top:0; left:0; width:100vw; height:100vh; z-index: 10000"></div>
Put it in your layout file, usually app.component.html, and implement a *ngIf for it show up only when necessary. Also, its z-index should be greater than the z-index of any other element in your whole app.
have you consider Using *NgIf for both the buttons
**
<button *NgIf="oneActive" (click)="oneActive=false;callfunction()">one</button>
<button *NgIf="!oneActive" (click)="oneActive=true;callfunction2()">two</button>
**
It would be better if you write a custom function for protractor click:
protractor.ElementFinder.prototype.waitClick = function(wait){
browser.sleep(wait);
this.click();
};
describe('Tests', function() {
element.all(by.css('#testElements')).get(0).waitClick(1000)
});
Since, overriding the default click function is not recommended.
I am using a simple script which :
displays a message after 3 seconds if user has not clicked by then (using a setTimeout),
then if user clicks within 5 seconds, then the message should not appear within the defined setTimeout,
after this previous click if the user does not click for 5 seconds, then the user will see the message and so on...
this goes on a like a loop.
My script acually works but I have an issue because it seems it is double firing "exponentially". I think my error is how I created this "loop" and self referencing the setTimerForMsg inside itself.
Here is a Demo: https://jsfiddle.net/3wm7z576/11/
Here is the code:
html
<div id="zone">
<span id="msg" class="displayNone">this is the messager</span>
</div>
js
setTimerForMsg(3000, 5000);
function setTimerForMsg(initial_timelaps, new_timelaps) {
var timer = setTimeout(showMsg, initial_timelaps);
$("#zone").on('click', function(e) {
//if user clicks before msg appears (but after timer was initiated )
clearTimeout(timer);
//if user went beyond timer laps and msg already visible on Step (n)
//remove it when move to Step (n+1)
$('#msg').addClass('displayNone');
console.log("message1");
//loop the process for the next Step
setTimerForMsg(new_timelaps, new_timelaps);
});
}
function showMsg() {
$('#msg').removeClass('displayNone');
console.log('message2');
}
This issue is important because while this script is simple, in my real app it does other things that could drain the browser performance so I can't have them be done 64 times!
And you can see here in the console of the Demo, each time I click the events occur twice : 2 times , then 4 times then 8, then 16, then 32 times, and so on...
use $("#zone").off('click', ... to remove the eventListner you previously added. Otherwise you're just adding more and more click actions.
Documentation here
Well first of all your new_timelaps parameter is unused, this might cause some confusion.
As for the exponential growth in logs, this is caused by the fact that you don't remove your event listener, so everytime the time for your interval is passed or you click ur button another click event with the same function is aplied to your button.
How you would solve this is by using
$( "#zone").unbind( "click" )
to make sure the event is only aplied once and not get aplied again or the old ones get removed.
I've got slider in template glitching, and code is minimized. So, got tired of looking for the cause of the problem and decided to use a quick hack.
I need to fire a div click multiple times.
I've used this piece of code to trigger a click
$('.control-prev').trigger('click');
Works fine for one time click.
Now, how do i make it click multiple times?
http://jsfiddle.net/br4Lmyso/ (warning: creates three alerts, just to quickly show it works)
// set your count to whatever you want. Get a reference to the div
// so you're not querying the DOM everytime.
var triggerCount = 3;
var triggerDiv = $('.control-prev');
// loop!
for(var i = 0; i < triggerCount; i++) {
triggerDiv.trigger('click');
}
To be clear, trigger(...) does not simulate the click behavior and there is no way you can simulate the click behavior. What it does is to call the function that handle given event. These two are total different. For example:
$('#test').click(function() {
console.log("Clicked");
});
$('#test').dblclick(function() {
console.log("Double Click");
});
$('#test').trigger('click');
$('#test').trigger('click');
Despite of rapidly trigger two clicks, the double click will not trigger.
Ok this example code contains a button. Forget about the button, it does not exist, cannot be referenced and cannot be edited.
The buttons dont exist in this example - they merely represent another process. However the fields still need to be updated from values. Sorry I couldn't explain it better.
Answer:
http://jsfiddle.net/piezack/X8D4M/56/
If you want the event to fire whenever the text inside the box changes, then I think you're best off using jquery's keyup event instead of blur:
$('#FormCustomObject6Name').keyup(
function()
{
var x = $('#FormCustomObject6Id').val();
$("a[href*='http://www.msn.com']").attr('href',('http://www.google.com/search?q='+ x));
$('a#link').text('Link has been updated');
}
);
The only problem with this is that it won't catch instances where users enter data without using their keyboard (paste via right click, etc.).
You could use a mouseover event, say over the button or the link.
I changed this
$('.butter').mouseover(function(){
to have a mouseover the button.
Example: http://jsfiddle.net/X8D4M/39/
You can trigger events on objects yourself manually by using trigger(event).
So this might work for you:
$('button.butter').trigger('click');
Did you try just triggering a click?
$('button.butter').click();
Here's what you're looking for.
$('#FormCustomObject6Name').trigger('blur');
Okay, this is probably not the most efficient solution, but if you use setInterval to check for the changed value you're guaranteed to cover all sources of the change.
setInterval(function(){
var id = $('#FormCustomObject6Id').val();
var name = x + $('#FormCustomObject6Name').val();
if (id.length > 0 && name.length > 0){
$("a[href*='http://www.msn.com']").attr('href',('http://www.google.com/search?q='+ id));
$('a#link').text('Link has been updated');
}
},500);
I wonder if someone here can help me figure out this problem.
I need to temporarily disable the code in the 'onblur' attribute of an input field, and then re-enable it after. The reason I need to do this is b/c my workflow is as follows:
1) An AJAX event is triggered by the "onblur" attribute of an input field, which resulted from the user tabbing off of the field to go to the next one.
2) The page is updated and my Javascript code is called from the "onafterajax" hook.
3) My code does some serious re-arranging of the DOM, which results in loss of focus on the current input field. So, I must restore focus manually. I've attached a focus handler to all input fields, so I can keep track of which field had focus last, so I know where to put the focus.
4) I call .focus() on the correct input field, which for some reason causes 'onblur' to fire on that same input field. This happens in all browsers. This a) suggests that the field still had focus?! and b) Creates an infinite loop, since Step 1 executes again...
In order to avoid the infinite loop, I've done the following. Before performing any DOM rearrangements, I do this:
if ( window.currentFocusId ) {
this.savedFocusId = currentFocusId;
this.onblur_bak = $(this.savedFocusId).onblur;
$(this.savedFocusId).onblur = null;
LOG.warn(" --- Disabling blur on " + this.savedFocusId);
}
Then, after I've completed my DOM hackery, I do this:
setFocusAndRestoreBlur : function(req) {
if ( this.savedFocusId ) {
var focusElement = req.form.elements[this.savedFocusId];
LOG.warn(" ------ Focusing on " + focusElement.id);
if (focusElement) {
focusElement.focus();
if (focusElement.select) {
focusElement.select();
}
}
LOG.warn(" --- Enabling blur on " + this.savedFocusId);
$(this.savedFocusId).onblur = this.onblur_bak;
delete this.onblur_bak;
delete this.savedFocusId;
}
}
This works well in all browsers (FF, Chrome, Opera), except for IE6.
In IE6 it kind of works. First of all, in order to make it work in IE at all, I had to modify the call to "setFocusAndRestoreBlur" like so:
setTimeout(function() {
this.setFocusAndRestoreBlur(req);
}.bind(this), 0)
This has the effect of running the code after the current thread finishes. For some reason IE does not respect the fact that I have removed the onblur handler, if I try to set the focus in the same thread!
So, with this modification, the first time I enter some numbers into a few fields, everything is fine. I get log output that looks like this:
Type something into j_id390 and tab off:
warn[16:35:33,091]: blur fired from statementProgramsDataTable:0:j_id390
warn[16:35:33,092]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[16:35:33,225]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[16:35:33,225]: --- Enabling blur on statementProgramsDataTable:0:j_id397
Type something into j_id397 and tab off:
warn[16:35:38,259]: blur fired from statementProgramsDataTable:0:j_id397
warn[16:35:38,260]: --- Disabling blur on statementProgramsDataTable:0:j_id446
warn[16:35:38,390]: ------ Focusing on statementProgramsDataTable:0:j_id446
warn[16:35:38,390]: --- Enabling blur on statementProgramsDataTable:0:j_id446
However, when I go back to the first input field, overwrite the value and tab off, I get this:
warn[17:18:15,454]: blur fired from statementProgramsDataTable:0:j_id390
warn[17:18:15,469]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:16,870]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:16,874]: --- Enabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:18,097]: blur fired from statementProgramsDataTable:0:j_id397
warn[17:18:18,112]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:19,550]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:19,555]: --- Enabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:24,492]: blur fired from statementProgramsDataTable:0:j_id397
warn[17:18:24,187]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:24,531]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:24,545]: --- Enabling blur on statementProgramsDataTable:0:j_id397
Most of the time this loop then goes on for a variable number of iterations and then stops with the input field correctly focused. I've seen a few times where the loop appeared to be infinite.
It looks like IE is not respecting the absence of the onblur handler again? But only sometimes?!
So, this is where I'm confused. Why is IE behaving inconsistently? What am I doing wrong? Is there a better way?
Any ideas would be appreciated.
Val
EDIT:
I have tried the approach suggested by JeanK. It still does not work, but I learned something potentially useful from this attempt.
I wrap the original 'onblur' function with a proxy, like this:
this.allowBlur = false;
if ( !this._functionsEqual($(this.savedFocusId).onblur, this._proxiedBlur) ) {
$(this.savedFocusId).onblur = this.proxyOnBlur($(this.savedFocusId).onblur);
}
And the proxy function itself:
proxyOnBlur : function(method) {
var object = this;
this._proxiedBlur = function(event) {
if ( object.allowBlur ) {
return method.apply(this, [event || window.event])
}
};
return this._proxiedBlur;
},
Now, all I have to do is set this.allowBlur as the very last thing, and I should be fine. And herein lies the problem. In all other browsers, the onblur event is fired as I modify the DOM tree, so it correctly gets blocked. But in IE6, no matter what I do, it fires the onblur event after all of my code. I even tried this:
setTimeout(function() {
this.allowBlur = true;
}.bind(this), 2)
and my this._proxiedBlur still gets called after I set the flag to true!
So, the question becomes - Where do I need to put my flag reset so that it executes after IE6 reacts to the DOM changes?
ok, I figured it out. The trick was to set the focus in the separate thread:
setTimeout(function() {
this.setFocusAndRestoreBlur(req);
}.bind(this), 0)
and then reset the flag with another nested setTimeout(). This seems to sequence the events properly in IE6:
setFocusAndRestoreBlur : function(req) {
setFocus(req);
setTimeout(function() {
this.allowBlur = true;
}.bind(this), 0)
}
I suggest that you disable blur in a logic way.
I mean, something like this:
Suppose that this is your onblur event function, you can control it by flags:
function myOnBlur() {
if (ableToExecute) {
executeWhatYouNeed();
}
}
So, when you do your request, you set the flag to false, and then after the response and your needed processing, you reset the flat to true, so your onblur event can trigger your request again.
I don't know if this simple control can help you, but you can try it.