I have following code in my JavaScript library. My goal is to store the original onscroll function which is the first line of code snippet, and then point onscroll to a new function. However, what I am finding is that wind.origonscroll which is supposed to be the original scroll function is always pointing to the new function in second line.
Question: Is there a way to store the original function in code below, so window.origscroll always points to the function in first line of commented code? I am trying to keep track of what was the original window's onscroll event, which is not related to overriding a function. I do not need to override a function here.
//window.onscroll = function() {console.log('scrolling done');}
wind.origonscroll = window.onscroll;
window.onscroll = function () { window.scrollTo(wind.x, wind.y); };
If window.onscroll is not null ( if has been defined before) it can be saved away.
Try this:
window.onscroll=function() { console.log('asd') }
var old = window.onscroll
window.onscroll=function() { console.log('gggg') }
old()
Related
Using google apps script I'm having trouble running a js function which passes parameters. When I add the parameters it will always run the code when the page loads instead of when the button is clicked.
Direct from the HtmlService example, it is OK - it runs when the button is pressed...
document.getElementById('button1').onclick = doSomething;
But when I add a parameter to the call (and function) as below, it runs just once when the page loads (and not when the button is pressed)...
document.getElementById('button1').onclick = doSomething('with_this_parameter');
Any insight into this behaviour would be greatly appreciated... sorry if the answer is obvious!
When you say
document.getElementById('button1').onclick = doSomething('with_this_parameter');
This means call doSomething('with_this_parameter') and then assign the returned value to document.getElementById('button1').onclick. Hence that is why it gets called when code reaches that line. Whether the value is assignable to that property or not is another question, but that is why it gets called.
Use it like this
document.getElementById('button1').onclick = function(){
doSomething('with_this_parameter');
}
Reference: This solution was given by Mark Linus.
Do like this:
document.getElementById('button1').onclick = function(){
doSomething('with_this_parameter');
}
To assign a reference of function to some variable, you do:
var a = doSomething;
where doSomething is a function.
But when you have to pass parameters and assign that function
var a = doSomething(b);
this will cause trouble as while assigning the function to the variable, it gets called and not when it is intended to be called.
To overcome this, you can use arrow functions or simple function to call your own function with params.
var c = () => doSomething(d);
This actually is understood as var c = anonymous_function;
or
var c = function() {
doSomething(d);
}
Hence you can do:
document.getElementById('button1').onclick = () => doSomething('with_this_parameter');
I usually do clickHandlers like so:
// create button here or get button...
var button1 = document.getElementById('button1').setName('button1');
var clickHandler = app.createServerClickHandler('doSomething');
button.addClickHandler(clickHandler);
function doSomething(e){
var button1 = e.parameter.button1;
<do something with var button>
}
I'm not sure what parameter you are adding, but you need to add a callback element to pass it if it isn't passed by the button itself via a .setId/getId or .setTag/getTag. If it is from a textbox:
var textbox = app.createTextBox();
var button1 =
app.createButton.setName('button1');
var clickHandler =
app.createServerClickHandler('doSomething').addCallbackElement(textBox);
button1.addClickHandler(clickHandler);
Hope this helps!
In the code below, initializeBoard has access to the property, and the console returns 'white' when I start the script. But when I click inside the window, I get 'undefined'. What obvious thing am I missing? (Bonus: what's the search query that'd have led me to the answer without having to ask?)
var view = {
currentMove: 'white',
initializeBoard: function() {
console.log(this.currentMove);
},
click: function(e) {
console.log(this.currentMove);
}
}
window.onload = function() {
view.initializeBoard();
document.onclick = view.click;
}
The value of this is determined by how the function is called, not by where it is first assigned.
You are copying the (reference to the) function to document.onclick.
When the click event happens document.onclick is called. view.click is not called (even though it has the same value as document.onclick). This means that this is document not view.
Use bind if you want to create a wrapper function that calls the original function in the right context.
document.onclick = view.click.bind(view);
Trickshot #29 shows how to define touch events in jQuery. I've reworked it to my style of rogue writing in this fiddle.
What the author does is define a touchmove listener whenever a touchstart event is fired.
request.dom.ball.on('mousedown touchstart',myTouchStart);
function myTouchStart(myEvent){
request.dom.ball.on('mousemove.myNameSpace touchmove.myNameSpace',myTouchMove);
function myTouchMove(myEvent) {
What I'd like to do is put myTouchMove outside of myTouchStart because my rogue style of JavaScript writing is to try to keep it as flat as possible, and not have functions inside of functions, if I can help it.
That might seem strange since I already wrap everything inside of:
(function() {
})();
to begin with, but I really don't want to have functions inside of functions inside of functions if I can help it.
One way to do this is to return the inner function from another function (called a closure) that will pass any variables that you were originally referencing to your original function.
As far as I can tell in your case that's only one variable - local - but if you ever add new variables, just add a new argument to the function definition and the function call.
Updated fiddle: http://jsfiddle.net/ynUHb/1/
The affected code:
request.dom.ball.on('mousedown touchstart',myTouchStart);
function myTouchStart(myEvent){
var local = {};
//...
request.dom.ball.on('mousemove.myNameSpace touchmove.myNameSpace',myTouchMove(local));
//...
};
function myTouchMove(local) {
return function(myEvent) {
var myCss = {};
myEvent = (myEvent.originalEvent.touches) ? myEvent.originalEvent.touches[0] : myEvent;
myCss.top = local.elementPosition.y + myEvent.pageY - local.startPosition.y;
request.dom.top.text(myCss.top);
myCss.left = local.elementPosition.x + myEvent.pageX - local.startPosition.x;
request.dom.left.text(myCss.left);
request.dom.ball.css(myCss);
};
};
See:
Forming Closures
Quite an interesting thing was discovered by me as a JS learner, consider the following code.
this.init = function (e) {
var container = e.container;
// slider
var slider = $("#div1").slider({ orientation: "horizontal", step: 1,
slide: function () {
console.log(e.container); // not null
console.log(container); // null
}
});
};
here's how it's called:
lib.init({ container: $("#container") });
I know that I can use on("slide", {container: container}, function(event, args){...})) to bind slide event and pass external data into it. But - could anyone explain why values returned by two console.log are different? Also I wonder if the technique is a technically sound replacement for on approach?
First of all, I am amazed that you are getting a null for container. Would actually want to see your logs if you can post
Secondly, here's an explanation of why this won't work, but not of why you get a null:
This has nothing to do with hoisting
you are executing the init function with lib.init({ container: $("#container") });
At that time attached function this.init = function (e) { ... gets executed with some value of e, may be an Event, so e is defined and the variable container gets a value
Whereas, in the following code on 5th line,
var slider = $("#div1").slider( ... // u are calling slider
the slider function is being called with options, and one of the options is:
slide: function () { // anonymous and will execute later
console.log(e.container); // not null
console.log(container); // null
}
most important, you are in the scope of slider function of your library, as it is being executed
here, the function you are attaching to slide: ... has not been executed yet. It will, when slide event happens
when that happens, the present value of container will be used
If you are getting a null, something definitely is resetting container, as in the fiddle here by yckart its not null and is same as e.container
Can't see a difference... For me are both logs equal: http://fiddle.jshell.net/WJ2s8/
I have replicated a toggle functionality from this site:
http://www.williamsprofessionalpainting.com/FAQ.php
Here is the updated version which renders the basic toggle function with minimum CSS:
http://jsfiddle.net/NinjaSk8ter/yXNmx/
Your code is working fine, but jsFiddle is wrapping it in a function. In other words, it ends up looking something like:
window.onload = function() {
function ToggleFAQ(Ans) {
...
}
};
The function is defined within the onload handler, so when your onclick tries to call it, it doesn't exist.
If you change the drop-down on the top-left of your fiddle to "no wrap", it all works fine. See this modified version.
On your JSFiddle - if you change the wrap method to "no wrap(head)" and it simply works.
Alternatively - you can declare the function as a global var:
ToggleFAQ = function (Ans)
{
//..
}
what renders as
jQuery(document).ready(function(){
//when defined like this - ToggleFAQ will still be visible when the
//"ready" event finishes.
ToggleFAQ = function (Ans)
{
//..
}
}
the wrap you selected puts your code in a function passed to jQuery's "dom-ready" event - and that's a closure that once is executed - all local variables are "vaporized".