How do I combine actions on events. So a hover will animate the menu and display the tooltip attached to that menu item.
I am currenlty using the lavalamp and beautytips plugins.
You'll need to explore event listeners vs. event handlers. For example:
// Event handlers are declared like this:
var elm = document.getElementById("someElement");
elm.onmouseover = function() {
elm.innerHTML = "OVER state has been triggered!";
}
Written this way, each element can have one function for an event.
Event listeners let you attach as many functions as you want for an event. They're different scripts in IE and FF, but do the same thing. Using raw javascript, you could attach events like this:
function listenFor(obj,eventName,fcnRef,bubbling) {
if(!bubbling) { bubbling= false; }
if(!obj.addEventListener) { obj.attachEvent("on"+eventName,fcnRef); }
else { obj.addEventListener(eventName,fcnRef,otherthing); }
};
function handler1() {
this.style.border = '2px solid red';
}
function handler2() {
this.style.background = 'green';
}
listenFor(elm,"over",handler1);
listenFor(elm,"over",handler2);
Libraries like JQuery and others have similar ways to do this. A little research and experimentation on this subject should give you more than enough info to animate the menu and display a tooltip simultaneously on the same element.
Related
I am following this tutorial to build a store locator page with a Mapbox map.
I don't want to add custom markers because I already have custom map labels (symbols?), which means I don't need the optional last section of the tutorial and stop right after Add Event Listeners.
Once this is completed, the page should react to clicks in the side panel list, as well as on the map (2 event listeners). However, in the demo provided in the tutorial for that particular step, you can tell the code for the second event listener, the one making the map clickable, is not functioning, which makes me believe there is a mistake in the provided code:
// Add an event listener for when a user clicks on the map
map.on('click', function(e) {
// Query all the rendered points in the view
var features = map.queryRenderedFeatures(e.point, { layers: ['locations'] });
if (features.length) {
var clickedPoint = features[0];
// 1. Fly to the point
flyToStore(clickedPoint);
// 2. Close all other popups and display popup for clicked store
createPopUp(clickedPoint);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
// Find the index of the store.features that corresponds to the clickedPoint that fired the event listener
var selectedFeature = clickedPoint.properties.address;
for (var i = 0; i < stores.features.length; i++) {
if (stores.features[i].properties.address === selectedFeature) {
selectedFeatureIndex = i;
}
}
// Select the correct list item using the found index and add the active class
var listing = document.getElementById('listing-' + selectedFeatureIndex);
listing.classList.add('active');
}
});
Would anyone be able to tell what is wrong with this code?
Turns out the code is incomplete in that the cursor doesn't change to a pointer as you hover over a map label/marker so it doesn't clue you into realising you can click on it, hence my assumption it wasn't working at all. I assume the general users who would then face the map would be equally deceived unless the pointer shows up. So in the tutorial, if you do go ahead and click the marker, it will have the expected behaviour and display the popup, although no pointer is shown.
Here is how to create the pointer, based on this fiddle: https://jsfiddle.net/Twalsh88/5j70wm8n/25/
map.on('mouseenter', 'locations', function(e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'locations', function() {
map.getCanvas().style.cursor = '';
});
I want add eventListener highlight buttonLockup with stackTemplate.
Can you guide to use this?
Thanks,
The event system in TVJS is extremely similar to that in a web browser. After all, it's just JS and a DOM. MDN's documentation on Event Handlers should be mostly relevant
To add an event listener to a specific button, just find that button (using ID or name or whatever), and use addEventListener.
var myButton = doc.getElementByName('buttonLockup')
var onSelect = function(ev) {
console.log('Button selected!')
}
myButton.addEventListener('select', onSelect)
However, depending on your use case, I've found Apple's approach in their sample apps to be quite useful. They rely on the fact that events bubble up to the root of the template, and just listen to them there. So for example:
// Given a TVML document has been presented with this somewhere in it
<buttonLockup action="doSomething">Do something</buttonLockup>
// When it's selected, doSomething
var globalOnSelect = function(ev) {
var target = ev.target;
var action = target.getAttribute('action')
if (action === 'doSomething') {
console.log('Do Something button selected');
doSomething();
}
}
doc.addEventListener('select', globalOnSelect);
I have multiple MovieClip Symbols published with Flash into FlashDevelop (I'll only use 2 in my example). Each have 3 frames for default, hover and click that I'm using as buttons.
private var btnPlay:PlayButton, btnQuit:QuitButton;
btnPlay = new PlayButton();
btnQuit = new QuitButton();
btnPlay.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler);
btnPlay.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler);
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler);
btnPlay.addEventListener(MouseEvent.MOUSE_UP, onReleaseHandler);
btnPlay.buttonMode = true;
btnPlay.useHandCursor = true;
function onRollOverHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(2);
}
function onRollOutHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(1);
}
function onPressHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(3);
}
function onReleaseHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(2);
}
// Same code for btnQuit here, but replace btnPlay with btnQuit
Instead of adding new EventListeners to every button that do practically the same thing like what I'm doing above, is there a way I could just pass in the button itself to the MouseEvent functions something like this? (I realize this might be difficult since all buttons are their own class)
btnPlay.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.MOUSE_UP, onReleaseHandler(btnPlay));
function onRollOverHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(2);
}
function onRollOutHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(1);
}
function onPressHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(3);
}
function onReleaseHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(2);
}
Maybe I am misunderstanding, but "event.target" provides you a reference to the button that has been clicked. So if you want to do something to the clicked button, you would write:
myEvent.target.gotoAndStop(1);
Or sometimes you might need to use "currentTarget". You'd still need to create listeners for each function but could use one set of handlers.
Simple answer: No. You could go to some trouble to override the MouseEvent class and allow it to send additional parameters, but why bother in this case? You don't seem to be saving any code.
SLIGHT UPDATE:
Here's a possibly-useful simplification of your original code. It saves a few lines-of-code and uses just a single handler function. Obviously, the 'trace' statements could be replaced by various 'gotoAndStop()' statements:
btnPlay.addEventListener(MouseEvent.ROLL_OVER, HandleAll);
btnPlay.addEventListener(MouseEvent.ROLL_OUT, HandleAll);
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, HandleAll);
btnPlay.addEventListener(MouseEvent.MOUSE_UP, HandleAll);
function HandleAll(e)
{
if (e.type == "rollOver") trace("rollover");
if (e.type == "rollOut") trace("rollout");
if (e.type == "mouseDown") trace("mousedown");
if (e.type == "mouseUp") trace("mouseup");
}
Trying to change the cursor
I am trying to make a draggable scrollable image and as such am trying to change the cursor over an image when a variable is set to zoom mode so I can have good usability. What I am finding is that the cursor only changes once I have clicked the ".page" and THEN moved the mouse not just as I click the page as it should. Here is some example code:
$(".page").on("mousedown", function (evt) {
if(model.zoomMode){
$('.page').css('cursor','url("img/hand_closed.gif"),auto');
}
}).on("mouseup", function (evt) {
if(model.zoomMode){
$('.page').css('cursor','url("img/hand_open.gif"),auto');
}
});
Another approach relying more on CSS
This seems to happen when I use classes to achieve the same effect as well. ie. zoom mode adds a class outside of the .page object and then the javascript is:
$(".page").on("mousedown", function (evt) {
$('.page').addClass('mouseDown');
}).on("mouseup", function (evt) {
$('.page').removeClass('mouseDown');
});
Then in the CSS:
.zoom .page:hover{
cursor:url(../img/hand_open.gif),auto;
}
.zoom .page.mouseDown:hover{
cursor:url(../img/hand_closed.gif),auto;
}
I am using chrome 18 to test. Anyone know a way to trigger the CSS cursor being applied without moving the mouse?
Short answer: No.
Long answer: Nope, sorry.
(source)
I am trying to cancel a tooltip event (I only want it to display when the mouse is hovered over a certain area), and can't seem to figure it out. I tried stopPropagation, preventDefault, and stopImmediatePropagation, but none of them seem to work.
Here the code I am using:
private function toolTipCreateHandler(event:ToolTipEvent):void {
if(event.currentTarget.mouseX < 130) {
var tooltip:PhotoToolTip = new PhotoToolTip();
tooltip.src = event.currentTarget.toolTip;
event.toolTip = tooltip;
}
else {
event.stopImmediatePropagation();
}
}
Any ideas?
Thanks
Step one, add an event listener to detect when the mouse leaves the area you want the tooltip, run a function and title it something like "toolTipDestroyer"
Step two, You need to call the destroy method of the tooltip manager
private function toolTipDestroyer():void {
if (myToolTip) {
ToolTipManager.destroyToolTip(myToolTip);
myToolTip= null;
}
}
Also, just for readability, give your tooltip some other name than "tooltip", you'll find it easier to follow up on your code later. My example names it "myToolTip"