passing what my mouse over is to function - javascript - javascript

I'm new to javascript so i'm not exactly sure how I can do this. Basically, in my website I have a kind of tooltip, that displays when hovering over certain input boxes.
This is my javascript:
function showTip () {
firstnameTip.style.display = "inline";
}
function hideTip () {
firstnameTip.style.display = "none";
}
/* link HTML elements to corresponding event function */
function init () {
/* link the variables to the HTML elements */
firstnameTip = document.getElementById("firstnameTip");
firstname = document.getElementById("firstname");
/* assigns functions to corresponding events */
firstname.onmouseover = showTip; /* for mouse */
firstname.onmouseout = hideTip;
firstname.onfocus = showTip; /* for cursor on input field */
firstname.onblur = hideTip; /* for cursor moving out */
}
/* execute the initialisation function once the window*/
window.onload = init;
Basically the functionality i would like is to if i hover over "firstname", it displays the firstnameTip, and so on for other things like lastname (lastnameTip), etc.
Simple question but I've tried many things and can't figure it out. Anyone have any ideas? Thanks.

Here's how I'd set it up:
function showTip (tipElement) {
return function () {
tipElement.style.display = "inline";
};
}
function hideTip (element, tipElement) {
return function () {
if (document.activeElement !== element) {
tipElement.style.display = "none";
}
};
}
function init() {
initTipEvents("firstname", "firstnameTip");
initTipEvents("lastname", "lastnameTip");
}
function initTipEvents(elementId, tipId) {
var el = document.getElementById(elementId),
tip = document.getElementById(tipId),
showHandler = showTip(tip),
hideHandler = hideTip(el, tip);
el.onmouseover = showHandler;
el.onfocus = showHandler;
el.onmouseout = hideHandler;
el.onblur = hideHandler;
}
window.onload = init;
DEMO: http://jsfiddle.net/LX2Cb/
The initTipEvents binds all necessary events, based on an element's id and its tip's id, reusing the modified showTip and hideTip functions. I added an extra check to the hideTip function to make sure that the tip isn't hidden when the mouse leaves the input, yet its still focused.

And whats the problem? Works like a charm:
var firstnameTip;
var firstname;
function showTip () {
firstnameTip.style.display = "inline";
}
function hideTip () {
firstnameTip.style.display = "none";
}
/* link HTML elements to corresponding event function */
function init () {
/* link the variables to the HTML elements */
firstnameTip = document.getElementById("firstnameTip");
firstname = document.getElementById("firstname");
/* assigns functions to corresponding events */
firstname.onmouseover = showTip; /* for mouse */
firstname.onmouseout = hideTip;
firstname.onfocus = showTip; /* for cursor on input field */
firstname.onblur = hideTip; /* for cursor moving out */
}
/* execute the initialisation function once the window*/
init();
http://jsfiddle.net/6QvXT/

ok, to have that more generic, you should use the event parameter passed to the handler and the retrieve the target object out of that like:
var getTarget = function (event)
{
var ttn = null;
if (!event)
event = window.event;
else if (event.target)
ttn = event.target;
else if (event.srcElement)
ttn = event.srcElement;
var tipId = ttn.id + "Tip";
ttn = document.getElementById(tipId);
return ttn;
}
and then:
function showTip (evt) {
var ttn = getTarget(evt);
ttn.style.display = "inline";
}
function hideTip (evt) {
var ttn = getTarget(evt);
ttn.style.display = "none";
}
furthermore:
function init () {
/* for all relevant elements */
for ( .... ) // iterate through a list or the dom
{
var theElement = ....(); // get the element
/* assigns functions to corresponding events */
theElement.onmouseover = showTip; /* for mouse */
theElement.onmouseout = hideTip;
theElement.onfocus = showTip; /* for cursor on input field */
theElement.onblur = hideTip; /* for cursor moving out */
}
}
/* execute the initialisation function once the window*/
init();
hope that helps.

Related

Multiple buttons for same function with if statement

I've tried to make my own case function, but I cannot get it to "show stuff" once I've hidden them on first click. So my question is what am I doing wrong, how can I solve it, and how should I've done it instead?
My only requirement is that multiple buttons can use the same code to show/hide the same object – hence things like oddClick won't work since that'll require unnecessary clicks to get even/odd again (I think?).
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
var state = 1;
if(state == 0) { // I think we are trying to compare value here.
/* alert("foo"); */
var state = 1;
console.log(state);
/*show stuff here*/
}
else {
/* alert("bar"); */
var state = 0;
console.log(state);
/*hide stuff here*/
}
});
this line 5: var state = 1; causes it to always go into "else
var state = 1; //placed on global scope
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
//var state = 1; removed from function scope
if(state == 0) {
/* alert("foo"); */
state = 1;
console.log(state);
/*show stuff here*/
}
else {
/* alert("bar"); */
state = 0;
console.log(state);
/*hide stuff here*/
}
});
Fiddle: http://jsfiddle.net/8ubk5c0f/
For detecting the state of your object, you should use the object properties (instead of a parallel state variable).
Using the value of boxwidth for instance.
In more simple way:
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width(); //Not sure why you want this
console.log(boxwidth);
console.log('-'+boxwidth+'px');
var btnVal=$(this).text(); //get the button text
if(btnVal=="Show Stuff") //if it is show stuff
{
$(this).text('Hide Stuff'); //change its text
alert('stuff shown');
/*show stuff here*/ //do the functionality
}
else {
$(this).text('Show Stuff'); //change back to normal
alert('stuff hidden');
/*hide stuff here*/ //hide functionality
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="boxbtn">Show Stuff</button>
Declare state variable outside click function.
var state = 1; // Do not write inside click function scope
var state = 0; //placed on global scope
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
if(state == 0) {
state=1;
console.log(state);
}
else {
state = 0;
console.log(state);
}
});

How to click on a map area only once?

I'm creating a medical assessment and there is this page where you can select the body parts which are in pain. Once you click on a body part, the name of it will be displayed below. The problem is it will display multiple times when clicked repeatedly. Is there a way to block the click event from repeating?
Here is the sample.
http://jsfiddle.net/qpmxnv2g/6/
var map = document.getElementById("Map");
map.addEventListener("click", function (e) {
callAction(e.target);
});
map.one("click", function (e) {
callAction(e.target);
});
var body = [];
document.getElementById("body").innerHTML = body;
function callAction(area) {
body.push(area.title);
document.getElementById("body").value = body;
}
document.getElementById("Clear").addEventListener('click', function () {
body.length = 0;
document.getElementById("body").value = '';
});
change your function like this:-
function callAction(area) {
if (body.indexOf(area.title) !== -1) { return; }
body.push(area.title);
document.getElementById("body").value = body;
}
Demo

JS Event Disabler: Can't stop native eventlisteners from executing

I am implementing a JS Event-Disabler class, to disable all Native and Programmable eventlisteners of a certain dom element and all its children.
So far I've been able to disable all JQuery events and the default browser events, but not the eventlisteners set like
document.getElementById('cin').addEventListener("click", function(){
alert('I should not alert when disabled');
});
So clicking on the element ('native element') shouldn't alert, but it does.
How do I stop that from happening, within my nothing function.
If there is away to not even need to call another function but just disable all events then that would also be fine, but need to be able to re-enable all again.
Also, I can assure you that the nothing() function executes first.
var tellme = function(who) {
//console.info('Event by: '+who+' #'+Date.now());
alert('Event by: ' + who + ' #' + Date.now());
}
$(window).load(function() {
/* SOME FUNCTION TO ENSURE OUR FUNCTIONS ARE THE FIRST TO BE CALLED */
$.fn.bindFirst = function(name, fn) {
this.on(name, fn);
this.each(function() {
var handlers = $._data(this, 'events');
for (var key in handlers) {
if (handlers.hasOwnProperty(key)) {
var listeners = handlers[key];
if (listeners.length > 1) {
var lastEvent = listeners.pop();
listeners.splice(0, 0, lastEvent);
if (listeners[1].handler.name === lastEvent.handler.name)
listeners.splice(1, 1);
}
}
}
});
};
function shouldbenothing() {
tellme('native catcher');
nothing();
}
/* THE DO NOTHING FUNCTION, NEEDS SOMETHING MORE, DOESN'T CANCEL ALL*/
function nothing() {
event.cancel = true;
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
//Needed for Jquery
throw new Error("NOT AN ERROR: Just forcefully stopping further events #" /*+Date.now()*/ ); //Add the Date.now to see that this code does run before the native function.
return false;
}
/* THIS WILL ONLY RETURN NON-NATIVE EVENTS, ONLY PROGRAMMED EVENTS*/
function getAllActiveEvents(element) {
var result = [];
var handlers = $._data(element, 'events');
for (var key in handlers) {
if (handlers.hasOwnProperty(key)) {
result.push(key);
}
}
return result.join(' ');
}
function getAllEvents(element) {
var result = [];
for (var key in element) {
if (key.indexOf('on') === 0) {
result.push(key.slice(2));
}
}
return result.join(' ');
}
/*SOME PROGRAMMED EVENTS, BESIDES THE NATIVE ONES*/
$('input').on('keyup', function() {
$('#text').html(this.value);
});
$('p').on('click', function() {
$('#text').html(this.innerHTML);
tellme('jquery');
});
document.getElementById('jsE').addEventListener("click", function() {
tellme('p:js');
});
document.getElementById('cin').addEventListener("click", function() {
tellme('input:js');
});
/* THE ACTUAL DISABLER CODE */
/*TOGGLE TO ACTIVE OR DISABLE EVENTS FROM TAKING PLACE NATIVE AND EXTRA*/
var isOn = false;
$('button').on('click', function() {
if (isOn)
$("#obj *").each(function() {
$(this).off(getAllEvents($(this)[0]), "", nothing);
$("#obj").css('pointerEvents','');
});
else {
$("#obj *").each(function() {
var elem = $(this)[0];
var events1 = getAllActiveEvents(elem); //Only programmed listeners
var events2 = getAllEvents(elem); //Native + other listeners
$(this).bindFirst(events2, nothing);
});
$("#obj").css('pointerEvents','none');
}
isOn = !isOn;
this.innerHTML = isOn;
});
});
p {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<style>p {pointer:hand;}</style>
<div id="obj">
<p>jquery event</p>
<p id="jsE">js event</p>
<p onclick="tellme('native');">native event</p>
<input id='cin' type="text" />
<p id="text">3</p>
</div>
<p>not catched</p>
<input type="text">
<button>toggle</button>
There might be a very simple, non-js, pure css-solution ... like this:
.whatever {
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
pointer-events:none;
}
... just add the whatever-class to any elements you want to disable completely from user-interaction.
So I found a solution shortly after.
By playing with the css code, I could disable all the relevant mouse events. This however doesn't stop the native events, say if you were to trigger the event via JS, but at least it stops it from user's point.
I actually also like the css method better, as it does allow me to still interact and trigger events, for instance when I want to show the user something without having the user interfere.
The css code:
//To Disable
$("#obj").css('pointerEvents','none');
//To Enable
$("#obj").css('pointerEvents','');
For anyone looking for the full Working Code: Here it is.
Make sure you add the css.
/* Event Disabler, disables all events */
/* How to use:
* Toggle Events: toggleEvents(selector);
* Disable all Events: toggleEvents('body',true);
* Enable all Events: toggleEvents('body',false);
*/
var toggleEvents = null;
$(window).load(function(){
/* SOME FUNCTION TO ENSURE OUR FUNCTIONS ARE THE FIRST TO BE CALLED */
$.fn.bindFirst = function(name, fn) {
this.on(name, fn);
this.each(function() {
var handlers = $._data(this, 'events');
for (var key in handlers) {
if (handlers.hasOwnProperty(key)) {
var listners = handlers[key];
if (listners.length > 1) {
var lastEvent = listners.pop();
listners.splice(0, 0, lastEvent);
//Removes duplicate eventListners
if (listners[1].handler.name === lastEvent.handler.name)
listners.splice(1, 1);
}
}
}
});
};
/* THE DO NOTHING FUNTION CANCELS ALL EVENTS, EVEN BY TRIGGERED*/
function nothing() {
event.cancel = true;
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
event.bubbles = false;
if(window.event){
window.event.cancelBubble=true;
}
//throw new Error("NOT AN ERROR: Forcefully stopping further events");
return false;
}
function getAllActiveEvents(element) {
var result = [];
var handlers = $._data(element, 'events');
for (var key in handlers) {
if (handlers.hasOwnProperty(key)) {
result.push(key);
}
}
return result.join(' ');
}
function getAllEvents(element) {
var result = [];
for (var key in element) {
if (key.indexOf('on') === 0) {
result.push(key.slice(2));
}
}
return result.join(' ');
}
var enabled = false;
toggleEvents = function(selector,flag) {
enabled = flag === undefined ? !enabled : flag;
if (enabled) {
$(selector+" *").each(function(){
//Only programmed and attached listners
var events1 = getAllActiveEvents($(this)[0]);
//All Native events attached or not
var events2 = getAllEvents($(this)[0]);
$(this).bindFirst(events2, nothing );
});
//Disabled most user pointer events
$(selector).addClass('eventsDisabled');
} else {
$(selector+" *").each(function() {
$(this).off(getAllEvents($(this)[0]), "", nothing );
});
$(selector).removeClass('eventsDisabled');
}
};
});
.eventsDisabled {
-webkit-user-select:none !important;
-moz-user-select:none !important;
-ms-user-select:none !important;
user-select:none !important;
pointer-events:none !important;
}

Change variable based on which element is clicked

It is possible to change variable inside function which is based on element is user clicks?
In my case this will fully work for one kind of menu but I need two fully identical menu
with one difference -
second click handler must load toggleDrawer with changed $sidebar to $navbar variable.
/*
Variables
*/
var $sidebar = $('#sidebar'),
$navbar = $('#navbar'),
drawerOpen = false,
/*
Functions
*/
closeDrawer = function() {
drawerOpen = false;
$body.css('overflow','').removeClass('sidebar-open');
$sidebar.removeClass('open');
$sidebar.animate({'right':'-50%'},{duration:300});
$(this).hide();
},
openDrawer = function() {
drawerOpen = true;
$body.addClass('sidebar-open').css('overflow','hidden');
$sidebar.addClass('open');
$sidebar.animate({'right':'0%'},{duration:300});
},
toggleDrawer = function() {
if (drawerOpen) {
closeDrawer();
}else{
openDrawer();
}
},
/*
Bind Events
*/
$document.on('click', '.drawer-toggle-sidebar', function(event){
toggleDrawer();
event.preventDefault();
});
$document.on('click', '.drawer-toggle-navbar', function(event){
toggleDrawer();
event.preventDefault();
});
To elaborate on the above comment, and show an example:
Here are your functions with passing in the element you wish to open/close:
/*
Functions
*/
closeDrawer = function(drawer) {
drawerOpen = false;
$body.css('overflow','').removeClass('sidebar-open');
drawer.removeClass('open');
drawer.animate({'right':'-50%'},{duration:300});
$(this).hide();
},
openDrawer = function(drawer) {
drawerOpen = true;
$body.addClass('sidebar-open').css('overflow','hidden');
drawer.addClass('open');
drawer.animate({'right':'0%'},{duration:300});
},
toggleDrawer = function(drawer) {
if (drawerOpen) {
closeDrawer(drawer);
}else{
openDrawer(drawer);
}
},
And your bind events:
/*
Bind Events
*/
$document.on('click', '.drawer-toggle-sidebar', function(event){
toggleDrawer(event.currentTarget);
event.preventDefault();
});
$document.on('click', '.drawer-toggle-navbar', function(event){
toggleDrawer(event.currentTarget);
event.preventDefault();
});
You could even combine the two on click events into one and just pass in the currentTarget.
I hope this helps.

Copy/Paste element with jQuery

I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});

Categories

Resources