Change cursor on hovering over a Raphael element - javascript

A Raphael element is created dynamically (in response to user input, not upon page load). I want to use Raphael's .hover() method to change the cursor to "pointer" (the hand usually used for links) when the user hovers over the object. How can this be accomplished?
(I know that you can use CSS to achieve this effect, but because the DOM element is created via scripting, rather than being built into the page upon load, I don't know if CSS can be applied here, or how it would be if it can be.)
http://www.w3schools.com/cssref/playit.asp?filename=playcss_cursor&preval=pointer
https://web.archive.org/web/20160121064823/http://raphaeljs.com/reference.html

Looks like "cursor" is actually one of the attributes than can be modified with Raphael's .attr() function. So,
el.hover(function(){el.attr({'cursor':'pointer'})},
function(){el.attr({'cursor':'default'})}, el, el);
does the trick.

var paper = Raphael("rect", 400, 400);
var hoverIn = function() {
// if the context is not stated forcefully, this refers to the element in context.
// can be any valid cursor types.
this.attr({"cursor": "pointer"});
};
var hoverOut = function() {
this.attr({"cursor": "default"});
}
// simple click callback.
var clickFN = function (){
alert('Hey you just clicked me :p, Thanks!!!')
};
var cItem = paper.rect(40,40,50,30)
// attaching the hovering callbacks.
.hover(hoverIn, hoverOut)
// these are just additional cosmetics and fuctionalities.
.attr({
"fill": "#0ff000"
})
.click(clickFN);
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.1/raphael.min.js"></script>
<div id="rect"></div>
or play with this fiddle!
Hey while invoking the .hover function the third and fourth parameters remains optional and used only if you need to change the context in your code.

Set the cursor attribute value for a specific object directly.
Keep it simple! :)
var paper = Raphael("rect", 400, 400);
var myRectangle = paper.rect(40,40,50,30);
myRectangle.attr({
'cursor':'pointer',
"fill": "#0ff000"
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.1/raphael.min.js"></script>
<div id="rect"></div>

Related

Alter the text in the p tags

I want to alter the text in the p tags to gain (upon clicking the text) the properties set by the attribution class.
Here is the HTML:
<p onclick="function">Hello</p>
CSS:
.attribution{
color:blue;
font-weight:bold;
}
Javascript:
var main = function() {
$('<p>').text('.attribution');
};
$(document).ready(main);
Thank You!
<p onclick="function">Hello</p>
You:
Have to use the name of the function, not the keyword function which creates a new function.
Have to actually call the function, by appending () to the variable name
Shouldn't use intrinsic event attributes at all. Bind event handlers with JavaScript.
So
<p>Hello</p>
<script>
$("p").on("click", main);
</script>
var main = function() {
$('<p>').text('.attribution');
};
$(document).ready(main);
You:
Should use a function declaration (since it plays nicely with debuggers)
Need to select the existing paragraph instead of creating (and promptly discarding) a new one)
Add attribution to the classes on the element instead of replacing the text content of it with the phrase ".attribution"
Not call the function on DOM ready when you want it to be called when something is clicked
Such
function main() {
$('p').addClass('attribution');
};
As an aside, paragraphs are not designed to be interactive. While you can click on them with a mouse pointer, nothing encourages people to do so, they are outside the normal focus list (so people who don't use a mouse can't tab to them) and don't show up in screen readers as something that should be clicked on. Use appropriate markup (perhaps a button).
Okay, since your loading JQuery why no use its methods for handling click events and changing the css properties.
$( "p" ).on( "click", function() {
$(this).addClass('attribution');
});
1) You are not actually hooking any callback function to onclick event. You need to specifiy what function you want to be executed on click.
So:
HTML:
<p onclick="addClass(event)">Hello</p>
JavaScript:
function addClass(evt){
evt.target.classList.add('attribution');
}
jQuery alternative:
var main = function(){
$("p").click(function(){
$(this).addClass("attribution");
});
}
$(document).ready(function(){
main();
});

'This' in Object Oriented Javascript

I think that I currently write pretty good javascript, but am trying to move to a more Object Oriented approach. I am just starting with this so forgive my noob-ness. I was moving some of my functions over to objects and ran into this issue. Previously, I had an accordion function that worked like this:
jQuery(document).ready(function ($){
var accordionTrigger = $('.accordion-title');
function toggleAccordion() {
// Set a variable for the accordion content
var accordionContent = $('.accordion-container .accordion-content p');
// Slide up any open content
accordionContent.slideUp();
// Remove any active classes
accordionTrigger.removeClass("active");
// If the sibling content is hidden
if(!$(this).siblings().is(":visible")) {
// slide it down
$(this).siblings().slideDown();
// add a class to the title so we can style the active state and change the svg
$(this).addClass("active");
}
}
accordionTrigger.on("click", toggleAccordion);
});
I have moved this over to an Object in my new set-up like this:
Accordion = {
accordionContent: '.accordion-container .accordion-content p',
accordionTrigger: '.accordion-title',
init: function() {
jQuery(this.accordionTrigger).click(this.toggleAccordion.bind(this));
},
toggleAccordion: function() {
// Slide up any open content
jQuery(this.accordionContent).slideUp();
// Remove any active classes
jQuery(this.accordionTrigger).removeClass("active");
// If the sibling content is hidden
if(!jQuery(this.accordionTrigger).siblings().is(":visible")) {
// slide it down
jQuery(this.accordionTrigger).siblings().slideDown();
// add a class to the title so we can style the active state and change the svg
jQuery(this.accordionTrigger).addClass("active");
}
}
}
jQuery(document).ready(function ($){
Accordion.init();
});
The issue that I'm running into is with the way that 'this' works in Object Oriented Javascript. In the original setup, I was able to use 'this' to reference the accordion content that was clicked. I do not have access to that with the Object Oriented method. Can someone please help me out with?
You can use event.target to refer to the element that triggered the event, or event.currentTarget to refer to the element the handler was bound to, which is equivalent to using this.
toggleAccordion: function(event) {
// Slide up any open content
jQuery(this.accordionContent).slideUp();
// Remove any active classes
jQuery(this.accordionTrigger).removeClass("active");
// If the sibling content is hidden
if(!jQuery(event.currentTarget).siblings().is(":visible")) {
// slide it down
jQuery(event.currentTarget).siblings().slideDown();
// add a class to the title so we can style the active state and change the svg
jQuery(event.currentTarget).addClass("active");
}
}
Learn more about event handling with jQuery.
The problem is not how this works on OOP JavaScript because this is always referencing the caller object.
You can learn more about this with You Don't Know JS: this & Object Prototypes.
You can indeed use event.target and event.currentTarget as #Felix says, but eventually you will get into trouble if you don't understand how to use this properly or at least understand how it works.
An alternative approach to #FelixKling solution, removing .bind() , using event.data to have access to both jQuery(this) and Accordion object within accordionTrigger handler
var Accordion = {
accordionContent: '.accordion-container .accordion-content p',
accordionTrigger: 'div',
init: function() {
// set `event.data` to `this`:`Accordion` at first parameter to `.click()`
jQuery(this.accordionTrigger).click(this, this.toggleAccordion);
},
toggleAccordion: function(e) {
// Slide up any open content
// jQuery(e.data.accordionContent).slideUp();
// Remove any active classes
// jQuery(e.data.accordionTrigger).removeClass("active");
// If the sibling content is hidden
// `this`:`div`
if (jQuery(this).is(e.data.accordionTrigger)) {
console.log(this, e.data, $(e.data.accordionTrigger))
}
}
}
Accordion.init()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div>
click
</div>
Within toggleAccordion(), you can still use $(this) to get the accordion title element that has been clicked on. Hopefully then you can get the appropriate accordion content.
First bind it like how PHPglue mentioned:
jQuery(this.accordionTrigger).click(this.toggleAccordion);
Then you can do $(this) to get the accordionTitle:
toggleAccordion: function() {
var $accordionTitle = $(this);
}
Basically when you bind it like that and the click is triggered, the scope changes and "this" is no longer "Accordion".
If you need to access accordionContent and accordionTrigger, you can either pass it into the function toggleAccordion or use Accordion.accordionContent and Accordion.accordionTrigger.
Additional source: http://api.jquery.com/click/#click-eventData-handler

Two Html select drop down apply class for span element using Javascript

I am working on HTML select Dropdown. I have two dropdowns one is for font size adjust and other is for text alignment.
When I select the fontsize from the dropdown it has to apply along with text-capitalize (bootstrap css) and If I select the font alignment all three should apply for the span element. For Example.
<div>
<span id="Title"class="text-capitalize">check</span>
</div>
Right now the code was like this
function changeFont_size () {
var select = document.getElementById('font_size');
// Bind onchange event
select.onchange = function() {
document.querySelector("#Title").className = this.value += " text-
capitalize";
};
}
function changeAlignment () {
var select = document.getElementById('text_align');
// Bind onchange event
select.onchange = function() {
document.querySelector("#Title").className = this.value;
};
}
Actually I am newbe on Javascript. Some how I am not getting.
The output result would be the combination of :
<span class="h1 left text-capitalize">Text</span>
Everything should be in pure javascript.
Thanks in advance. Kindly help me.
Here is the Link
This jsfiddle makes your code work. You need to run the code when the document is loaded, so that your onchange functions are being hooked in time.
It does not work exactly like you intended though. Your alignment classes need to be on the parent element and when you select your alignment, you disregard the previously set h1 or h2 class.
window.onload = function() {
var font_size = document.querySelector('#font_size');
// Bind onchange event
font_size.onchange = function() {
document.querySelector("#Title").className = this.options[this.selectedIndex].value += " text-capitalize";
};
var text_align = document.querySelector('#text_align');
// Bind onchange event
text_align.onchange = function() {
document.querySelector("#Title").className = this.options[this.selectedIndex].value;
};
};
You are mixing things up. There are two ways to bind events (well, two ways which are still common even with recent browsers).
The first one is to put a function call in the onsomething property of an element in the html code. Whatever is put there will be executed when the event happens.
<button onclick="alert('hi');">Click me</button>
You should pass the event object to an event handler instead of writing inline code.
<button id="helloworld" onclick="helloworld_onclick(event)">Run</button>
...
function helloworld_onclick(e) {
alert("Hello world!");
}
If you want to be able to bind events dynamically, if you want to bind multiple events to an object and if you want to keep the JavaScript outside of your HTML, the modern way to to so is with addEventListener.
document.querySelector("#helloworld").addEventListener("click", function(e) {
alert("Hello world!");
});
The event object passed (called e in my functions) contains information about what triggered the event and can be used to prevent default behavior and to control event propagation. You can't use "this" in event handlers, but the element which called the handler will be stored in e.target.
In your code, you created functions which, when called, bind events to the elements. Then you bound those functions to the elements with the html attributes.
Finally, you seem to be stuck between querySelector and getElementById. Note that querySelector(All) returns a static node/nodelist while getElement(s)By(...) returns a live node/nodelist. A static node is a copy of all the information about the element. A live node is a reference to the real element. If you modify the element, it modifies the live node, but the static node will keep the old information. You should use getElementById over querySelector for that, and because it runs faster. For code simplicity however, you might prefer always using querySelector. Just don't mix using querySelector("#something") on a line and getElementById("something") on another one, it's the best way to get confused and end up wasting time on a bug because you wrote querySelector("something") or getElementById("#something") instead.
function changeFont_size (element) {
if(element.options[element.selectedIndex].value != 'select'){
document.getElementById('Title').className = element.options[element.selectedIndex].value;
} else{
document.getElementById('Title').className = '' }
}
function changeAlignment (element) {
if(element.options[element.selectedIndex].value != 'select'){
document.getElementById('container').className = element.options[element.selectedIndex].value;
} else{
document.getElementById('container').className = '' }
}
Try this, Hope it will work

jsPlumb: Can't click() on a div inside a div that acts as a jsPlumb source/target

I'm using jsPlumb. My current functionality lets me create a .project div that can then have .task divs inside it. The .project div has 3 clickable buttons which all work using jQuery and the .tasks inside the .project have a single close button which also works.
As can we seen here: http://jsfiddle.net/9yej6/3/
(click the add project button then click on the green project and try to click on the X near some task - an alert should pop up)
However, whenever I try to make the .tasks a makeTarget/makeSource using jsPlumb it surpasses (probably not the best word) any other event done by jQuery. That is when I click on the X icon of the .task it instead acts as if I click on the .task itself and tries to create jsPlumb's bond.
As can be seen here: http://jsfiddle.net/9yej6/4/
So the following line no longer works (note I'm using the on() function since the .project/.task divs are dynamically created):
$("#container").on('click','.task .close',function(e) {
alert('a task`s add was clicked');
});
Initially the addTask() function was (which worked, but you can't add jsPlumb bonds):
function addTask(parentId, index) {
var newState = $('<div>').attr('id', 'state' + index).addClass('task');
var close = $('<div>').addClass('close');
newState.append(close);
var title = $('<div>').addClass('title').text('task ' + index);;
newState.append(title);
$(parentId).append(newState);
}
But when I add the makeTarget()/makeSource() calls to it, it seems to surpass any other jQuery event handling. Where my new addTask() function becomes:
function addTask(parentId, index) {
var newState = $('<div>').attr('id', 'state' + index).addClass('task');
var close = $('<div>').addClass('close');
newState.append(close);
var title = $('<div>').addClass('title').text('task ' + index);;
newState.append(title);
$(parentId).append(newState);
jsPlumb.makeTarget(newState, {
anchor: 'Continuous'
});
jsPlumb.makeSource(newState, {
anchor: 'Continuous'
});
}
You can also use the filter parameter to specify what element to be included for the object drag.
See my complete answer here.
http://jsplumbtoolkit.com/doc/connections.html#sourcefilter
jsPlumb.makeSource("foo", {
filter:":not(a)"
});
Above means, don't interfere with operations related to a (anchor tag).
As mentioned,
$("#container").on('click','.task .close',function(e) {
alert('a task`s add was clicked');
});
This code doesn't work becasue you have made the '.task' element as either target or source part of jsPlumb hence the mouse events will be handled by jsPlumb which prevents the default event handling(jQuery or pure JS) of those elements.
In such case you need to create a small rectangle DIV(refer image) from where the user can drag the connection instead of an entire DIV.

Set time delay between two frames on mouseover

I have to display two images for single mouseover. So when I mouseover to the image, first, the image is displayed then with a time delay of 5000, the image is needed to display for that same hover. Now on mouseout display the original image.
I am not so familiar with JavaScript and jQuery.
Can someone please give me some idea about how to do this.
What i did is,
$('.image1').mouseover(function() {
setInterval($(this).removeClass(.image1).addClass('image-over1'),5000);
$(this).removeClass(.image1).addClass('image-over2');
});
$('.image1').mouseout(function() {
$(this).removeClass('image-over1');
$(this).removeClass('image-over2').addClass(item);
});
$('.image1').click(function(){
document.location='index.php?page='index.php';
})
The .hover() function lets you specify both mouseover/mouseout at the same time, and you need to make a function for the setInterval:
$('.image1').hover(function(evt) {
// mouse over function.
// DOM Element that got the mouseover.
var target = evt.target;
if (target.timer) {
clearTimeout(target.timer);
target.timer = null;
}
target.timer = setInterval(function() {
// $(this) will not work here, since 'this' has changed.
// depending on your css you shouldn't need to remove the '.image1'
// class, just make sure .image-over1 and .image-over2 are
// stronger selectors, or occur after .image1
$('.image1').addClass('image-over2');
// at this point your element will be (just guessing <img>, could be
// anything really:
// <img class="image1 image-over1 image-over2" .../>
// it's absolutely fine for the image to have all those classes as
// long as your css is correct.
}, 5000);
$('.image1').addClass('image-over1');
}, function(evt) {
// mouse out function.
// DOM Element that got the mouseout.
var target = evt.target;
if (target.timer) {
clearTimeout(target.timer);
target.timer = null;
}
$('.image1').removeClass('image-over1');
$('.image1').removeClass('image-over2');
});
$('.image1').click(function(){ document.location='index.php?page='index.php'; })
First of all, I think there's a problem in your approach; if you remove the "image1" class from the element on a mouseover, then that element won't be matched by the $(".image1") selector for the mouseout. Is there a reason you need to remove it? If you do (i.e. if there is something defined on the class in the CSS that you need to disable), is there some other selector you could match on?
As to the time delay, if you're using a jQuery version greater than 1.4, you can use the .delay() function:
$('.image1').mouseover(function() {
$(this).addClass('image-over1').delay(5000).addClass('image-over2');
});
Perhaps you to create an animated GIF of these images??? Then use a code similar to here: http://www.netmechanic.com/news/vol3/design_no10.htm
Even if the images are generated on fly, it is possible to programtically generate animated gif in PHP - see http://php.net/manual/en/function.imagegif.php

Categories

Resources