Impress.js + Firefox: How to disable advance slide on mouse click - javascript

Impress.js works great in Chrome, but unfortunately, it's somewhat buggy in Firefox. The biggest problem that I am having is that, in Firefox, the slideshow advances to the next slide on every mouse click. Does anybody know of a way to disable this functionality?

Go to js/impress.js, delete the code below (about line 783~797) , it listen the click event:
// Delegated handler for clicking on step elements
document.addEventListener( "click", function( event ) {
var target = event.target;
// Find closest step element that is not active
while ( !( target.classList.contains( "step" ) &&
!target.classList.contains( "active" ) ) &&
( target !== document.documentElement ) ) {
target = target.parentNode;
}
if ( api.goto( target ) ) {
event.preventDefault();
}
}, false );

Related

Autocomplete: How to focus on first item after pressing arrow down key on last item?

Go through each option of the dropdown by using arrow down key. When focusing on the last option, and pressing arrow down key the cursor move to textbox instead of the first option. How make the cursor go to the first option?
You can use below code block to fix that issue.
.autocomplete('instance')._move = function( direction, event ) {
if ( !this.menu.element.is( ":visible" ) ) {
this.search( null, event );
return;
}
if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
this.menu.isLastItem() && /^next/.test( direction ) ) {
if ( !this.isMultiLine ) {
this._value( this.term );
}
this.menu[ direction ]( event );
// this.menu.blur();
return;
}
this.menu[ direction ]( event );
}

Hide an element when a user clicks outside of it

$( document ).on('click', '.toggle_comments', function( event ){
event.preventDefault();
var container = $('div[name="comments"]');
if ( container.css('display') == 'block' ) {
container.hide();
return;
}
container.fadeIn(500);
});
When .toggle_comments is clicked, the container fades in. Is there a way to do something, ie fadeout, if anything outside the container is clicked WHILE it's display block? Bearing in mind, obviously, that .toggle_comments is outside of it in the first place. So it needs to be a live event, something that only fires while the container is in the state if display:block.
You can bind a mousedown event to document and check if the element clicked on is not div[name="comments"] like so:
$(document).mousedown(function(event)
{
var commentSection = $('div[name="comments"]');
if(!$(commentSection).is($(event.target)) && !$(event.target).closest($(commentSection)).length)
$(commentSection).fadeOut();
});
Just do different things if different elements are clicked
$( document ).on('click', function( event ){
event.preventDefault();
var target = $(event.target);
var container = $('div[name="comments"]');
if ( target.closest('.toggle_comments').length > 0 ) {
if ( container.is(':visible') ) {
container.hide();
} else {
container.fadeIn(500);
}
} else if (target.closest(container).length === 0 && container.is(':visible')) {
container.fadeOut(500);
}
});
FIDDLE

Unwanted Multiple Calls

The code I am working on displays some messages on different pages.
page is the page number.
ActionGetMessages is an ajax request.
PushMessage just manage the content.
Here is the code:
function ShowMessages ( page ) {
var oMessages = ActionGetMessages ( page );
for ( var key in oMessages ) {
if ( key == "end" ) continue;
PushMessage ( oMessages [key] );
}
var previous_page_button = document.getElementById ( "previous_page_button");
var next_page_button = document.getElementById ( "next_page_button" );
if ( page > 0 ) {
previous_page_button.style.display = "block";
previous_page_button.addEventListener ( "click",
function () {
ShowMessages ( page - 1 );
} );
}
if ( !oMessages ["end"] ) {
next_page_button.style.display = "block";
next_page_button.addEventListener ( "click",
function () {
ShowMessages ( page + 1 );
} );
}
}
Debugging this code I noticed that after the user have navigated back and forth the pages some times clicking (for example) the next page button cause multiple calls to ShowMessages or something like that.
Any help would be really appreciated.
It's not totally clear to me what you're doing with the above code but what you describe seems to me like there are some event listeners attached multiple times that you don't want to have.
In fact when you click a button which calls ShowMessages() it will attach another event listener to the button everytime the button is clicked. So before you attach the event, try to remove the existing listener first. Have a look at:
removeEventListener
if you make sure that there are no events attached to the button before you add your event listener it should work and have the code executed just one time.
Keep in mind, that you will need to have a reference to your listener to remove it. You can do it like this:
//Define this listener globally (anywhere outside your function)
// so you can reference it anytime or keep track of the last
// added listener somewhere. Otherwise you won't be able to
// remove it.
var myPreviousPageListener = function () {
ShowMessages ( page - 1 );
}
previous_page_button.removeEventListener("click", myPreviousPageListener);
previous_page_button.addEventListener ( "click", myPreviousPageListener);

How to force the focus on a modal box on a web page

TL;DR;
Is there a way to force the focus to be inside a modal box in a web page ?
Here's the problem: I have a classic web page, containing text, links and forms. When I click one specific link in the page, a modal box appear (something similar to fancybox or jQuery.ui.dialog). This modal contains also links and form elements. If the user use its "tab" key, he can focus every element on the page, elements which are inside the modal, but also elements which are outside it. I would like to force the focus to say inside the modal box, but I can't find a way to do it. I would like to do this in CSS or JavaScript if possible.
I know this is possible, because jQuery.ui.dialog can do it using the modal option, here's an example http://jsfiddle.net/pomeh/QjLJk/1/show/. I tried to look at the source code but I'm not figuring how it works precisely. Here's some code I found in the jQuery UI source code which sounds like resolving this issue:
this.document.bind( "focusin.dialog", function( event ) {
if ( !that._allowInteraction( event ) ) {
event.preventDefault();
$(".ui-dialog:visible:last .ui-dialog-content")
.data( widgetFullName )._focusTabbable();
}
});
_allowInteraction: function( event ) {
if ( $( event.target ).closest(".ui-dialog").length ) {
return true;
}
// TODO: Remove hack when datepicker implements
// the .ui-front logic (#8989)
return !!$( event.target ).closest(".ui-datepicker").length;
},
_focusTabbable: function() {
// Set focus to the first match:
// 1. First element inside the dialog matching [autofocus]
// 2. Tabbable element inside the content element
// 3. Tabbable element inside the buttonpane
// 4. The close button
// 5. The dialog itself
var hasFocus = this.element.find("[autofocus]");
if ( !hasFocus.length ) {
hasFocus = this.element.find(":tabbable");
}
if ( !hasFocus.length ) {
hasFocus = this.uiDialogButtonPane.find(":tabbable");
}
if ( !hasFocus.length ) {
hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
}
if ( !hasFocus.length ) {
hasFocus = this.uiDialog;
}
hasFocus.eq( 0 ).focus();
}
keydown: function( event ) {
if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
event.keyCode === $.ui.keyCode.ESCAPE ) {
event.preventDefault();
this.close( event );
return;
}
// prevent tabbing out of dialogs
if ( event.keyCode !== $.ui.keyCode.TAB ) {
return;
}
var tabbables = this.uiDialog.find(":tabbable"),
first = tabbables.filter(":first"),
last = tabbables.filter(":last");
if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
first.focus( 1 );
event.preventDefault();
} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
last.focus( 1 );
event.preventDefault();
}
}
I wont get into the coding as you already have the code, I'll explain you the logic behind it.
If your page has the following elements,
element0(tabindex 1) --> element1(tabindex 2) --> element2(tabindex 3)
To prevent focus going out, you basically create a cycle.
When tab key is pressed on element0, it goes to element1 as it would normally go.
But when the tab key is pressed on element2, you need to prevent the browser's default behaviour (by event.preventDefault()) i.e going to an element with a higher tabindex and give focus to the element0.
Same ways when shift+ tab is pressed on element0, you need to prevent the browser's default behaviour (event.preventDefault()) and manually give focus to element2.
In this way, you create a cycle such that focus never goes outside.

mousemove and cross-browser e.which

I need to know which mouse key is pressed on every mousemove event, and I try to use this:
getMouseCode: function(e) {
e = e || window.event;
if (!e.which && e.button) {
if (e.button & 1) e.which = 1;
else if (e.button & 4) e.which = 2;
else if (e.button & 2) e.which = 3;
};
return e.which;
},
But this is works only in chrome and IE7-8. IE9 debugger always says e.button == 0 and e.which == 1. After some debugging I figured out that window.event for IE9 contains right value of which, so I swapped
e = window.event || e;
This also does the trick for Safari & Air, but Firefox has window.event undefined, and Opera has the same wrong values in both callback argument and window.event objects.
I was looking at this question when investigating a related issue. It turned out that my issue was that I needed to use separate functions to handle onclick and onmouseover events.
I have found that when using Opera, Safari and FireFox, the "which" property of the mousemove event object is set to 1 when no mouse button has been clicked.
Though this answer may be kind of late, I am sure it will help those in the future. I stumbled upon this question while searching for this cross browser feature and originally disregarded it. I am back to provide my answer for those that follow in my footsteps.
First, some knowledge. I found this site very helpful, as all the cross browser issues (well most) are worked out, and laid out for your amusement (I laugh when us developers need to create charts and diagrams to how browsers work..)
http://unixpapa.com/js/mouse.html
On this page, near the bottom, you will find a blue link that says "Click here with various mouse buttons to test", above this you will see a code snippet. This goes into your mousedown or mouseup. If you right click and view the source at this location, you will find a script tag that holds 2 functions, the one above this link, and a 'dont' function that prevents the events from doing their default, or falling through, though not needed in all cases, is useful to know about.
The second piece of knowledge comes from another website, and provides us some insight into how to capture the mouse wheel up and down events.
http://www.javascriptkit.com/javatutors/onmousewheel.shtml
To put this all together in 1 place, we basically have the following..
function GetMouseButton(e) {
// Normalize event variable
var e = window.event || e;
// Set button to initially not recognized (or false if you need to to be)
var button = 'Not Recognized';
// Check if this is a button push event
if(e.type == 'mousedown' || e.type == 'mouseup') {
if (e.which == null) {
// Check if IE, if so, what e.button was pressed
button = (e.button < 2) ? "Left" :
((e.button == 4) ? "Middle" : "Right");
} else {
// All other browsers, what e.which was pressed
button = (e.which < 2) ? "Left" :
((e.which == 2) ? "Middle" : "Right");
}
} else {
// If this is not a button push event, then we get the direction
var direction = e.detail ? e.detail * (-120) : e.wheelDelta;
// And name the direction as a 'button'
switch(direction) {
case 120: // Browsers use different variants of these
case 240:
case 360:
button = "Middle Scroll Up";
break;
case -120:
case -240:
case -360:
button = "Middle Scroll Down";
break;
}
}
alert(button);
}
/* Simple Bind function (like jQuery's for example) */
function Bind(elem, type, eventHandle) {
if (elem == null || elem == undefined) return;
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
} else {
elem["on"+type]=eventHandle;
}
}
/* Bind your mousedown / mouseup to the window, as well as the mousewheel */
Bind(window, 'mousedown', GetMouseButton);
Bind(window, 'mouseup', GetMouseButton);
/* One of FireFox's browser versions doesn't recognize mousewheel,
* we account for that in this line
*/
var MouseWheelEvent =
(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel";
Bind(window, MouseWheelEvent, GetMouseButton);
To save you some time [and knowledge, if you don't care to look at these links], you can view a working example at the following jsfiddle:
http://jsfiddle.net/BNefn/
EDIT
I should have also said, that since you need to know this on every mousemove event, you can simply store the resulting button 'name' and event type (down or up), and then recall that variables information during your mousemove event. If you have a variable for each of these "buttons" you can then see which button is pressed and which isn't, and clear the variables that are pressed on mouseup.

Categories