0

I'm trying to setup an event handler for all occurrences of a certain HTML tag, for example onclick()=my_f() event in tag <p> in HTML file like this :

<body>
<p id="1"></p>
<p id="2"></p>
<p id="3"></p>
</body>

the result would be that my_f() is the handler for all <p> .
the catch is that I don't want to write : <p id="1" onclick()="my_f()"> for every <p>, so I tried doing so in JavaScript, like this:
JSutil.js:

window.onload = function() {
   init();
   alert("Hello!");
}
 
function init() {

    for (var i = document.getElementsByTagName("P").length - 1; i >= 0; i--) {
        alert("i "+i);
        document.getElementsByTagName("P")[i].addEventListener("mouseover", readenter(document.getElementsByTagName("p")[i].id));
        document.getElementsByTagName("P")[i].addEventListener("onmouseout", readleave(document.getElementsByTagName("p")[i].id));
    };
}

function readenter(id) {
    alert("readenter , id "+id);
}
function readleave(id) {
    alert("readleave , id "+id);
}

and in the HTML file I did :

<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<script type="text/javascript" src="JSutil.js"></script>
</head>

The problem is that the readenter() and readleave() gets called at the start of the page (onload), and when I move in/out over the paragraphs (<P>) nothing happens.
The ids that are printed in alert (in readenter() and readleave()) are correct and belongs to the <p> in my HTML. I tried also doing:

document.getElementsByTagName("P")[i].onmouseover = readenter(document.getElementsByTagName("p")[i].id);

same result. What is the problem?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Epsilon
  • 73
  • 2
  • 12

2 Answers2

3

Because you called the function, instead of binding the event to it. Instead of

  document.getElementsByTagName("P")[i].addEventListener("mouseover", 
      readenter(document.getElementsByTagName("p")[i].id));

Write

  document.getElementsByTagName("P")[i].addEventListener("mouseover", readenter);

And "readenter" will be called.

However your code is very verbose for lack of a better term, and it may break down in certain browsers. Try using jQuery for example. Using jQuery you would write:

$("p").mouseover(readenter).mouseleave(readleave)
Jodi Supporter
  • 330
  • 1
  • 7
1

You just need to attach function while adding eventlistener and not call it. So changes to be done in for-loop is as below:

for (var i = document.getElementsByTagName("P").length - 1; i >= 0; i--) {
        alert("i "+i);
        document.getElementsByTagName("P")[i].addEventListener("mouseover", readenter);
        document.getElementsByTagName("P")[i].addEventListener("onmouseout", readleave);
};

Or if at all you want to pass a parameter then create an anonymous function while adding eventlistener as below:

for (var i = document.getElementsByTagName("P").length - 1; i >= 0; i--) {
        alert("i "+i);
        document.getElementsByTagName("P")[i].addEventListener("mouseover", 
           function(){
               readenter(document.getElementsByTagName("p")[i].id)
           }
        );

        document.getElementsByTagName("P")[i].addEventListener("onmouseout",
            function(){
               readleave(document.getElementsByTagName("p")[i].id);
            }
        )
};

You can find still more good solutions from this Post

Community
  • 1
  • 1
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200