JavaScript Event Not Firing - javascript

So I recently decided to start learning JavaScript. I come from only knowing VB.NET for programming knowledge and HTML & CSS for design. Anyway, scrap.tf is a website for TF2 banking which makes things automatic. I am planning to write a basic Chrome plugin, and I want to be able to if the button is clicked, this function will happen. I've got this all set up but when the button's clicked, it only takes me to scrap.tf/hats, EnQueueHatBank(); is the JS command they use there to join the queue. This even never fires unless I type it in after I'm on the site. Do I need to wait for it to fire?
if (location.href === 'http://scrap.tf/hats')
{
EnQueueHatBank();
}
else
{
window.location.href='http://scrap.tf/hats';
EnQueueHatBank();
}

You need to correct the comparison to use two equal signs.
if (location.href == 'http://www.scrap.tf/hats')
{
EnQueueHatBank();
}
Once you end up with tools like jslint, javascript even offers a === operator, which does type checking, too (checks if both sides are strings, as in this example).

I think this talk of = vs == is missing the point. You're changing window.location before you call EnQueueHatBank, so you navigate to a new page before the function is ever called. That's what's stopping it from running. So the first thing you need to do is:
Call EnQueueHatBank first.
if (location.href === 'http://www.scrap.tf/hats') {
EnQueueHatBank();
} else {
EnQueueHatBank();
window.location.href='http://www.scrap.tf/hats';
}
Clean up the code a little, because the structure is a little awkward. You're calling EnQueueHatBank either way, so there's no need for it to be in the if statement:
EnQueueHatBank();
if (window.location.href !== 'http://www.scrap.tf/hats') {
window.location.href = 'http://www.scrap.tf/hats';
}
Finally, remember that http://www.scrap.tf/hats/ probably goes to the same place as http://www.scrap.tf/hats, not to mention https://www.scrap.tf/hats?foo=bar and so forth. You'd be better off with a less-strict test:
EnQueueHatBank();
if (window.location.href.indexOf('://www.scrap.tf/hats') > -1) {
window.location.href = 'http://www.scrap.tf/hats';
}
EDIT: Based on your comment, you will need to do this:
if (window.location.href.indexOf('://www.scrap.tf/hats') > -1) {
EnQueueHatBank();
}
else {
window.location.href = 'http://www.scrap.tf/hats';
}
This will only work if your program runs again after navigating to scrap.tf/hats, so make sure it runs every time you load a new page.
For security reasons, you cannot initiate code on one page and have it continue after you've navigated somewhere else. You'll have to call EnQueueHatBank from the page it's meant to run on.

You should use comparison === operation, but you did an value assignment =.
if (location.href === 'http://www.scrap.tf/hats')
{
EnQueueHatBank();
}
else
{
window.location.href='http://www.scrap.tf/hats';
EnQueueHatBank();
}

Related

Exit object method in work

I am making some SPA app. When app is running at some point i start one method. Some code in there give me boolean. I would like to stop method when is 'half executed' and that boolean is false. I need something like break for loop, but that might work with methods. It is possible ?
Thanks for answers.
if(el === 'work'){
if(!actions.authentication()){
// That code is in another method. I want break that with some code placed here.
}
}
It's kinda obvious and you almost answered yourself, but you can use return ...
if(el === "work") {
if(actions.authentication() == false) {
return
}
}

How would I go about using window.find() activate on that text only once

I use hack.chat a bit, and I saw that they have a bot, but the bot program wasn't working for me so I decided to make my own.
var finderBinder;
var searchFor = function(command){
finderBinder = window.find(command, true, true);
if(finderBinder){
if(command === "/hello"){
ws.send(JSON.stringify({cmd: "chat", text: "hello!"}));
}
else if(command === "/cry"){
ws.send(JSON.stringify({cmd: "chat", text: "wah waha wahhh"}));
}
else
{
console.log("it was found but it was not a command.")
}
}
else
{
console.log("Did not find the command");
}
}
var loopdeloop = 0;
while(loopdeloop === 0){
searchFor("/hello");
searchFor("/cry");
}
Now, the first part works if I just run that by itself on the page, and enter searchFor("/hello"); that would work, but if I wanted it to just automatically do that whenever a message popped up, I attempted the loop,(In a empty chatroom so it wouldn't spam a used room if it did) and it crashed my browser. I know why it did that. because it just checked forever, and it saw it forever so it kept on trying to do the code forever..
But how would I make it only run the searchFor when a new text showed up so it would run the text in it and if it was a command it would do the command? Or is there a better way to do this?
The simplest way to stop your function from looping to infinity (and beyond!) would be to call it once every X seconds/minutes/hours/lightyears.
Using setInterval(searchFor, 1000); where the second parameter is the time interval in milliseconds.
To pass a parameter to your searchFor function, you must create an anonymous function so it doesn't get called right away.
setInterval( function() { searchFor ("/hello"); }, 1000 );
This will call your function every ~1 second, although keep in mind there is some overhead to javascript and there will be a slight delay. Also be careful of looping your function too often, as it will be expensive, and browsers have a built in delay, for example, you will not be able to setInterval to 2 ms and have it function normally cross browser.
Edit: The more elegant solution of binding an event to a change in the textbox is also possible, depending on how the page is setup and your access to it, hard to answer without that structure known.

Optimizing search functions in Sencha Touch 2

I hope I'm not breaking any guidelines or anything as this is mostly a showcase of my search setup. There are a few question at the bottom. I promise.
I've made a Sencha Touch 2 PhoneGap app (which is now live in the AppStore for iOS, Android will be ready soon).
The basic premise of the app is a (somewhat huge) searchable list (with a couple of additional filters). Thus search performance is essential.
A rundown of my search controller:
When looking at examples I found people using either a submit button or search on keyup, since the latter interested me the most this is where I started.
In the examples I found, only the keyup listener was activated, a quick fix:
'searchfield[itemId=searchBox]' : {
clearicontap : 'onClearSearch',
keyup: 'onSearchKeyUp',
submit: 'onSubmit',
action: 'onSubmit',
paste: 'onSubmit',
blur: 'onSubmit'
}
Now, why are keyup and submit different you might ask?
Well, the onSubmit function just runs the search function (more on that later).
The onClearSearch just clears the filters set on the store and then adds the non search based ones back in.
The onSearchKeyUp function is where it gets interesting. Since the list is huge, searching on every single letter equals poor performance. The search field stalls while searching (especially on older devices), so while the user keeps tapping letters on the keyboard nothing shows up, while at the same time queuing up javascript and (in some cases) leading to the user tapping letters again so that when all the search functions are actually done, the input might not even be what the user intended.
I remedied this by trying to deduce when the user has finished typing. I did this by having the keyup triggering a timer, in this instance 650 ms, if another keyup event is triggered within this period, the timer is cancelled, if it runs its course it triggers the search function. This timer can of course be set higher or lower. Lower means the user has type faster for it not to search while typing. Higher means that the user will have to wait longer from their last keyup event for the actual searching to begin (perceived as lag).
Of course, there is an exception, if the keyup event is from the enter key, it searches right away. Code:
onSearchKeyUp: function(searchField,e) {
if (e.event.keyCode == 13){
window.clearTimeout(t);
window.timer_is_on=0;
searchFunction();
} else {
doTimer();
}
function timedCount()
{
t=setTimeout(function(){timedSearch();},650);
}
function timedSearch()
{
console.log('b4 search');
searchFunction();
window.timer_is_on=0;
}
function doTimer()
{
if (window.timer_is_on === 0)
{
window.timer_is_on=1;
timedCount();
} else {
window.clearTimeout(t);
window.timer_is_on=0;
console.log('cleared timeout');
doTimer();
}
}
}
onSubmit: function(searchField,e) {
if (window.timer_is_on === 0)
{
console.log('timer was not on when done was pressed');
} else {
console.log('timer was on when done was pressed');
window.clearTimeout(t);
window.timer_is_on=0;
searchFunction();
}
} else {
searchFunction();
},
So for the search function. I think I might have some room for improvement here.
First off, I noticed that when I had scrolled down the list and searched, I could end up below the actual list content, unable to scroll up. So the first thing the search function does is scroll to top.
As I mentioned in the beginning of the post, I have some additional filters. These are toolbar buttons which basically set variables and then trigger the search function. Within the search function, filtering is done based on the variables. I combined the search and filter functions as they both needed to clear filters and add them back in.
You'll also notice a loading mask and a delay. The delay is strictly empirical, turned out that a delay of 25 ms was needed for the loading mask to actually show.
My search function code:
function searchFunction() {
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Searching'
});
setTimeout(function() {
Ext.getCmp('lablist').getScrollable().getScroller().scrollTo(0,0);
var searchField = Ext.getCmp('searchBox');
queryString = searchField.getValue();
console.log('Please search by: ' + queryString);
var store = Ext.getStore('LabListStore');
store.clearFilter();
genderFilterFuncForSearch();
ageFilterFuncForSearch();
if(queryString){
var thisRegEx = new RegExp(queryString, "i");
store.filterBy(function(record) {
if (thisRegEx.test(record.get('Analysis'))||thisRegEx.test(record.get('Groupname'))) {
return true;
}
return false;
});
}},25);
}
function ageFilterFuncForSearch() {
if (ageFilter === 'A') {
Ext.getStore('LabListStore').filter('adult', '1');
} else if (ageFilter === 'C') {
Ext.getStore('LabListStore').filter('child', '1');
}
Ext.Viewport.setMasked(false);
}
function genderFilterFuncForSearch() {
if (genderFilter === 'M') {
Ext.getStore('LabListStore').filter('Male', '1');
} else if (genderFilter === 'F') {
Ext.getStore('LabListStore').filter('Female', '1');
}
}
That's basically my search setup. As this is my first Sencha Touch project it's been sort of a trial and error based workflow but where it's at now seems pretty good.
Hopefully someone'll have a few pointers to share (and hopefully I had some that some of you hadn't thought of).
A big part of this was collected from loads of different SO posts, thanks!
I promised I would have some questions:
Can you clear individual filters?
If so, would it be better
for performance to check which filters are set and then just
clearing those insted of calling store.clearFilter?
As you can see my searchfunction uses regex, is there a way to achieve the same
kind of search without converting it to a regex object, would it be
better for performance?
PS. Regarding 1)- I've found one way, store.filter('field', '', true); would actually clear a filter that was set in the same way. I couldn't clear the search filter in the same way though.

Using if-if or if-else if-else within a simple function

I wrote this simple function once, to display notifications on hash change :
function watchHash() {
if(location.hash == '#thanks') {
displayNotification('Thanks for your feedback, I\'ll try to get back to you as soon as possible.'); // Notify on form submit success
}
if(location.hash == '#error') {
displayNotification('Oops, something went wrong ! Please try again.'); // Notify on form submit error
}
}
window.onhashchange = watchHash;
I came back to it today and I thought, is it correct if I write it this way instead?
function watchHash() {
if(location.hash == '#thanks') {
displayNotification('Thanks for your feedback, I\'ll try to get back to you as soon as possible.'); // Notify on form submit success
}
else if(location.hash == '#error') {
displayNotification('Oops, something went wrong ! Please try again.'); // Notify on form submit error
}
else {
return;
}
}
window.onhashchange = watchHash;
If so, is it relevant?
I'm a bit confused here, I'd like to stick to best practices.
Thanks for your help.
The second scenario is much better. Why?
Because in the first scenario if first condition is met or not met - it doesn't matter, the second case is checked too, the third, the fourth and so on.
In second case If the first case fails, then the second one is tested, if it fails, the third is tested, so your software does not spend useless time checking scenario which will not happen.
In your case, either method works just as well. However, there are some times when using the else clause is truly the best way to handle over-lapping logic.
Untested p-code, just for an example
if (isRaining) && (iHaveUmbrella) {
iGetWet = false;
} else if (isRaining) {
iGetWet = true;
} else {
iGetWet = false;
}
In this case, the else if means that if the first condition is true, the second condition is never checked.
it might not be relevant for this usecase, but the 1st way is slower because the interpreter has to check conditions more often.. consider a game loop which is called 60 times per second and you don't structure your if else blocks you will get a huge performance hit.
Either way works properly. Differences between two are readability and pattern of coding.
Regarding readability, I personally prefer the first way to work on a single input. Second one works in better performance, but you might lost in multiple boundaries if you're not proficient developer.
Regarding pattern of coding, we can see that the first one won't return anything. Second one will return null ONLY IF hash tag is neither your selections. You can't use this function to check the condition because it won't return when hash tag is either '#thanks' or '#error'.
Your second version is "correct" insomuch as its functionality is identical to the first version, but the added code is entirely redundant.

ExternalInterface and Javascript not working in harmony

The other day I posted about a Flash/Javascript issue I was having. Please see this:
Issues with javascript properly loading and seeing everything
I know how I want to fix it, but I am not in any way shape or form familiar with actionscript. I have avoided adobe products like the plague from when I was developing myself since it costs a fortune to buy and of their products, but big employers love it and pay for it so here I am. Our "Flash" guy just left the team and I inherited this issue. If you read my other post you know what is going on so I will move on. I want to make a simple call from actionscript to my javascript taht is referenced in my other post. I specifically want to call the CheckboxCollection function from inside of actionscript. I don't need to pass it any args or anything of the such from inside of actionscript. All I need it to do is run that function once the flash is done loading. The javascript function will take care of everything I need, I just HAVE TO HAVE IT called from actionscript to make everything work in harmony. I am in the middle of teaching myself all things adobe and actionscript(much to my dismay), but I really have no clue where top go from here to make this work. I have reviewed adobe documentation, but until I have a better grasp of the language as a whole I am still lost. I copied most of my actionscript on to here, but I did leave out everything that had to deal with mouseover events, since my issue is not about a mouseover and they all work like a charm. Thanks in advance!
-------------------------------------------------------------------------------------------UPDATE: I had to stop working on this to get some other things done, but I am back to step one. NO matter what I do I am having no luck making this work. I have tried all suggestions on here, and tried everything I KNOW how to do, but I am having no luck. If anyone could take a look at this post and the one that I link to (It is the companion javascript for this) and see if they can come up with anything. I have tried so many different iterations of my code there is no use putting all of my trials up for example of what doesn't work, Thanks Everyone!
/*
JavaScript External Calls
*/
function RegisterExternalCalls():void
{
if(ExternalInterface.available)
ExternalInterface.addCallback("HighlightWheel", HighlightWheel);
}
function HighlightWheel($args:String,$show:String,...arguments):void
{
$args = $args == "financial"?"center":$args;
var _obj:Object = ObjectCollection[$args].Objects.Click;
if(ObjectCollection[$args].Objects.currentObject.name.toLowerCase() == "center")
{
bcenter = true;
_obj = ObjectCollection[$args].Objects.currentObject.getChildByName("financialBtn");
}
if(CBool($show))
{
if(arguments.length > 0 && arguments[0] == "TITLE") // || $args == "center")
_obj.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER));
else
{
if(ObjectCollection[$args].labels.Label.toUpperCase() === "CENTER")
{
ObjectCollection["income"].Objects.Click.gotoAndPlay(2);
ObjectCollection["property"].Objects.Click.gotoAndPlay(2);
ObjectCollection["education"].Objects.Click.gotoAndPlay(2);
ObjectCollection["health"].Objects.Click.gotoAndPlay(2);
ObjectCollection["retirement"].Objects.Click.gotoAndPlay(2);
}
else
{
_obj.gotoAndPlay(2);
}
}
}
else
{
if(arguments.length > 0 && arguments[0] == "TITLE")
_obj.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT));
else
{
if(ObjectCollection[$args].labels.Label.toUpperCase() === "CENTER")
{
ObjectCollection["income"].Objects.Click.gotoAndPlay(11);
ObjectCollection["property"].Objects.Click.gotoAndPlay(11);
ObjectCollection["education"].Objects.Click.gotoAndPlay(11);
ObjectCollection["health"].Objects.Click.gotoAndPlay(11);
ObjectCollection["retirement"].Objects.Click.gotoAndPlay(11);
}
else
{
_obj.gotoAndPlay(11);
}
}
}
}
function CallExternalFunction($label:String,$show:Boolean = true):void
{
var lbl:String = $label.toLowerCase().indexOf("btn") > -1?"financialTitle":$label + "Title";
if(ExternalInterface.available)
ExternalInterface.call("COUNTRY.Financial.highlightProductGroup",lbl,$show);
}
function CBool($value:String):Boolean
{
if($value == "true")
return true;
else
return false;
}
function PrintSetup($evt:MouseEvent):void
{
var pjob:PrintJob = new PrintJob();
if(pjob.start())
{
pjob.addPage(wheel);
pjob.send();
}
}
I believe you do this through ExternalInterface.call and pass the javascript function that should be called, like so:
ExternalInterface.call( "CheckboxCollection" )
If you need to pass arguments:
ExternalInterface.call( "CheckboxCollection", value1, value2 )
For more information here is the documentation
If in your JS you don't need necessarily this:
var CheckboxCollection = function()
try to change it to this:
function CheckboxCollection()
even if it seems (if the JS is still the same) you have anything nested. Maybe you can try too call it this way to (but I never tried anything similar):
ExternalInterface.call("SOME.PLACE.QuoteRequest.CheckboxCollection");

Categories

Resources