Reputation: 695
I am trying to fetch data from file using ajax on mouseover. Everything works fine, except when I try to access a <p>
element inside an anonymous function, I get nothing. Possible reason is that the element lost scope inside anonymous function. Please advise if you see a possible solution.
<html>
<head>
<title>MouseOver Effect And Ajax </title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript" src="http://localhost/study/libraries/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var xhr=false;
initAll();
$('div.pcard').mouseover(function(){
if(xhr)
{
var pname=$(this).children('p.pname').text();
var pname=pname+"_details.txt";
xhr.open("GET",pname);;
xhr.onreadystatechange=function(){
if(xhr.readyState==4)
{
if(xhr.status==200)
{
$(this).children('p.pdesc').text(""+msg);
alert($(this).children('p.pname').text());
$(this).children('p.pdesc').css({'visibility':'visible'});
}
}
}.bind(this);
xhr.send(null);
}
});
$('div.pcard').mouseout(function(){
$(this).children('p.pdesc').css({'visibility':'hidden'});
});
function initAll()
{
if(window.XMLHttpRequest)
{
xhr=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
try{
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
});
</script>
</head>
<body>
<h2>Interactive MouseOver</h2>
<div id="products">
<div class="pcard">
<p class="pname">Sandwhiches</p>
<p class="pdesc"></p>
</div>
<div class="pcard">
<p class="pname">Pizzas</p>
<p class="pdesc"></p>
</div>
<div class="pcard">
<p class="pname">Soups</p>
<p class="pdesc"></p>
</div>
<p style="clear:both"></p>
</div>
</body>
</html>
Upvotes: 0
Views: 916
Reputation: 50905
Us commenters have concluded that sharing one XMLHttpRequest
is not a good idea and you would probably want to fire off a new one for every mouseover
event occurring. Things can get messy when you call open
on an already opened/uncompleted request, while send
should be okay. What is normally done is something like this:
$(document).ready(function () {
$('div.pcard').mouseover(function () {
var self = $(this);
var pname = self.children('p.pname').text();
var pname = pname + "_details.txt";
var xhr = ajaxFunction();
xhr.open("GET", pname);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var msg = "" + xhr.responseText;
self.children('p.pdesc').text(""+msg);
//alert(self.children('p.pname').text());
self.children('p.pdesc').css({'visibility':'visible'});
}
}
};
xhr.send(null);
});
$('div.pcard').mouseout(function(){
$(this).children('p.pdesc').css({'visibility':'hidden'});
});
});
function ajaxFunction() {
var ajaxRequest; // The variable that makes Ajax possible!
try {
// Firefox, Chrome, Opera 8.0+, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP.6.0");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP.3.0");
} catch (e) {
throw new Error("This browser does not support XMLHttpRequest.");
}
}
}
}
}
return ajaxRequest;
}
In the ajaxFunction
, I'm not sure if you really have to go past the first 2 ActiveXObject attempts, that's just something I've seen...and there's several more you can "try" for. There were a few other things that were weird in your original code (that was edited by others without looking) - you commented out the line that set the msg
variable, and then you tried to use it on the next line. The .bind
probably works, but I like the way I provided...that's up to you...try both and see if either one works separately.
But as the other answer already points out, if you're already using jQuery, why not use $.ajax
?
Upvotes: 1
Reputation: 43820
You have jquery, why are you rewriting your own ajax call?
Save the this into a local variable : var that = this
then you can reuse it.
$(document).ready(function(){
$('div.pcard').mouseover(function(){
var pname=$(this).children('p.pname').text();
pname=pname+"_details.txt";
var that = this; /// keeping the scope
$.ajax({
url:pname,
success: function () {
$(that).children('p.pdesc').text(""+msg);
alert($(that).children('p.pname').text());
$(that).children('p.pdesc').css({'visibility':'visible'});
}
});
});
Upvotes: 0