Changing CSS URL for pointer cursor (using Javascript) - javascript

I asked a question yesterday here about having a cursor that changes regularly using javascript, to make it look animated. I got a great answer (Thank you Shiva!). I've now been trying to get two different 'animated' cursors, one for the 'auto' cursor, and a different one for the 'pointer' cursor.
I tried it lots of different ways, but just can't work it out (I must admit, I'm completely new to this - trying to improve). Here's one of the ways I tried to do it:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript">
var images = [
'assets/shared/cursors/drum1.cur',
'assets/shared/cursors/drum2.cur',
'assets/shared/cursors/drum3.cur',
'assets/shared/cursors/drum4.cur'
];
var x = 0;
function displayNextImage() {
x = (x === images.length - 1) ? 0 : x + 1;
document.body.style.cursor = 'url("' + images[x] + '"), default';
}
setInterval(displayNextImage, 250);
</script>
<script type = "text/javascript">
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function displayNextImage() {
x = (x === images.length - 1) ? 0 : x + 1;
document.body.style.cursor:pointer = 'url("' + images[x] + '"), default';
}
setInterval(displayNextImage, 250);
</script>
<body>
<div style="height: 1000vh; width: 1000vw;"></div>
</body>
</html>
</head>
</html>
If possible I'd like to do it without jQuery.
Again, any help is really appreciated.
Thanks! :)

You can try using jQuery for this :
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function changeLinkCursorHoverBinding(){
$("a").hover(function(){/*this is the mouseenter triggered function*/
$(this).css("cursor",'url("' + images[x] + '"), default');
}, function(){
//handle mouseleave here if needed
});
x = (x === images.length - 1) ? 0 : x + 1;//put at the end to start at 0
setTimeout(changeLinkCursorHoverBinding, 250);
}
$(document).ready(changeLinkCursorHoverBinding);//initial call of the function
EDIT
Or without jQuery :
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function changeLinkCursorHoverBinding(){
var elems = document.querySelectorAll("a");
elems.removeEventListener("mouseenter", onHover);
elems.removeEventListener("mouseleave", offHover);
elems.addEventListener("mouseenter", onHover);
elems.addEventListener("mouseleave", offHover);
x = (x === images.length - 1) ? 0 : x+1;
setTimeout(changeLinkCursorHoverBinding, 250);
}
function onHover(){
var elems = document.querySelectorAll("a");
for(e in elems){
e.style.cursor = "url('" + images[x] + "'), default";
}//you can use the regular for loop here if you wanna
}
function offHover(){
var elems = document.querySelectorAll("a");
for(e in elems){
/*handle mouseleave here*/
}
}
I had to name EH functions (and remove EH each call) because I wasn't sure that addEventListener overrides same handler if called again.
EDIT
for non jQuery way, you need to add onload="changeLinkCursorHoverBinding()" on your <body> tag this way :
<body onload="changeLinkCursorHoverBinding()"> (the initial call after page's load).

Related

increment variable using jquery

I feel like this is a pretty basic thing, but I cant seem to find the solution. Im trying to increment a value after the loading of an IFRAME.
the code looks like this:
var x=0;
$(document).ready(function() {
$('#iframe-2').load(function() {
var x=x+1;
});
$('#iframe-3').load(function() {
var x=x+1;
});
$('#iframe-4').load(function() {
var x=x+1;
});
$('#iframe-5').load(function() {
var x=x+1;
});
});
What I want to do is give a number of loaded iframes that updates when an iframe completes its loading. The output code is like this currently:
<script language="javascript">
document.write(x + " Results");
</script>
thanks a ton in advance for any help!
You should change
var x = x+1;
to
x = x+1
Because the var keyword is creating a new variable every time in your every load so global variable x is not getting updated/incremented.
You declare local variable in the load callback function, so it will not increase the global x, you could declare var x inside of dom ready callback function, and use it in load callback function.
$(document).ready(function() {
var x = 0;
$('#iframe-2').load(function() {
x++;
});
$('#iframe-3').load(function() {
x++;
});
$('#iframe-4').load(function() {
x++;
});
$('#iframe-5').load(function() {
x++;
});
});
Edit:
After this, document.write(x + " Results"); still won't work, because it executes before the iframe has been loaded. You need to do a check asynchronously.
Here is the live demo.
$(document).ready(function() {
var x = 0;
$('iframe').load(function() {
x++;
});
var time_id = setInterval(function() {
$('#count').text(x);
if (x === $('iframe').length) {
clearInterval(time_id);
}
}, 200);
});​
The html:
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<hr>
Loaded iframe count: <span id="count">0<span>
I finally came up with a very simple solution:
var x=0;
$(document).ready(function() {
$('#iframe-2').load(function() {
$("#t2").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-3').load(function() {
$("#t3").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-4').load(function() {
$("#t4").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-5').load(function() {
$("#t5").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
});
Javascript has "function scope" - variables exist only within the function they were created in. So it is possible to have several different variables named x, if and only if they are in different functions (which is the case here).
Variables are created with the var keyword and accessed without a keyword. So, var x = 10; creates a variable named x, and x = 10; modifies an existing variable named x.
In your code every function calls var x = 10;. Since the previously defined x was defined in an outer function, that line is valid and created a new variable named x, scoped to the function it is being called in. If you were to omit the var statement, the interpreter would first look at the current function's namespace and not find x. Then it would move up to the global scope and find the x that you already declared, and use that.
In short, omit the word var in every line except line 1:
var x = 0;
$(document).ready(function () {
$('#iframe-2').load(function () {
x = x + 1;
});
$('#iframe-3').load(function () {
x = x + 1;
});
$('#iframe-4').load(function () {
x = x + 1;
});
$('#iframe-5').load(function () {
x = x + 1;
});
});
Another alter solution for above query using jQuery is here...
HTML:
<div id="top"></div>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<div id="bottom"></div>
JQuery:
var x = 0;
$(function() {
$('iframe:eq(0)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(1)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(2)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(3)').load(function() {
x = x + 1;
result(x);
});
});
function result(x) {
if (x == null || typeof(x) == "undefined") x = 0;
$("#top").html("<div>Loaded iframe count: " + x + "</div><hr/>");
$("#bottom").html("<hr/><div>Loaded iframe count: " + x + "</div>");
}
Try on codebins too http://codebins.com/codes/home/4ldqpbk

loop into js object

i have this js object:
var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];
i try to loop in this way:
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX ){
$(myDiv).bind('click',function(){
document.location.href = 'x.php?a='+ tags[i].linea +'&b=' + tags[i].id;
}).css('cursor','pointer');
}else{
$(myDiv).unbind('click').css('cursor','none');
}
}
But i loose the first!
Is this the correcy way??
Thanks!
You don't loose the first (sounds like it was a car key). You problem is your anonymous function, that closes over its parent scope when executed( for your .bind() method). It creates, what we call, a Closure.
Its a very common mistake in ECMAscript there. You need to invoke an additional context to avoid this issue.
$(myDiv).bind('click',(function( index ){
return function() {
document.location.href = 'x.php?a='+ tags[index].linea +'&b=' + tags[index].id;
};
}( i ))).css('cursor','pointer');
If you don't do that, all of those anonymous function context will share the same parent context in their scope-chain. Without describing that too much in detail now, it'll end up that all event handlers would reference the same variable i.
Beside that, it looks like you're binding multiple click event handlers to the same element myDIV. Each handler would cause the browser to redirect to another url, so, this will bring trouble. I can't even tell if the first or the last handler will win this race.
Variable scope.. change to this and it should work fine:
var lineA = tags[i].linea;
var id = tags[i].id;
$(myDiv).bind('click',function(){
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
}).css('cursor','pointer');
The problem is with i being the loop iterator, so when you click myDiv it will have the last value always.
Edit: after looking into it, I could see you are taking the wrong approach. What you are after is identifying where the user clicked inside the <div> and redirect to different location according to your array. For this, such code should work:
var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];
$("#myDiv").bind('click',function(event) {
var left = event.pageX - $(this).position().left;
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX ){
var lineA = tags[i].linea;
var id = tags[i].id;
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
break;
}
}
});
The code should be pretty clear, anyway it's not possible to have only parts of the element with hand cursor - I advise you not to mess too much as it will be really complicated.
Live test case.
Edit 2: Having the "clickable" parts of the element with different cursor is easier than I initially thought, you just have to handle the onmousemove event as well and in there set the cursor:
var posLeft = $("#myDiv").position().left;
$("#myDiv").bind('click',function(event) {
var tag = GetHoveredTag(event);
if (tag) {
var lineA = tag.linea;
var id = tag.id;
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
}
}).bind("mousemove", function(event) {
var tag = GetHoveredTag(event);
var cursor = (tag) ? "pointer" : "";
$(this).css("cursor", cursor);
});
function GetHoveredTag(event) {
var left = event.pageX - posLeft;
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX )
return tags[i];
}
return 0;
}
Updated fiddle.

Make a jQuery slider work with divs instead of images

I am working on this website page poochclub.com and I am trying to make all of it text instead of images. The problem is when I want to work on the panels below with all the information the js file (called about.js) is set to work with images instead on divs where I could potentially add text.
I am not very good at writing javascript and I need help to fix the original file which looks as follows:
<script type="text/javascript>
(function ($) {
var pages, panels, arrows, currentClass = 'current',
currentIndex = 0, currentSize = 0;
function showPage() {
var ctx = jQuery.trim(this.className.replace(/current/gi, ''));
$(this).addClass(currentClass).siblings().removeClass(currentClass);
$('.panel')
.removeClass(currentClass)
.find('img')
.removeClass(currentClass)
.removeAttr('style')
.end();
panels.find('.' + ctx)
.addClass(currentClass)
.find('img')
.removeClass(currentClass)
.removeAttr('style')
.eq(0)
.fadeIn()
.addClass(currentClass)
.end()
currentIndex = 0;
currentSize = panels.find('.' + ctx + ' img').length;
return false;
}
function showArrows(e) {
arrows['fade' + (e.type === 'mouseenter' ? 'In' : 'Out')]();
}
function getPrev() {
currentIndex = currentIndex - 1 < 0 ? currentSize - 1 : currentIndex - 1;
return currentIndex;
}
function doPrev() {
var ctx = panels.find('div.current img');
ctx.removeClass(currentClass).removeAttr('style');
ctx.eq(getPrev()).fadeIn().addClass(currentClass);
}
function getNext() {
currentIndex = currentIndex + 1 >= currentSize ? 0 : currentIndex + 1;
return currentIndex;
}
function doNext() {
var ctx = panels.find('div.current img');
ctx.removeClass(currentClass).removeAttr('style');
ctx.eq(getNext()).fadeIn().addClass(currentClass);
}
$(document).ready(function () {
pages = $('.panels-nav a');
panels = $('.panels');
arrows = $('.arrows');
pages.click(showPage);
panels.bind('mouseenter mouseleave', showArrows);
arrows.find('.prev').click(doPrev).end().find('.next').click(doNext);
pages.eq(0).click();
});
});
</script>
My questions is, how do I change the js file from finding img to finding several different div id's attached to the sliding panles?
Thanks.
any reference to img should be a new selector. Something like 'div.slider', a div with a class slider.
Look at all the finds, thats where you will see the img selectors.

Rotating URLs within an Iframe

I have 10 different urls that I want to feed into an iframe src attribute that I would also like to rotate say every 5 seconds between all the 10 urls within the iframe.
Unsure how to do this using javascript/best approach?
Sorry, should've mentioned that I am using IE6.
Thanks.
<iframe id="rotator" src="http://...first"></iframe>
<script>
// start when the page is loaded
window.onload = function() {
var urls = [
"http://...first",
"http://...second",
// ....
"http://...tenth" // no ,!!
];
var index = 1;
var el = document.getElementById("rotator");
setTimeout(function rotate() {
if ( index === urls.length ) {
index = 0;
}
el.src = urls[index];
index = index + 1;
// continue rotating iframes
setTimeout(rotate, 5000);
}, 5000); // 5000ms = 5s
};
</script>
Javascript (place in window.onload)
var urls = ['http://www.stackoverflow.com', 'http://www.google.com'];
var pos = 0;
next();
setInterval(next, 5000); // every 5 seconds
function next()
{
if(pos == urls.length) pos = 0; // reset the counter
document.getElementById('rotate').src = urls[pos];
pos++;
}
HTML
<iframe id="rotate"></iframe>
There are many ways, so best is up for debate. Take a look at setInterval() since you mentioned JavaScript. I'd write a method that got the iframe on the page by it's id attribute, getElementById() and changed the src attribute to the next URL in the array of URLs.
<!doctype html>
<html>
<body>
<iframe id="foo"></iframe>
<script>
(function() {
var e = document.getElementById('foo'),
f = function( el, url ) {
el.src = url;
},
urls = [
'http://www.msn.com/',
'http://www.mtv.com/'
],
i = 0,
l = urls.length;
(function rotation() {
if ( i != l-1 ) {
i++
} else {
i = 0;
}
f( e, urls[i] );
setTimeout( arguments.callee, 5000 );
})();
})();
</script>
</body>
</html>
Is there a reason to reload the iframes every time they rotate in? I might load all the iframes upfront and simply rotate through their display if this particular project was concerned with quality of experience.
Hi I assume you would want to load the page completely before starting the timer to load the next URL, otherwise you would end up showing the next URL before the existing page even shows up (depending on your internet speed).
Secondly you said you want to rotate the URLS.
Below is the tested code for this:
<html>
<head>
<title></title>
<style type="text/css">
</style>
<script type="text/javascript">
var urls = [
"http://www.google.com"
,"http://www.yahoo.com"
,"http://www.ajaxian.com"
,"http://www.ebay.com"
];
function showUrl(idx) {
alert(idx + " Showing " + urls[idx]);
var f = document.getElementById("f");
// call the next load after 5 seconds only after
// this iframe loads
f.onload = function() {
var next = ++idx % urls.length;
setTimeout(function(){
showUrl(next);
}, 5000);
}
// set the src
f.src = urls[idx];
}
</script>
</head>
<body onload="showUrl(0)" class="app-chrome">
<iframe id="f" src="about:blank"></iframe>
</body>
</html>
Adding a more compact version: (Works in IE6, FF, Opera, Chromium)
<script type="text/javascript">
window.onload = (function(urls, interval) {
var idx = 0;
var bAttached = false;
return function showUrl() {
var f = document.getElementById("f");
var onLoad = function() { // loading only after previous page loads
idx = ++idx % urls.length; // rotation
setTimeout(showUrl, interval);
}
if(! bAttached) {
if(navigator.userAgent.indexOf("MSIE") !== -1) {
f.attachEvent("onload", onLoad);
bAttached = true;
}else {
f.onload = onLoad;
}
bAttached = true;
}
f.src = urls[idx];
};
})([
"http://www.google.com" ,"http://www.yahoo.com" ,
"http://www.sun.com" ,"http://www.ebay.com"
], 5000
);
</script>
I am not going to do it all for you but an example as requested:
Using Jquery for ease.
Code:
<script type="text/javascript">
//sets a var to 0//
var MyInt = 0
//sets some URLS//
var url1 = 'http://UR1L.com';
var url2 = 'http://URL2.com';
var url3 = 'http://URL3.com';
function RunEveryTenSecs {
// Increases var by 1//
MyInt + 1;
//Checks var value if 1 runs if not goes to next//
if (MyInt == 1) {
$('#MyElementID').html('<iframe src="' + url1+ '"></iframe>');
}
if (MyInt == 2) {
$('#MyElementID').html('<iframe src="' + url2+ '"></iframe>');
}
if (MyInt == 3) {
$('#MyElementID').html('<iframe src="' + url3+ '"></iframe>');
MyInt = 0;
}
}
window.setTimeout(RunEveryTenSecs, 10000);
</script>
HTML:
<div id="MyElementID">
IFRAME WILL GO HERE.
</div>
It may not be the neatest there are other ways to do it but it is something simple and easy to understand. The URL's dont have to be seperate but it will make changing them in the future easier.

Animating with parameters in Javascript using a timer

I'm trying to animate a dot from one point to another on a map. Right now I have the following code:
function animate(){
//animation
var pt = oldLoc;
for(i = 0; i < 1000; i++){
pt.y += 5
pt.x += 5
graphic.setGeometry(pt); //sets the new point coordinates
graphic.show(); //redraws the display
dojo.byId("info").innerHTML += "testingcheck"; //print check
}
}
When I run the code right now, the dot does move, but it "jumps" from the beginning location to the final location. It seems like the show() doesn't execute until the entire loop has been run through.
I know I need something that looks like setTimeOut(animate(), 20), but I don't know how to incorporate it into my code (do I make a new function?) and how to specify when to stop the animation. Any insight would be much appreciated. Thanks in advance!
You could also easily replace your for loop for a setInterval call, e.g.:
function animate(){
var pt = oldLoc, i = 0, timer; // no global variables declared...
timer = setInterval(function () {
pt.y += 5;
pt.x += 5;
graphic.setGeometry(pt);
graphic.show();
dojo.byId("info").innerHTML += "testingcheck";
if (i >= 1000) { // stop condition
clearInterval(timer);
}
i++;
}, 100);
}
You are using dojo, so why not using it also for animation ?
Suppose your point is a floating div with an absolute positioning, which id is "point", you could do :
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4.0/dojo/dojo.xd.js" djConfig="parseOnLoad: true, isDebug: true"></script>
<script type="text/javascript">
function moveNodeByXY(movingNode, shiftX, shiftY) {
var startPos = dojo.position(movingNode);
var endX = startPos.x + shiftX;
var endY = startPos.y + shiftY;
console.debug("Point moving from (" + startPos.x + ", " + startPos.y + ") to (" + endX + ", " + endY + ")");
dojo.fx.slideTo({ node: movingNode, left:endX, top:endY, units:"px" }).play()
}
dojo.addOnLoad(function() {
dojo.require("dojo.fx");
});
</script>
<style type="text/css">
#point {
position : absolute;
z-index : 1000;
height : 10px;
width : 10px;
left : 50px;
top : 50px;
background-color : #3C3C3C;
}
</style>
</head>
<body>
<div id="point" onClick="moveNodeByXY(this, 5, 5);"></div>
</body>
</html>
dojo.require("dojox.fx._Line"); // multidimensional curve support
dojo.ready(function(){
new dojo.Animation({
curve: new dojox.fx._Line([ [startx, endx], [starty, endy] ]),
onAnimate:function(currentx, currenty){
graphic.setGeometry({ x: currentx, y: currenty });
graphic.show();
},
duration:1000,
rate:10 // framerate, aka: setInterval(..., rate)
}).play();
});
Something along the lines of:
function animate(){
....;
}
var timer = setInterval(animate, 50);
//To stop
clearInterval(timer);
Ideally you want to measure the real time which has passed between the animate calls and move the object taking in account that time. But this should be a start. JavaScript timers are little bit tricky, intervals aren't that accurate in JavaScript.
Two good links to get you started:
One
Two
And here's a good starting tutorial on the topic.
Something like
var currentPoint = oldLoc;
var i = 0;
function animate()
{
i++;
if ( i >= 1000 )
{
i = 0;
clearInterval ( timeOutId );
}
else
{
currentPoint.y += 5;
currentPoint.x += 5
graphic.setGeometry(currentPoint); //sets the new point coordinates
graphic.show(); //redraws the display
dojo.byId("info").innerHTML += "testingcheck"; //print check
}
}
var timeOutId = setInterval(animate, 20);

Categories

Resources