I'd like to define my own onblur event for all text boxes in an application so that I can strip all high ascii values, so I wrote a script that runs on an asp.net master page that runs per page load, overriding all text box / area onblur events, and storing a copy of the old event.
The new event then called the old event so it wouldn't break existing events across the forms.
It worked fine until a page defined an onblur like: onblur="func(this)"
When the original event fires the 'this' point doesn't seem to point to the sender control any longer.
Pastebin link with 2 simple examples
So would anyone be able to point me towards a better way to accomplish this?
Thanks!
To call a function dynamically while controlling the value of this, use func.apply instead of a standard call. For example instead of
myStoredFunc(arg1, arg2)
use :
myStoredFunc.apply(this, arguments);
This way the value of the this variable will be correctly passed to the called function, thanks to apply's first argument. The second argument allows you to specify the parameter values (here I pass all the current function's arguments to the called function).
Related
On a portion of a web page, user options are provided though sets of radio buttons, check boxes, and input elements, and a change-event listener is placed on the parent containing all of the options.
The change-event handler builds an object of information necessary to undo/redo the option selections, pushes the most recent change to RAM as a function property, writes it to indexedDB, and, in the transaction oncomplete handler of the write request, logs a description of the change to an area of the document for the user to see, based on the data written to RAM as the property of a function.
If the user edits the value in an input element and, while it still has the focus, clicks a radio button, two change events fire, each invoking the same handler function of the parent's event listener.
The data written to RAM and indexedDB is recorded accurately, but if the user performs the click rapidly, the second change event updates the function property again before the first change event's write transaction completes, such that when the first event's log description is built from the most recent selection held in that function property, it uses the second event's data, resulting in two loggings to the DOM of the second event's selections.
To prevent this from occurring, an independent copy of the option-selection object is assigned to a variable declared locally in the change-event handler function, immediately after it has been built. It seems to be working, for I cannot reproduce what was taking place before no matter how quickly I attempt to click a radio button while an input element with an edit retains the focus.
My question is, does making the copy of the undo object guarantee that the oncomplete handler will always refer to that local function variable to build the log, even if a second change event updates the function property from which it was copied, and makes a new copy, before the oncomplete event fires? Is that local function's variable value "locked" in the function scope, such that the second invocation of it cannot alter what the oncomplete event of the first invocation uses to build the log?
Thank you.
After reading the answer from #Bergi, his use of "shared object" makes something clear to me, for my terminology was poor.
Since the shared object is an array of objects, where each object is data required for undo/redo, each change event needs to modify the shared object so the data is there for potential undo/redo. The issue is not that the second event is adding to the array while the first event's database write completes and before it references the last element in the array to build a log item. The issue is that the log item is always referencing the last object in the array. The undo object doesn't need to be cloned (for it's in RAM as a function property); instead, the array index needs stored in a local variable for reference to build the log from either the last element or the next-to-last element, when two change events take place in rapid succession.
Yes. Every function invocation creates its own local variables, and no code outside of its scope can access them. In your scenario, you also have to take care of not modifying shared objects but cloning them.
As there is (according to my research) no way to catch user input with selenium, I am trying to use a JavaScript event listener.
But when I add the event listener by executing the JavaScript code, the function is automatically triggered without me (as the user) doing anything. Furthermore, there is no way to trigger the function again.
Does anyone know what the problem might be and how I could solve it?
FYI: My code is in Python 3.8
Thank you in advance,
Raphael
# this is a self defined function that creates a new selenium WebDriver
browser = gf.create_browser(headless=False)
browser.get("https://www.google.com")
browser.execute_script('document.getElementById("hplogo").addEventListener("mouseover",console.log("Success"))')
time.sleep(90)
The console displays "success" as soon as the script is executed, afterwards the event is never triggered again. I have tried different events (click, mouseover,...), different functions and different websites with different elemtents.
You're not passing a function – you're actually just directly calling it
console.log("Success")
This ^ calls the function. The actually parameter you end up passing is the result of console.log, not the function itself (which if I remember is just an undefined). If you want to actually pass a function, you should make something like this.
() => console.log("Success")
For pre ES6 supported browsers, you can use:
function(){console.log("Success")}
The code is entirely a infinite loop because of which it is triggering only once and then after it is not triggering.
It is suggested to edit your code as
addEventListener("mouseover",{console.log("Success")})
I don't even know where to begin. I'm using Kendo Grid to list data sourced from a server. Everything is fine on first load including when I add additional functions and dom elements in the dataBound function. Calls to the server seemingly update (sync) the Grid just fine. BUT, it seems the dataBound function is called an additional time the second time round. Performing an on click function coded in the dataBound performs it a total of 4 times. How do I test for where the issue is and what do I need to destroy to stop this infuriating behaviour?
I don't even know what code to give you save for pasting in my whole website. What is the underlying theory behind this behaviour because there's obviously something I am fundamentally missing about how javascript, and therefore Kondo, works? How do I test for this, please. Thanks!
A quick solution might be to use off() then on() in the databound e.g.
$(".cell").off("click").on("click", function(e){ ... });
this will get rid of previously attached handlers and ensure you only have one.
Even better, use event delegation outside of the Grid generating code.
$(document).on("click", ".cell", function(e) { ... });
With event delegation, the target of the event does not have to exist at the time the event handler is setup. In the example above, the click is on the document object which already exists, but the handler will only fire if an element with the class 'cell' is actually clicked. You can define this handler once in the document.ready before the grid is even created.
Snap.svg is a js library to process SVG in DOM. It has a method unclickand a number of similarly named methods. Their purpose is to unbind event handlers. According to docs they all have callback parameters. What purpose do these parameters serve? Is executing these methods without parameters not enough?
Elements can have more than one click handler. You need to pass in the original click handler so it know which one to remove.
I have a weird one here. I am working on a JSF2 (Java) based system using Primefaces component library (not sure its relevancy), and I have a number of buttons that execute a JavaScript function called checkParams() on a onclick event. I need to edit this function to reivew its code and adapt it to some newly added components but I cannot for the life of me actually find the JavaScript function. I am working in NetBeans & I have performed a project search for this function and the only search results returned are the button references to this component. Similarly I have done a search for the function in Google Chrome's developer console, which again only returned the button references. I have also tried creating a quick dirty function that calls an alert(checkParams()); on the body load, but Chromes console tells me the function is undefined.
However the buttons work perfectly, checking various input boxes and submitting the information to the backing Java files...
Does anyone have any idea where this function may be hiding or how I can locate it?
It might be contained in a JavaScript Closure in a script file that is executed and then removed from the DOM. It would be a neat trick to 'hide' it a little bit. But, that is only if the checkParams() in the onclick is not in the onclick attribute. It would have to be assigned in JavaScript.
If this is the case, you would want to see what scripts are loaded initially, and look through those. Also, this is a lot of effort to hide a function for your own site unless you're trying to make sure people don't see how you are validating your parameters. There are ways to obfuscate it to assign the function without having it defined by name directly in the file, but, again, that is a lot of effort.
Outside of the above, I'm not sure there is a lot I can say for finding it. But I'm not sure that this is actually the case. One thing to note is that alert(checkParams()) will alert the return value, which means the function could be defined. Try running alert ( typeof ( checkParams ) ) instead. If that is undefined, than your function doesn't exist. If its not, you can also do console.log(checkParams) which should output the toString() of the function, which will often show you the code.