roll-over script not working - javascript

I am trying to make a mouse roll-over. i.e when user places the pointer on the image mouse over event is triggered and the next image from the array comes over.But nothing is happening when i am running this script :
window.onload = startRollOver;
var pictures = new Array("1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg","8.jpg");
var i = 0;
function startRollOver() {
document.getElementById("picture").src.onmouseover = createRollOver();
}
function createRollOver() {
if(i<=7)
return pictures[i++];
if(i>7) {
i=0;
return pictures[i];
}
}
Where am i going wrong ?

.src.onmouseover does not make much sense. You should assign a function to onmouseover so that the function gets called when the mouse moves over the element:
document.getElementById("picture").onmouseover = function() { // is executed when mouse is over element
this.src = createRollOver(); // each time it is called, change the src
};
Also, you can use a more convenient way of declaring arrays:
["1.jpg", "2.jpg", ...]

You're setting "onmouseover" on the string "src" instead of on the DOM element. You need to set the event on the DOM element.
window.onload=startRollOver;
function startRollOver() {
document.getElementById("picture").onmouseover = function (e) {
e.target.src = createRollOver();
};
}
function createRollOver() {
// ...
}

Related

Get data attr value on hover

I have a few links. When I hover mouse over the links I would like to get the values stored in data attributes. I need to pick the t values and pass them into function
HTML
<a href="#" data-lat="23.333452" data-lon="-97.2234234">
JS
var loc = document.querySelectorAll("a[data-lat]");
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
function locOver() {
// do something
}
function locOut() {
// do something else
}
It's been a while since I used vanilla JS and it's been a long day so I'm sure it's pretty close but I'm stuck. I keep getting:
Uncaught TypeError: loc.addEventListener is not a function
What am I missing here?
You need to loop through the nodes that you obtained with document.querySelectorAll("a[data-lat]") for adding events.
Working example.
Node
<script>
var loc = document.querySelectorAll("a[data-lat]");
loc.forEach(node => {
node.addEventListener("mouseover", locOver);
node.addEventListener("mouseout", locOut);
})
function locOver(event) {
// do something
console.log('mouseover', event.target.dataset)
}
function locOut() {
// do something
console.log('locOut')
}
</script>
const loc = document.querySelector("a[data-lat]");
const locOver = () => {
console.log("Mouse is over the link");
}
const locOut = () => {
console.log("Mouse is out of the link");
}
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
Link
Explanation:
I target the link using .querySelector method that returns a single node.
After that i created two event handler for mouseOver and mouseOut and than i added the eventListener to the link.

Attaching onclick method to multiple canvas using a for loop

I need to add a onclick function to multiple canvas in a . I use a for loop to go through all the canvas and then add the onclick event with attachEvent.
I already tried with an eventlistener or directly adding the onclick event but nothing seems to work please let me know if you can see my mistake...
Here's my JavaScript code:
//here's the loop where the canvas get their width, height and onclick
//event.
function canvasSize() {
var canvas=document.getElementsByTagName('canvas');
var ctx;
for (var i=0;i<canvas.length;i++) {
canvas[i].width="50";
canvas[i].height="50";
ctx=canvas[i].getContext('2d');
ctx.fillRect(0,0,50,50);
ctx.fillStyle="blue";
canvas[i].attachEvent("click", onClick(this,"voitures"));
}
};
//onclick() function
function onClick(elem,theme) {
var images=preloadImages(theme);
var canvas=getElementsByTagName("canvas");
for (var i=0;i<canvas.length;i++) {
if (canvas[i]==elem) {
elem.drawImage(images[0],0,0)
}
}
};
//function where I preload every images
function preloadImages(theme) {
var tab=[];
var imageObj= new Image();
if (theme=="cars") {
tab[0]="0.jpg"
tab[1]="1.jpg"
tab[2]="2.jpg"
tab[3]="3.jpg"
tab[4]="4.jpg"
tab[5]="5.jpg"
tab[6]="6.jpg"
tab[7]="7.jpg"
tab[8]="8.jpg"
tab[9]="9.jpg"
tab[10]="10.jpg"
tab[11]="11.jpg"
tab[12]="12.jpg"
//...
}
for (var i=0;i<32;i++) {
imageObj.src=tab[i];
//imageObj.onload=alert("img "+i+" is loaded");
}
return tab;
}
}
The code crash before adding the onclick function. Hope someone can help me find my mistake.
One: attachEvent is only available in IE.
Two: DON'T name functions onClick it's a reserved global event handler.
So to fix your for loop I would change your last line to this:
for (var i=0;i<canvas.length;i++) {
var self = this;
if(window.attachEvent){
canvas[i].attachEvent("click", function(){
newNameForOnClickFunction(self, "voitures");
}, false);
}else{
canvas[i].addEventListener("click", function(){
newNameForOnClickFunction(self, "voitures");
}, false);
}
}
I'm betting that you want to pass the canvis to your next function and not a refrence to your canvasSize function. If that's the case then you should pass canvas[i] instead of this (or self in my example above)

A Function to Check if the Mouse is Still Hovering an Element Every 10 Milliseconds (and run a function if it is)

I was wondering if there is a function to be run after an element (e.g. div class="myiv") is hovered and check every X milliseconds if it's still hovered, and if it is, run another function.
EDIT: This did the trick for me:
http://jsfiddle.net/z8yaB/
For most purposes in simple interfaces, you may use jquery's hover function and simply store in a boolean somewhere if the mouse is hover. And then you may use a simple setInterval loop to check every ms this state. You yet could see in the first comment this answer in the linked duplicate (edit : and now in the other answers here).
But there are cases, especially when you have objects moving "between" the mouse and your object when hover generate false alarms.
For those cases, I made this function that checks if an event is really hover an element when jquery calls my handler :
var bubbling = {};
bubbling.eventIsOver = function(event, o) {
if ((!o) || o==null) return false;
var pos = o.offset();
var ex = event.pageX;
var ey = event.pageY;
if (
ex>=pos.left
&& ex<=pos.left+o.width()
&& ey>=pos.top
&& ey<=pos.top+o.height()
) {
return true;
}
return false;
};
I use this function to check that the mouse really leaved when I received the mouseout event :
$('body').delegate(' myselector ', 'mouseenter', function(event) {
bubbling.bubbleTarget = $(this);
// store somewhere that the mouse is in the object
}).live('mouseout', function(event) {
if (bubbling.eventIsOver(event, bubbling.bubbleTarget)) return;
// store somewhere that the mouse leaved the object
});
You can use variablename = setInterval(...) to initiate a function repeatedly on mouseover, and clearInterval(variablename) to stop it on mouseout.
http://jsfiddle.net/XE8sK/
var marker;
$('#test').on('mouseover', function() {
marker = setInterval(function() {
$('#siren').show().fadeOut('slow');
}, 500);
}).on('mouseout', function() {
clearInterval(marker);
});​
jQuery has the hover() method which gives you this functionality out of the box:
$('.myiv').hover(
function () {
// the element is hovered over... do stuff
},
function () {
// the element is no longer hovered... do stuff
}
);
To check every x milliseconds if the element is still hovered and respond adjust to the following:
var x = 10; // number of milliseconds
var intervalId;
$('.myiv').hover(
function () {
// the element is hovered over... do stuff
intervalId = window.setInterval(someFunction, x);
},
function () {
// the element is no longer hovered... do stuff
window.clearInterval(intervalId);
}
);
DEMO - http://jsfiddle.net/z8yaB/
var interval = 0;
$('.myiv').hover(
function () {
interval = setInterval(function(){
console.log('still hovering');
},1000);
},
function () {
clearInterval(interval);
}
);

Jquery - binding click event to a variable

All,
I am really stuck/ confused at this point.
I have an array with 6 items in it. Each item in the array is dynamically filled with elements using jquery '.html' method. However, I cannot seem to be able to attach/ bind an event to this dynamically created variable.
As soon as the browser gets to the problem line (see the area labeled 'PROBLEM AREA'), I get a 'undefined' error, which is really confusing as all the previous code on the very same variable works just fine.
var eCreditSystem = document.getElementById("creditSystem");
var i = 0;
var eCreditT = new Array(6); // 6 members created which will be recycled
function createCreditTransaction () // func called when a transaction occurs, at the mo, attached to onclick()
{
if (i < 6)
{
eCreditT[i] = undefined; // to delete the existing data in the index of array
addElements (i);
} else
if (i > 5 || eCreditT[i] != undefined)
{
...
}
}
function addElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditT[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditT[i]).attr ('id', ('trans' + i));
$(eCreditT[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditT[i], 666); // calling slideOut animation
console.log(eCreditT[i]); // this confirms that the variable is not undefined
/* ***** THE PROBLEM AREA ***** */
$(eCreditT[i]).on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn (eCreditT[i], 150); // slide back in animation
});
return i++;
}
Try this:
$(eCreditT[i]).bind('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Edit: use ++i instead of i++ like this:
return ++i;
/*
or
i += 1;
return i;
*/
retrurn ++i performs the increment first then return i after the increment.
While return i++ return i then icrement it.
Try to add click event out of addElements() function and try once.
Nonsense create an element using JavaScript and then use jQuery function to transform it into a jQuery object. You can let jQuery create the element directly for you.
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
Also, since eCretitT[i] is already a jQuery element, no need to call the jQuery function again.
eCreditT[i].on('click', function () {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
If you already tried on, bind, live and click methods, then maybe the called function is your problem. Try to put a console.log() or an alert() inside the function to make sure the click event is actually happening. If it happens then the function creditTransactionSlideBackIn() is your problem.
EDIT
The problem is when the event takes place, i is not the original variable anymore.
function addElements (arrayIndex)
{
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
eCreditT[i].attr ('id', ('trans' + i));
eCreditT[i].data ('id', i); // Store the id value to a data attribute
Then when you call the function you can refer to the data attribute instead of the i variable:
/* ***** THE PROBLEM AREA ***** */
eCreditT[i].on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn ($(this).data('id'), 150); // slide back in animation
});
return i++;
}
try to bind parent div and then use if($e.target).is('some')){}, it will act as .live, like this:
$(eCreditSystem).bind('click', function (e){
if($(e.target).is('.cCreditTransaction')) {
creditTransactionSlideBackIn ($(e.target), 150);
}
});
of course you'll need in a minute larger if for checking if clicked dom el is a child of .cCreditTransaction, like this:
if($(e.target).parents().is('.cCreditTransaction')){}
Try this:
$(eCreditT[i]).live('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});

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