admin管理员组文章数量:1277876
I've got a small drag and drop set up up and running, but it's using inline javascript and I'd prefer to move it all to an external file. Theoretically it's an easy swap, but I'm getting referenceErrors in my inspector and my minifcation is failing.
From what I can tell, the issue is ing from the return
.
Original HTML
<section id="titles" ondrop="dropClip(this, event)" ondragenter="return false" ondragover="return false"></section>
Desired HTML
<section id="titles"></section>
JavaScript
var titles = document.getElementById('titles');
titles
.addEventListener('drop', dropClip(this, event))
.addEventListener('dragenter', return false)
.addEventListener('dragover', return false);
I've got a small drag and drop set up up and running, but it's using inline javascript and I'd prefer to move it all to an external file. Theoretically it's an easy swap, but I'm getting referenceErrors in my inspector and my minifcation is failing.
From what I can tell, the issue is ing from the return
.
Original HTML
<section id="titles" ondrop="dropClip(this, event)" ondragenter="return false" ondragover="return false"></section>
Desired HTML
<section id="titles"></section>
JavaScript
var titles = document.getElementById('titles');
titles
.addEventListener('drop', dropClip(this, event))
.addEventListener('dragenter', return false)
.addEventListener('dragover', return false);
Share
Improve this question
asked Apr 1, 2013 at 22:39
technopeasanttechnopeasant
7,96933 gold badges93 silver badges151 bronze badges
3
-
If I had to guess, I'd say your external script is being loaded in your page header and is being run before
titles
is created. You can move the loading of the script to the footer (this will also make your page seem to load faster) or run the script in anonload
handler. – Jerry Commented Apr 1, 2013 at 22:44 - @JerrySeeger script is on the bottom of the page and all JS is being executed on document ready – technopeasant Commented Apr 1, 2013 at 22:45
-
two things. (1) you don't call functions in
addEventListener
, you specify them instead using only function name. (2)return false
isn't a function. you'd likefunction(){return false;}
there inaddEventListener
. – Ejaz Commented Apr 1, 2013 at 22:47
2 Answers
Reset to default 11Javascript is a language where functions are "first-class objects". This means, possibly contrary to other programming languages that you may have experience in, that you can treat a function like any other object: you can pass it around, you can return it, you can have a function with a function inside it with a function inside it, and so on.
The consequence of this may be a very unexpected programming style required to be successful in Javascript. In other languages, UI event binding occurs in a variety of ways (such as C#'s Button1.Click += new System.EventHandler(this.myEventHandler);
, or Classic VB's Button_Click()
). In C#, you can pass around delegates, which are special objects with a specifically defined set of parameters and return values, to which a function can be bound. But all that disappears in javascript because you can simply attach a function to a property directly. For browser DOM event handling, the property is assumed to be a function reference, and during the native event handling code for that event, it calls the function attached to the property with the same name as the event.
Okay, you say, we have functions. And we can pass them around and treat them just like variables. Now what?
First, please take special note that the following two functions declarations are identical. They yield the exact same result, of declaring a function named myfun
in the current scope (in a browser, the window
object or the current function that is running).
function myfun(param1, param2) {
//do some stuff
};
var myfun = function (param1, param2) {
//do some stuff
};
(Actually, the first one will end up with a name
property that the second one won't, and possibly some other minor differences, but for all practical intents and purposes they are identical).
The first one is just a shortcut for the second one. Basically, you create a function (that may or may not have a name) and assign it to a variable. Programmers use the convenient shortcut of calling the result "the myfun
function", but in reality the case is "the myfun
variable--which contains a particular function right now".
You can get many references to the same function--which is a true object--just by assigning it to other variables:
function myfun(param1, param2) {
//do some stuff
};
var a = myfun, b = myfun, c = myfun;
a(); // runs `myfun`
b(); // runs `myfun`
c(); // runs `myfun`
The next thing to notice is that to invoke a function, you must use parentheses after its name, and any parameters go inside the parentheses.
var result = myfun('a', 1); // invoke the `myfun` function
// and store its return value in variable `result`
But take a look back at our assignment statement making a
, b
, and c
all be aliases of the myfun
function: in those cases we didn't use parentheses, because--and here is where it gets really important, so pay attention:
To invoke a function (and get the function's return value), use parentheses after its name.
To pass a function reference, do not use parentheses.
What if we had done this instead:
var a = myfun(), b = myfun(), c = myfun();
a
, b
, and c
would no longer be pointers to the myfun
function. They would all be the result of myfun
and would contain whatever myfun
returned--or undefined
if it didn't return anything. If you tried to invoke one of these, say a()
you would get some error similar to:
> TypeError: a is not a function
Now that I've painted all that background, there is one simple thing to know that will get you on track to being successful with addEventListener
: it expects a function as the second parameter. In your example code, you've put the contents of functions you'd like to run when addEventListener calls them, but no actual functions.
You can solve that by actually declaring the functions first, such as:
function doNothing() {
return false;
}
titles.addEventListener('dragenter', doNothing);
// Note: this is not invocation like `doNothing()`, but passing a reference
Or, you can simply wrap your function statements into an anonymous function. Remember, functions in javascript don't actually have names, we just have variables that contain functions. An anonymous function is one that has no name at all, and it is invoked either by an implicit name assignment (such as being passed as a parameter--where it will have the parameter's name) or by being directly invoked by doing the magic invocation action of putting parentheses after it.
That would look something like this:
titles.addEventListener('dragenter', function () { // anonymous function
return false;
});
If you want to invoke an anonymous function, you do have to let javascript know you want to treat it like a value as opposed to the normal shortcut-method of creating a named function in the current scope (where function myfun
is treated like var myfun = function
). That is done by wrapping the entire thing in one more set of parentheses, like this:
(function () { // begin a function value containing an anonymous function
// do something
}()); //invoke it, and close the function value
I hope this helps you understand more about javascript, why your code was not working, and what you need to do to make it work.
For sure you have to wrap the function contents you give to addEventListener into a function.
For instance instead of .addEventListener('drop', dropClip(this, event))
you will write .addEventListener('drop', function(event) { dropClip(this, event); })
本文标签: Adding multiple event listeners in javascript to elementStack Overflow
版权声明:本文标题:Adding multiple event listeners in javascript to element - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741284828a2370210.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论