Greasemonkey js going to subpage, again, again and wait - javascript
sorry for bad english and maybe newby question.
I want to write script that makes something automatic (in web game), everything I need to is go to subpage, then next one, and other. Then script needs to wait specific time and repeat.
I'm using global variable (boolean) and if its true I'm trying to do something like that:
unsafeWindow.location.href = linktodo + linkequipeq + accesKey;
unsafeWindow.location.href = linktodo + linkjednoraz + accesKey;
Script skips first going to page. Using setTimeout doesn't helped. I'm using:
// #run-at document-end
Still not working, I tried to use addEventListener wit parametr 'load' but nothing (I think I need to "clean" eventlistener by closing the window? - tried to use removeEventListener after first function/window redirect is done, fail).
Is it possible to do this without opening and closing new tabs/popups?
Will script like this work in inactive tab?
Can somebody post some example of doing it or tutorial I'll learn it alone?
P.s
for some explanations, those subpages will fill on some equipment, then get some cash and go quest.
linktodo is hostname, linkequipeq is pathname, and accesKey is some secuirty builded in webpage to not doing something after reload (I get acces to it via GM using unsafeWindow).
Huh mayby somebody understand me :D
// #include "site"
// #grant GM_addStyle
// #grant GM_getValue
// #grant GM_setValue
// #grant GM_deleteValue
// #grant GM_listValues
// #grant GM_xmlhttpRequest
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #run-at document-end
var wypki = 0;
var cash = 0;
var czas = 0;
var autowypki = false;
var linkwypki = '?a=q';
var linksklep = '?a=town=';
var linkequipeq = '?a=equip';
var linkjednoraz = '?a=buyone';
var linkrealm;
var accesKey = unsafeWindow.accessKey;
var numbercash = document.getElementsByClassName('cash')[0].getElementsByClassName('panel');
var mynumbercash = numbercash[0];
var cash1 = (mynumbercash.innerHTML);
cash = cash1.slice(28, cash1.indexOf('PLN'));
cash = parseInt(cash.replace(/\s+/g, ''));
var linktodo = link.slice(0, link.indexOf('?a='));
function doquest() {
'use strict';
unsafeWindow.location.href = linktodo + linkwypki;
setTimeout(function () {
unsafeWindow.getElementById('start')[0].click();
}, 2000);
}
function zlomek() {
'use strict';
if (cash < 20000) {
unsafeWindow.location.href = linktodo + linksklep + accesKey;
}
}
function jednoraz() {
'use strict';
if (autowypki === true && cash > 20000) {
unsafeWindow.location.href = linktodo + linkjednoraz + accesKey;
}
}
function equip() {
'use strict';
unsafeWindow.location.href = linktodo + linkequipeq + accesKey;
}
/* --- Main ----*/
function autoQuest() {
'use strict';
autowypki = true;
equip();
setTimeout(jednoraz(),5000);
}
/* --- Main ----*/
if (a === linkwypki) {
var przyciskwypki = document.getElementsByTagName("form")[0].getElementsByTagName('div')[13];
przyciskwypki.innerHTML = przyciskwypki.innerHTML + '<input class="button" type="button" style="height: 20px; width: 110px;" id="autowypki" value=" Robimy wypki" />';
}
document.getElementById("autowypki").addEventListener("click", autoQuest, false);
Greasemonkey scripts are exactly like normal scripts, they don't run unless the page is loaded
On any page that this script is injected loaded, this script will add a click event listener to the element with ID='autowypki'
when that event is fired, the script will set the page to linktodo + linkequipeq + accesKey in function equip
and that's all this script will ever do
there's nowhere that invokes functions doquest and zlomak, so they're just along for the ride in this script
function jednoraz is set to be called after a timeout of 5 seconds, but by then equip has loaded a new page, so, jednoraz wont actually be called as the page it was on is no longer loaded
however, if the same click event is fired in the page that equip loads, then perhaps jednoraz will be called - and then the page linktodo + linkjednoraz + accesKey will be loaded ... I say perhaps, because I'm not 100% sure what function equip will do if it's effectively setting the page to the current page - i.e. if that causes a page load, then jednoraz wont be called because the timeout will probably never fire as the page has reloaded
Related
Code working in browser console but not in tampermonkey
I am trying to run the following block of code on https://lichess.org/uZIjh0SXxnt5. var x = document.getElementsByTagName("a"); for(var i = 0; i < x.length; i++) { if(x[i].href.includes("WaisKamal") && x[i].classList.contains("user_link")) { x[i].innerHTML = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + x[i].innerHTML; } if(x[i].href.includes("WaisKamal") && x[i].classList.contains("text")) { x[i].innerHTML = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + x[i].innerHTML; console.log(x[i]); } } I am using tampermonkey to automate the process. When the page loads, the first if statement runs correctly, but not the second one. However, when I run the second one from the browser console, it works fine. Here is what the script does in more detail (I want to add those orange "GM"s): Without the script With the script What I want I have checked this but it didn't solve my problem. Any help? Thanks in advance.
Most of that page is loaded dynamically (AJAX-driven), which means that your script will normally finish running long before the nodes, that you are interested in, appear in/on the page. You must use AJAX-aware techniques such as waitForKeyElements or MutationObserver. Here's a complete Tampermonkey script that illustrates the process: // ==UserScript== // #name _Lichess.org, Glorify select users // #match *://lichess.org/* // #require https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js // #require https://gist.github.com/raw/2625891/waitForKeyElements.js // #grant GM_addStyle // #grant GM.getValue // ==/UserScript== //- The #grant directives are needed to restore the proper sandbox. waitForKeyElements ("a[href*='WaisKamal']", spiffifyLink); function spiffifyLink (jNode) { var oldHtml = jNode.html (); var newHtml = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + oldHtml; jNode.html (newHtml); } See this other answer for more information about choosing and using waitForKeyElements and/with jQuery selectors.
How do I remove the javascript blocking from some links?
For example, I am trying to change this: <a href="javascript: void(null)" class="jv-redirectCandidate" key="pcxe7gwP" >Some Name</a> Into this: Some Name I need the string "pcxe7gwP" that is currently part of key="pcxe7gwp" and then I want to attach it to part of a URL https://www.foo.com/something.aspx?p= and the use that as the href in place of the current "javascript: void(null)" I am using the Tampermonkey Chrome extension and trying to create a userscript to accomplish this. I am new to userscripts and would love any help. Thanks!
Test in Greasemonkey, don't need jquery. // ==UserScript== // #name Change link href with it's key // #namespace test // #grant none // #version 1 // #include http://localhost:8000/*.html // ==/UserScript== var prefix = 'https://www.foo.com/something.aspx?p='; var links = document.querySelectorAll('a.jv-redirectCandidate[key]'); for (var i = 0; i < links.length; i += 1) { var link = links[i]; link.href = prefix + link.getAttribute('key'); }
If I understood right, this is what you are looking for: <html> <script type="text/javascript"> function changeHREF(element){ element.href = "https://www.foo.com/something.aspx?p=" + element.key; } </script> <body> Some Name </body></html> Another possible solution: <html> <script type="text/javascript"> function changeHREF(){ elements = document.getElementsByClassName("jv-redirectCandidate"); for(i = 0; i<elements.length; i++) { elements[i].href = "https://www.foo.com/something.aspx?p=" + elements[i].getAttribute("key"); } } </script> <body onload="javascript:changeHREF()"> Some Name </body></html> Well, there are other solutions to achieve the same results. But, I think that it is out of topic. Cheers
Here is a complete script that will work in either Tampermonkey or Greasemonkey. It use's jQuery for ease and power: // ==UserScript== // #name _De-javascript links // #include http://YOUR_SERVER.COM/YOUR_PATH/* // #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js // #grant GM_addStyle // ==/UserScript== /*- The #grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ //-- Get links with the class "jv-redirectCandidate". var linksToFix = $("a.jv-redirectCandidate"); //-- Loop through the links linksToFix.each ( function () { var jThis = $(this); //-- An individual link var key = jThis.attr ("key"); jThis.attr ("href", "https://www.foo.com/something.aspx?p=" + key); } );
Write on html on load
I have created a function who tracks on which slide I am currently on and display the result e.g. If I am on slide 2 of 3 it will display 2/3 my problem is that right now it is set to do that every time I click the forward arrow but it displays nothing on page load. $('.forward').click(function() { var current = $('#slider').data('AnythingSlider').currentPage; // returns page # var count = $("#slider").children().length - 2; $("#bottom-image").html(current + "/" + count) ; }); I am trying to find out how to execute this function on page load and where to put it in my code. I am currently learning Javascript through Codecadamedy so I have a basic knowledge of Javascript but I am not enough fluent right now to figure this one out. Here is a link to the current non working code : http://www.soleilcom.com/metacor_dev/our-plants.php
It looks like you are using jQuery. To execute a function on DOM load in query, do this: $(document).ready(function() { /* your code */ }); In your case, that would be: $(document).ready(function() { $('.forward').click(function() { var current = $('#slider').data('AnythingSlider').currentPage; // returns page # var count = $("#slider").children().length - 2; $("#bottom-image").html(current + "/" + count) ; }); }); For things like most event handlers, and most other things, initializing at DOM load is good enough. If your code needs to take account for rendered elements or rendered heights, use $(window).load() instead. (In your case DOM load is fine). Note that this will just establish the click handler at load time. To also run it once, you can do it automatically by either calling the function yourself or triggering a click. To call it yourself, first define another function. The use the function in both the click handler and in one immediate call: $(document).ready(function() { var forward = function() { var current = $('#slider').data('AnythingSlider').currentPage; // returns page # var count = $("#slider").children().length - 2; $("#bottom-image").html(current + "/" + count) ; } $('.forward').click(forward); forward(); }); Or to trigger it yourself, just define the click handler and trigger a click programatically: $(document).ready(function() { $('.forward').click(function() { var current = $('#slider').data('AnythingSlider').currentPage; // returns page # var count = $("#slider").children().length - 2; $("#bottom-image").html(current + "/" + count) ; }).click(); });
It looks like you are using jQuery, so you would use this: $(document).ready(function(){ // Code here }); Or, you can use the shortcut: $(function(){ // Code here }); Read more about this on the jQuery website
If you give the function a name, then you can use it multiple times: $(document).ready(function() { // Bind to click event $('.forward').click(forwardSlide) // Execute function on page load forwardSlide(); }); function forwardSlide() { var current = $('#slider').data('AnythingSlider').currentPage; // returns page # var count = $("#slider").children().length - 2; }; Is this what you're looking for?
Why isn't this chrome / Greasemonkey script executing?
I have the following simple Greasemonkey script: // ==UserScript== // #name MetaCPAN Everywhere // #description Add to every link to CPAN a link to MetaCPAN on a Google results page. // #namespace http://ajct.info // #match http://*/* // #version 0.1 // ==/UserScript== (function() { var page_links = document.links; for (var i=0; i<page_links.length; i++){ if (page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i)) { var match = page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i); var span = document.createElement("span"); span.innerHTML = " MetaCPAN"; page_links[i].parentNode.insertBefore(span, page_links[i].nextSibling); } } })(); If I run the JavaScript snippet through firebug it does the right thing but if I install it and visit the search results page it doesn't seem to execute the script. It's presumably something trivial but can anyone point out what I missed?
The main thing is that Google ajaxes-in just about all of its results, so you need a way to wait for the first batch and to check for later batches. There are numerous techniques. A simple one is to use a timer: //--- This handles both page-load delays, and AJAX changes. var chkInterval = setInterval (checkForResultsLinks, 500); function checkForResultsLinks () { var links = document.querySelectorAll ('#search a'); if (links) { for (var J = links.length - 1; J >= 0; --J) { var link = links[J]; if (link.weHaveProcessed) continue; if (link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i) ) { var match = link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i); var span = document.createElement("span"); span.innerHTML = " MetaCPAN"; link.parentNode.insertBefore (span, link.nextSibling); link.weHaveProcessed = true; } } } } Notes: Google search results appear inside a div with the id, "search". Best add the // #run-at document-end directive to this kind of script. The current script's#match directive is overly broad, the script will fire on every web page! You probably want to restrict it to: // #match http://www.google.com/* // #match http://google.com/* There is no need or point to wrapping the code in an anonymous function, like: (function() { ... })(); .
I found that some scripts although really simple wouldn't run in chrome, however I did find a chrome extension that fully supports greasemonkey scripts, it's called Tampermonkey
Need help debugging greasemonkey script
I'm quite new here, and just as new with GM scripting. With the help of some of the members here, Brock and others, I'm making progress. I currently have the problem of debugging Greasemonkey scripts, but for some reason I'm not getting the hang of it. My first problem, to debug using console.log for firebug. Sometimes I find the logs, most of the times I cant find anything there, guess I'm using it wrongly. Then trying to use alert in order to see variable values... same story. I'm currently trying to get a script going to handle some auctions on the site Trada.net with the great help of Brock Adams, we got more than halfway there, but I'm still hitting my head on JS scripting... quiet a new experience, if u take I was used to turbo pascal 15 + years ago.:) Well, currently this is what I got together on the script: // ==UserScript== // #name bid up to test3 // #include http://www.trada.net/* // #require http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js // ==/UserScript== //--- Create a cell for transmitting the date from page scope to GM scope. $('body'). prepend ('<div id="LatestJSON_Data"></div>'); var J_DataCell = $('#LatestJSON_Data'); //--- Eavesdrop on the page's AJAX calls and paste the data into our special div. unsafeWindow.$('body').ajaxSuccess ( function (event, requestData) { J_DataCell.text (requestData.responseText); } ); // **bid function and var's // **var interval = 50; // **var bidClickTimer = setInterval (function() {BidClick (); }, interval); // **var numBidClicks = 0; // **var A1reset_go = false; // **function BidClick1 () // **{var //bidBtn1=document.getElementById("ctl00_mainContentPlaceholder_AirtimeAuctionItem1_btn_BidButton"); //** numBidClicks++; //** if (numBidClicks > 10) //** { Alert("check10"); //** clearInterval (bidClickTimer); //** bidClickTimer = ""; //** } //** else //** { Alert("check11"); //** bidBtn1.click (1); //** } //**}; //**end bid function //--- Listen for changes to the special div and parse the data. J_DataCell.bind ('DOMSubtreeModified', ParseJSON_Data); function ParseJSON_Data () { //**my var //**var auction_type ;A1_upto;A1_start;A1_current;A1_reset; //**end my var //--- Get the latest data from the special cell and parse it. var myJson = J_DataCell.text (); var jsonObj = $.parseJSON (myJson); //--- The JSON should return a 2-D array, named "d". var BidDataArray = jsonObj.d; //--- Loop over each row in the array. $.each ( BidDataArray, function (rowIndex, rowValue) { //--- Print the 7th column. console.log ('Row: ' + (parseInt (rowIndex) + 1) + ' Column: 7 Value: ' + rowValue[6]); //** my part //** Alert("check1"); //** auction_type=parseInt (rowValue[4]); //** if (auction_type== 1) //** //** {Alert("check2"); //** A1_upto=parseInt (rowValue[12]); //** Alert("check3"); //** A1_current=parseInt (rowValue[8]); //** Alert("check4"); //** A1_reset=rowValue[16]; //** if (A1_reset != "null") //** {Alert("check5"); //** A1reset_go='true'; //** }; //** if (A1_reset == "null") and (A1reset_go=='true') //** {Alert("check6"); //** A1reset_go=false; //** Alert("check7"); //** A1_start=rowValue[8]; //** }; //** if ((A1_current - A1_start) <= (A1_upto - 10)) //** {Alert("check8"); //** BidClick1 (); //** }; //** }; //** end my part }; ); } //--- Format our special cell with CSS. Add "visibility: hidden;" or "display: none;", if desired. GM_addStyle ( (<><![CDATA[ #LatestJSON_Data { background: gold; border: 3px ridge #0000DD; font-size: 10px; margin: 0 2em; padding: 1ex 1em; width: 94%; opacity: 0.8; overflow: hidden; z-index: 666; position: absolute; color: black; } ]]></>).toString () ); Basically, so far, it did create a cell in which it displays all the auction data which was put into an array BidDataArray. I want to use the data in the array, which is updated every second, to get certain pieces of data,and then decide whether or not to click on the bid button. For the first auction I got to a stand still. The timer auctions I got it to work to click every few seconds. On the first auction I basically want to: Check which auction it is, Find out if it is the first bid for auction, Get the bid up to amount, Do calculations to start clicking the last 10 clicks of the auction. Reset the starting amount. Sounds quite simple, but without a debugger and very little knowledge about Js and GM, it is keeping me quite busy. I've tried putting my Var's in console log, but cant track them. might have declared them wrongly, or used them wrongly... but I cant see the mistake, and I don't have an debugger to test them. Will a java debugger work? but it is not linked to the site... Also, the moment I added my parts into Brock's code, it didn't display the cell with the info any more... so somewhere I broke his code I cant find the problem... Before i added anything to his code, it worked well, then i added my parts, it didnt work any more, so i took it out by using "//". so the script should skip it, but his parts dont work anymore. I tried adding "alerts", but cant seem to find the problem. all my parts is marked with "//**" and should be inactive at the moment. Any help will be appreciated. Thanks
Well, I didnt get much response from here, but I've tried...:( I managed to get it debugged 90%, but here is my answer sofar...will update it after i've found a way aroud the minor glitches..: // ==UserScript== // #name let's try 3.42 // #include http://www.trada.net/* // #require http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js // ==/UserScript== var auctiontyp = 0;var aupto = 0;var A1_start = 0;var A1_current = 0;var A1_rest= 'x'; // **bid function and var's var interval = 50; var bidClickTimer = setInterval (function() {BidClick1 (); }, interval); var numBidClicks = 0; var A1reset_go = false; function BidClick1 () {var bidBtn1=document.getElementById("ctl00_mainContentPlaceholder_AirtimeAuctionItem1_btn_BidButton"); numBidClicks++; if (numBidClicks > 3) { alert("check10"); clearInterval (bidClickTimer); bidClickTimer = ""; } else { alert('check11'); //bidBtn1.click (1); } }; // end bid function var myJson = '{"d":[["","","y","ZAR","1","49517","6458, 8270, 8270, 8270, 7635",null,"1.40","6458","0:13:30","","12","","C","30",null],["y","-00:00","y","ZAR","2","49593","6458, 6458, 6458, 6458, 6458",null,"2.92","6458","0:13:37","","12","","L","12","Ve4mYdrvkkQMKxBH1\/1VMtDTCDQBRspg5jB8jjY08zg="],["","","y","ZAR","3","49058","7456, 9216, 6458, 5153, 7456",null,"194.40","7456","0:00:31","","1100","","T",null,null],["","","y","ZAR","4","49597","2935, 6554",null,"1.22","2935","0:01:16","","12","","T",null,null],["","","y","ZAR","5","49590","4440, 0518, 5343, 2625, 4848",null,"0.95","4440","0:15:58","","5","","L",null,null],["","","y","ZAR","6","49591","4848, 4440, 4440, 0518, 2625",null,"1.81","4848","0:16:05","","12","","L",null,null],["","","y","ZAR","7","49595","6458",null,"5.55","6458","0:04:13","","55","","T",null,null],["","","y","ZAR","8","49596","",null,"2.90","NONE","0:04:35","","29","","T",null,null],["","","y","ZAR","9","49496","6458, 2427, 2427, 7863, 5845",null,"2.56","6458","0:06:07","","10","","B",null,null],["","","y","ZAR","10","49524","6458, 2427, 7863, 7863, 5845",null,"1.67","6458","0:06:00","","5","","B",null,null],["","","y","ZAR","11","49539","6458, 2427, 7863, 7863, 0764",null,"2.02","6458","0:04:25","","10","","B",null,null]]}' var jsonObj = $.parseJSON (myJson); //--- The JSON should return a 2-D array, named "d". var arrayOfAuctions = jsonObj.d; //--- Loop over each row in the array. $.each ( arrayOfAuctions, function (rowIndex, singleAuctionData) { //--- Print the 7th column. console.log ('Row: ' + (parseInt (rowIndex) + 1) + ' Column: 7 Value: ' + singleAuctionData[6]); alert('test3.41'); auctiontyp=parseInt (singleAuctionData[4]); if (auctiontyp== 1) { aupto=parseInt (singleAuctionData[15]);alert('check2.6'); alert('check3 '+(singleAuctionData[8])); A1_current=parseFloat (singleAuctionData[8]); alert('check4 '+(singleAuctionData[16])); A1_rest=singleAuctionData[16]; alert(A1_rest); if (A1_rest != 'null') {alert('check5'); A1reset_go=true; }; alert('check5.1'); alert(A1reset_go); if (A1_rest == 'null') and (A1reset_go==true) {alert('check6'); A1reset_go=false; alert('check7'); A1_start=singleAuctionData[8]; }; alert('check7.3'); alert((A1_current) ); alert(( A1_start)); alert((aupto) ); if (((A1_current - A1_start)*100) < (aupto - 10)) {alert('check8'); //BidClick1 (); }; }; } ); My current problems on this script: 1.The "BidClick1" function runs in the beginning of the script without being called, i only call it close to the end, but then it is not running.. 2.This part: A1_rest=singleAuctionData[16]; alert(A1_rest); if (A1_rest != 'null') {alert('check5'); A1reset_go=true; }; alert('check5.1'); alert(A1reset_go); if (A1_rest == 'null') and (A1reset_go==true) {alert('check6'); A1reset_go=false; alert('check7'); A1_start=singleAuctionData[8]; }; is not executing correctly., for this array,"arrayOfAuctions", on the first segmant, that im doing all the tests on, "A1_rest" should be = to "null", but it's not, thus it executes:" if (A1_rest != 'null') {alert('check5'); A1reset_go=true; };" and also, it doesnt execute this statement : " if (A1_rest == 'null') and (A1reset_go==true) {alert('check6'); A1reset_go=false; correctly, it should only execute if A1_rest="null" AND A1_reset_go is true. It executes no matter which one is true,and if i put it as:if ((A1_rest == 'null') and (A1reset_go==true)) ,it doesnt run the script at all. If any1 got an complete answer, i will mark it as such. Thanks. alert('check7'); A1_start=singleAuctionData[8]; };" executes always