Issue Using JavaScript's onmouseover Event Within a Class - javascript

Earlier today I got some simple code to work allowing an image to slide over on mouse over, and decided to try to turn that into a class so I could instantiate it. However, I'm running into some problems.
init() is called on window load, which sets up shifttabout() as a function to be called upon mousing over the image. However, when shifttabout() is called, I get the following error: "this.movetabout is not a function." How can this be?
<script type="text/javascript">
function SlidingTab(img)
{
this.self = this;
this.outtimer;
this.intimer;
this.left = 0;
this.interval = 20;
this.animatingout = false;
this.animatingin = false;
this.increment = 10;
this.extenddist = 100;
this.imgobj = img;
this.movetabout = function(){
alert("moveout");
this.animatingout = true;
this.left = parseInt(this.imgobj.style.left);
if(this.left != this.extenddist)
{
this.imgobj.style.left = this.left + this.increment + 'px';
this.self = this;
this.outtimer = setTimeout(this.self.movetabout, this.interval);
}
else
{
this.animatingout = false;
}
};
this.shifttabout = function(){
alert("shiftout");
if(this.animatingin)
{
this.animatingin = false;
clearTimeout(this.intimer);
}
if(!this.animatingout)
{
this.movetabout();
}
}
this.init = function(){
this.imgobj.style.position = 'relative';
this.imgobj.style.left = '0px';
this.self = this;
this.imgobj.onmouseover=this.self.shifttabout;
}
}
function init(){
var img1 = document.getElementById("tab1");
var tab1 = new SlidingTab(img1);
tab1.init();
}
window.onload = init;
</script>
Presumably I am setting up the onmouseover function incorrectly somehow, since all class variables appear to be undefined or otherwise messed up in shifttabout() when it is called by mouse hover, but not when it is called directly via init().

your problem looks to be caused by these lines. Youre on the right track, in that you need to be properly setting the context of your function.
this.self = this;
this.imgobj.onmouseover=this.self.shifttabout;
change it to the following should properly set the context
this.imgobj.onmouseover=this.shifttabout.bind(this);
#bind(this) sets the scope of this inside the function to the input you pass it (in this case its the current scope)

The this you're using in the shifttabout refers to the shifttabout this - not the SlidingTab this.
You should pass the vars needed from outside shifttabout into it to use them properly.
Hope that helps.

Related

Replacing global variables with anonymous functions Joomla

I have these imagemap and function on it: http://jsfiddle.net/emedrs9n/3/
What happens is if clicked on the speechbubble, the src is new defined.
That leaves me with a problem: The imagemap does not work on the new src anymore. To solve this I added this peace of code. It basically redifines the functions, if clicked on the speechbubble.
//JS FUNCTION FOR CLICK
function bocadillaC() {
original = bocadillaC;
//REDIFINE THE OTHER FUNCTIONS
cuentaH = leftH = function() {
document.getElementById('garfio').src = boca_iz.src;
};
cuentaH = rightH = function() {
document.getElementById('garfio').src = boca_de.src;
};
cuentaH = garfio1H = function() {
document.getElementById('garfio').src = garfio1C.src;
};
cuentaH = garfio2H = function() {
document.getElementById('garfio').src = garfio2C.src;
};
cuentaH = garfio3H = function() {
document.getElementById('garfio').src = garfio3C.src;
};
cuentaH = garfio4H = function() {
document.getElementById('garfio').src = garfio4C.src;
};
document.getElementById('garfio').src = cuentaBoca.src;
}
On my computer, locally it works. But, uploading it to Joomla wont work (having trouble to get in JSFiddle to run as well). Here the link to the page http://fonag.org.ec/inicio/link4. What happens is: when clicked on the speechbubble and hoverd over the hooks, a white image appears. All the other active areas work...
Any ideas what is causing the problem in Joomla?

Cannot detect if window is loaded

I'm currently working on counting the number of opened tabs on my application. but my problem is it seems that my script won't detect events onload. Here is my code.
I'm using HTML5 web storage and native js. I'm not using jQuery to understand more on native js.
(function(w) {
function Tabz(win, key) {
this.name = '';
this.storageKey = key;
if(win.name != '')
this.name = win.name;
else {
var windowArr = JSON.parse(localStorage.getItem(key)) || [];
this.name = "tabz_"+ windowArr.length;
win.name = this.name;
windowArr.push(this.name);
localStorage.setItem(this.storageKey, JSON.stringify(windowArr) );
}
}
Tabz.prototype.getStorage = function() {
return localStorage.getItem(this.storageKey);
}
Tabz.prototype.removeWindow = function() {
//remove window function here
}
var newWindow = new Tabz(w, 'counter');
window.load = function() {
var count = JSON.parse(newWindow.getStorage()).length;
alert(count!); // this wont execute so that I can check the count.
}
})(window);
Your issue is on this line:
window.load = function() {
This will add a load property to the window, not add an event listener. I think you are looking for onload.
window.onload = function() {
Incidentally, using event properties is considered bad-practice. Using addEventListener would be better.
window.addEventListener("load", function(){
//Do stuff...
});

How to prevent first onclick execution

I'm writing a javascript function that dynamically creates an Iframe with a button that if pressed can delete its iframe.
These are my javascript functions:
function createIframe (iframeName, width, height) {
var iframe;
if (document.createElement && (iframe = document.createElement('iframe'))) {
iframe.name = iframe.id = iframeName;
iframe.width = width;
iframe.height = height;
var connectIP = document.getElementById("ip").value;
var connectPORT = document.getElementById("port").value;
iframe.src = "http://"+connectIP+":"+connectPORT;
document.body.appendChild(iframe);
addElement(iframe.name);
}
return iframe;
}
function removeIframe(iframeName) {
iframe = document.getElementById(iframeName);
if (iframe) {
var x=iframe.parentNode.removeChild(iframe)
}
}
function addElement(iframeName) {
var butt = document.createElement('button');
var butt_text = document.createTextNode('Remove');
butt.appendChild(butt_text);
butt.onclick = removeIframe(iframeName);
document.body.appendChild(butt);
}
The problem is that, when the button is created, the onclick function is executed immediately and not only when the user presses it, so my new Iframe is immediately deleted and I cannot see it.
How can I solve this problem?
Moreover, is it possible to add the button not in the parent body but directly into the new created iframe?
Thanks in advance.
The onclick has to be a function, replace following line
butt.onclick = removeIframe(iframeName);
with
butt.onclick = function() { removeIframe(iframeName); }
You need to pass function handler instead of function call result to onclick attribute.
You can do that using anonymously function:
butt.onclick = function() { removeIframe(iframeName); };

processing.js change script source

I need to find a way where I can dynamically change the source of a processing script inside an HTML document.
This is the embedded script which works fine:
<script type='application/processing' src='sketch.txt' id="applet">
</script>
Now I try to change the source:
$('#applet').attr('src', 'sketch2.txt');
alert($('#applet').attr('src'));
The alert shows that the source was changed to 'sketch2.txt' but the applet still remains the same. I think I need to refresh the script in some way.
Thank you in advance for any help!
I believe you have to manually attach each proc to the canvas, instead of just changing the the source file. This worked here:
function first_call(processing) {
processing.size(300,300);
processing.background(100);
var called = false;
processing.draw = function() {
if (!called) { processing.println("called #1"); called = true; }
}
}
function second_call(processing) {
processing.size(400,400);
processing.background(200);
var called = false;
processing.draw = function() {
if (!called) { processing.println("called #2"); called = true; }
}
}
var canvas = document.getElementById('canvas1');
var processingInstance = new Processing(canvas, first_call);
var processingInstance = new Processing(canvas, second_call);

Updating page HTML causes endless loop

I'm writing a Firefox extension. The extension replaces certain words on the page with other words. Here's the basic code I'm using:
function startup() {
gBrowser.addEventListener("load", pageLoad, true);
}
function pageLoad(event) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
}
The problem is that this code is causing an endless loop. When I set the innerHTML property of the body, it sends another load event, which causes the endless loop.
How can I modify the page when it loads without causing the page load event to fire again?
You could use the following code to check if it has already been run before.
var loaded = false;
function pageLoad(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
Alternatively, if you wanted to keep the loaded variable out of global scope, you could use a closure:
var pageLoad = (function () {
var loaded = false;
return function(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
}();
The outer function gets executed immediately and returns the inner function which will have visibility of the loaded variable due to closure.
Would having a div or span tag immediately inside of your body tag be an option? Then you could just update the innerHTML of that element, and not the entire body...

Categories