classList.toggle doesn't work in Firefox - javascript

I have noticed that toggling class in Firefox is not working and I'm not sure why.
var contactUs = document.querySelectorAll('.contact-us')[0];
var buttonExpand = document.querySelectorAll('a.write')[0];
buttonExpand.addEventListener('click', function(e) {
contactUs.classList.toggle('js-expand-form');
console.log('click');
},false);
When I click on a.write in Firefox nothing happens. It works on Chrome and IE.
The problem is related both to event binding and to classList.toggle, because console.log('click') doesn't work in FF and when I type manually from console:
document.querySelectorAll('.contact-us')[0].classList.toggle('js-expand-form')
it returns true or false but nothing actually changes - inspected element doesn't get a new class. What concerns me even more is that the same line pasted in Chrome's console doesn't take effect either, despite the fact it works in normal circumstances.
jQuery's equivalent jQuery('.contact-us').toggleClass('js-expand-form') works in every browser, including pasting into console.
See the fiddle.

You change the class on link (a.write). I'd guess that the link fires, page reloads and changes are flushed away.
Try to add
e.preventDefault();
in the handler after the toggle() command.

Mystery solved. The problem was caused by including code in window.onload:
window.onload = function() {
var buttonExpand = document.querySelectorAll('a.write')[0];
buttonExpand.addEventListener('click', function(e) {
console.log('click');
},false);
}
It started to work in Firefox after moving it elsewhere:
var buttonExpand = document.querySelectorAll('a.write')[0];
buttonExpand.addEventListener('click', function(e) {
console.log('click');
},false);
window.onload = function() {
}
Not sure why Firefox had problem with that, though.

Related

jQuery click does not fire consistently

I have an issue regarding the jQuery click event. The first time the page get loaded it does not work. After a refresh it works fine. I assume it has to do with the browser caching the files somehow.
This is the code:
$(window).ready(
function() {
$("#language-input").click(function() {
$("#language-dropdown").show();
});
Any ideas what I am missing?
Instead of
$("#language-input").click(function() {
You can use
$("#language-input").on('click', function() {.
This will ensure that the click event is fired even if the element is loaded dynamically.
You final code would be without $(window).ready(function() { :
$("#language-input").on('click', function() {
$("#language-dropdown").show();
});
The solution, which was mentioned in one of the comments, was to use:
$(document).on("click", "#element", function()
This seemed to work for dynamically added elements.

Safari doesn't correctly change active element on focus

I have a tooltip which depends on becoming the active element when clicked, so that on blur it can hide.
In a decent browser like Chrome a <button> becomes the active element when clicked. In FF and Safari it doesn't (they don't even call focus on the element!).
So I switched to an <a>, but even that is still broken in Safari.
Here is a demo of the issue, try in Chrome and then Safari:
document.querySelector('a').addEventListener('click', () => {
echoActiveEl();
});
function echoActiveEl() {
document.querySelector('.active-el-tag').innerHTML = document.activeElement.tagName.toLowerCase();
}
echoActiveEl();
Click me
<p>Active element: <span class="active-el-tag"></span></p>
How can I make Safari behave properly and call focus on the element so it becomes the activeElement? Doing element.focus() does nothing! Thanks.
Edit: e.currentTarget.focus() does actually work, e.target was pointing to a span I had in my <a>.
As far as manually putting focus is concerned i think it's an ES 6 support issue , try traditional syntax instead
document.querySelector('a').addEventListener('click', function(e) {
//e.preventDefault();
this.focus();
document.querySelector('.active-el-tag').innerHTML = document.activeElement.tagName.toLowerCase();
});
Since you need the onBlur event, you can archive what you want with something like this:
document.querySelector('a').addEventListener('blur', () => {
var targetElement = event.target || event.srcElement;
echoBluredEl(targetElement)
});
function echoBluredEl(ele) {
document.querySelector('.blured-el-tag').innerHTML = ele.tagName.toLowerCase();
}

Triggering a change event for Internet Explorer

I have several select menus that needs that need to have their change events triggered on page load, so that they can automatically use the change behavior from an on('change', ...) handler.
I have it working fine in Firefox, but apparently this doesn't work in Internet Explorer.
Example
var changeEvent = new Event('change')
input.dispatchEvent(changeEvent);
I have tried finding alternatives in IE, and this is the closest I've come:
ie_event = document.createEvent('change')
ie_event.initEvent('change', function(e) {
...
}, false);
document.dispatchEvent(ie_event);
*The above is from codeproject.com, but it doesn't tell me what to put in the ellipses.
Can someone tell me what's wrong, point me in the right direction, or give me an example?
Would this be of any help?
<script>
$(document).ready(function () {
$("#select").on("change",function(){
//do something
});
$("#select").trigger("change");
});
</script>

Using JavaScript / jQuery event handler in Firefox

I have a jQuery function that submits a form via menu navigation functions:
$(function () {
$('#sidebarmenu1 a').on('click', function () {
var url = $(this).attr('href');
$('#myform').attr('action', url);
$("#myform").submit();
if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; }
})
});
This section:
if (event.preventDefault)
{ event.preventDefault(); }
else
{ event.returnValue = false; }
Prevents the default action of the sidebar button (I think - still new to this) i.e. to simply navigate to a page.
It is written in this way to keep IE happy, because preventDefault isn't defined for IE (might be using incorrect terminology there, but IE doesn't like preventDefault.)
However now this throws up an error in Firefox, because (as I read on other Stack questions) event is not globally defined for Firefox! I get the following error:
ReferenceError: event is not defined
Now according to this Stack question:
event is not defined in FireFox, but ok in Chrome and IE
In IE and Chrome, event is resolving to window.event. Firefox doesn't have this property and instead provides an event to an event handler function by passing it as a parameter. jQuery abstracts this difference for you by providing an event object parameter in all browsers.
But I thought I was using jQuery here and am still getting the issue.
Sorry if I'm making basic mistakes, self teaching myself js and jQ. Any help much appreciated.
This should do..
$(function() {
$('#sidebarmenu1 a').on('click', function(e) {
var evt = e || window.event;
var url = $(this).attr('href');
$('#myform').attr('action', url);
$("#myform").submit();
evt.preventDefault();
})
});​
If you use the event object jQuery passes to the event handler you wont have problems
$('#sidebarmenu1 a').on('click', function (event) {
var url = $(this).attr('href');
$('#myform').attr('action', url);
$("#myform").submit();
event.preventDefault();
})
If I had a couple of more points I would up-vote the second answer (passing in the jQuery 'event' argument).
I had unknowingly relied on the global event defined by browsers other than Firefox. I went back through my code and ensured I was always specifying the event parameter on all click events.
E.g.
$('#situationTextInput')
.val('')
.fadeTo(1000, 1.0)
.focus()
.off('keydown')
.on('keydown', function (event) {
VsUtils.handleSpanishTextKeydown(event);
});
I've also gotten into the habit of calling .off prior to .on as most of my code is using single pages, reusing content. Without the .off I was inadvertently stacking up events (even if they were the same callback) in subsequent steps of the dialog.
A side effect of changing my code to pass on 'event' directly to the handler was the binding to 'this.' changed. I chose to refactor the code to change 'this.' references to 'event.currentTarget.'

IE7 loses parameters in event handler function - prototype.js

I have a bunch of elements on a page with a class of "product". I want to attach an event handler to each one, so on hover a tooltip is shown.
The following code is working fine in Chrome, Firefox, Safari and IE8+, but not IE7:
function init() {
$$('.product').each(function(elm) {
var id = elm.id;
var name = new Element('div', {'class': 'title'}).update(products[id].name);
var desc = new Element('div').update(products[id].desc);
var content = new Element('div');
content.appendChild(name);
content.appendChild(desc);
elm.observe('click', function() {showTooltip(content)});
elm.observe('mouseover', function() {showTooltip(content)});
elm.observe('mouseout', function() {hideTooltip()});
});
}
document.observe('dom:loaded', init);
In IE7 the first time I hover over each element, it works fine. But, the 2nd time I hover over the element, the "content" variable is empty. If I replace my showTooltip() function with a simple alert(content.innerHTML), it alerts the proper HTML first time, and the alert is empty every time after.
I also tried to store content as an object, and use bindAsEventListener, but I get the same result.
Anyone have any thoughts on what is causing content to not persist in IE7?
I would try appending "content" into the DOM instead and pass a reference to the element for the tooltip, rather than the one in code.
#Josh Ryan, what is the hideTooltip() function doing on mouseout. If that is when the functionality is being lost, I would start there with my debugging.
EDIT: Sorry, I now remember that you said this works in other browsers, but it would still be helpful to see the mouseout function.

Categories

Resources