I know this is a simple question but I have been playing around with no success.
I have the following code
<a id="mute"><i class="icon-volume"></i></a>
I want to be able to toggle the class .icon-volume to .icon-volume-off when clicking.
After anyone who can help!
Thanks
Try
var a = document.getElementById("mute");
a.onclick = function(e){
var cl = a.firstChild.getAttribute('class');
if(cl == "icon-volume"){
a.firstChild.setAttribute('class','icon-volume-off');
}else{
a.firstChild.setAttribute('class','icon-volume');
}
};
See demo here
You could use jQuery
$('#mute').on('click', function () {
var el = $(this).find('i');
if (el.hasClass('icon-volume')) {
el.removeClass('icon-volume');
el.addClass('icon-volume-off');
} else {
el.removeClass('icon-volume-off');
el.addClass('icon-volume');
}
});
Or you could just add the icon-volume-off class and make sure its css takes precedence over the icon-volume class
$('#mute').on('click', function () {
var el = $(this).find('i');
if (el.hasClass('icon-volume-off')) {
el.removeClass('icon-volume-off');
} else {
el.addClass('icon-volume-off');
}
});
WARNING: This is a (relatively) new attribute. Check the compatibility table from Mozilla's Developer Network before you proceed. If IE 9 (or below) is important to you, then this is not the answer you're looking for.
DOM elements have a property called classList. The 3 methods you should familiarize yourself with are add, remove, and toggle.
In your case:
var el = document.querySelector('i');
el.onclick = function () {
el.classList.toggle('icon-volume');
el.classList.toggle('icon-volume-off');
}
Pretty simple.
Related
I am creating a simple function to close a flash message div on click event, but my listener is not firing.
I wrote 3 different functions to try to get it working, but nothing is happening and Chrome console isnt telling me anything.
My first was in ES6 class style, this one:
class closeFlashMessages {
constructor () {
this.getFlashMessages = document.querySelector("#flash-messages");
this.addEventListeners();
}
close () {
console.log(this.getFlashMessages);
this.getFlashMessages.className = "hide";
}
addEventListeners () {
if(this.getFlashMessages)
this.getFlashMessages.addEventListener("click", this.close);
}
}
new closeFlashMessages();
My second was this:
(function (){
let getFlashMessages = document.querySelector("#flash-messages");
function close () {
console.log(getFlashMessages);
getFlashMessages.className = "hide";
}
function addEventListeners () {
getFlashMessages.addEventListener("click", function () {
close()
});
}
addEventListeners();
});
My last one is this:
(function (){
let getFlashMessages = document.getElementById("flash-messages");
getFlashMessages.addEventListener("click", close(getFlashMessages));
function close (id) {
console.log(getFlashMessages);
getFlashMessages.className = "hide";
}
});
My HTML:
<div id="flash-messages">
<div class="flash success">
<p>Recept byl přidán do nákupního seznamu.</p>
</div>
</div>
But none of them worked!! I dont understand
With the first two, I was getting undefined on my this.getFlashMessages also not sure why.
My solution is not in ES6
function Init(){
var id = document.getElementById('flash-messages');
var msg = document.querySelector('.flash');
id.addEventListener('click',function(){
msg.className = 'hide';
});
}
Init();
see demo here
I am not very much familiar with ES6.
But if I try similar code sample on a javascript it will be as given below and I hope it will be almost similar in ES6 aswell.
var getFlashMessages = document.getElementById("flash-messages");
getFlashMessages.addEventListener("click", function()
{
clicked(getFlashMessages);
});
function clicked(id){
console.log(id);
id.className = "hide";
}
Here, I am calling anonymous function, and its default argument will be event object as given in https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.
Just don't know why this piece of code is not working: (onClick not working, click() is working (using console))
function click(ID)
{
if(cost[ID] <= currency[costID[ID]])
{
currency[costID[ID]] -= cost[ID];
currency[ID] += buyamout[ID];
document.getElementById(x[costID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[costID[ID]])*100)/100)+not+"</center>";
document.getElementById(x[gainID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[gainID[ID]])*100)/100)+not+"</center>";
}
}
...'<button onClick="click('+i+');">'+button+x[i]+'</button>'
this gives output <button onClick="click(0);">Make DNA</button>
and after clicking button nothing happens.
There could be a namespace conflict with your click. Use another name like button_click below
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="button_click('+i+');" >'+(button+x[i])+'</button>');
function button_click(ID) { // notice the function name change
alert(ID);
}
Code below not working:
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="click('+i+');" >'+(button+x[i])+'</button>');
function click(ID) { // the function name click may have been used already
alert(ID);
}
indeed onclick="click('+i+');" executes the javaScript code between the double brackets: click('+i+');: it calls the javaScript click() function, but this does not work if you declare function click() and someone else did that elsewhere in javaScript code.
if onClick is not working you can also use addEventListener will do the same job.
for e.g.
element.addEventListener('click', function() { /* do stuff here*/ }, false);
To answer your question you must do the following.
Change:
onClick="click(0)"
To:
onclick="click(0)"
That will most probably fix your problem.
I'm using the Microsoft Translation Widget, which I'd like to use to automatically translate a webpage without user interaction.
The problem is, I can't get rid of the widget that keeps popping up or hide it on document.ready because the CSS and JS get loaded from Microsoft's own script in the widget!
Does anyone know a way around this? I've looked everywhere and cannot find a solutuion for this.
Whoa, after some time playing around with that, I've finally achieved what you want.
It's kindda ugly, because of some needed workarounds, but it works, take a look at the fiddle.
The steps were:
Firstly, we must override the default addEventListener behavior:
var addEvent = EventTarget.prototype.addEventListener;
var events = [];
EventTarget.prototype.addEventListener = function(type, listener) {
addEvent.apply(this, [].slice.call(arguments));
events.push({
element: this,
type: type,
listener: listener
});
}
Then, we create a helper function removeEvents. It removes all the event listeners of an element.
var removeEvents = function(el, type) {
var elEvents = events.filter(function(ev) {
return ev.element === el && (type ? ev.type === type : true);
});
for (var i = 0; i < elEvents.length; i++) {
el.removeEventListener(elEvents[i].type, elEvents[i].listener);
}
}
When creating the script tag, in the way Microsoft says:
var s = d.createElement('script');
s.type = 'text/javascript';
s.charset = 'UTF-8';
s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=True&ui=true&settings=Manual&from=';
var p = d.getElementsByTagName('head')[0] || d.dElement;
p.insertBefore(s, p.firstChild);
We must add a load event listener to that script, and the code below is fully commented:
s.addEventListener('load', function() {
// when someone changes the translation, the plugin calls the method TranslateArray
// then, we save the original method in a variable, and we override it
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
// we call the original method
translate.apply(this, [].slice.call(arguments));
// since the translation is not immediately available
// and we don't have control when it will be
// I've created a helper function to wait for it
waitForTranslation(function() {
// as soon as it is available
// we get all the elements with an attribute lang
[].forEach.call(d.querySelectorAll('[lang]'), function(item, i) {
// and we remove all the mouseover event listeners of them
removeEvents(item, 'mouseover');
});
});
}
// this is the helper function which waits for the translation
function waitForTranslation(cb) {
// since we don't have control over the translation callback
// the workaround was to see if the Translating label is visible
// we keep calling the function, until it's hidden again
// and then we call our callback
var visible = d.getElementById('FloaterProgressBar').style.visibility;
if (visible === 'visible') {
setTimeout(function() {
waitForTranslation(cb);
}, 0);
return;
}
cb();
}
});
Update 1
After re-reading your question, it seems you want to hide all the widgets at all.
So, you must add the following code as soon as the translation is got:
waitForTranslation(function() {
document.getElementById('MicrosoftTranslatorWidget').style.display = 'none';
document.getElementById('WidgetLauncher').style.display = 'none';
document.getElementById('LauncherTranslatePhrase').style.display = 'none';
document.getElementById('TranslateSpan').style.display = 'none';
document.getElementById('LauncherLogo').style.display = 'none';
document.getElementById('WidgetFloaterPanels').style.display = 'none';
// rest of the code
});
I've created another fiddle for you, showing that new behavior.
Update 2
You can prevent the widget showing at all by adding the following CSS code:
#MicrosoftTranslatorWidget, #WidgetLauncher, #LauncherTranslatePhrase, #TranslateSpan, #LauncherLogo, #WidgetFloaterPanels {
opacity: 0!important;
}
And you can even prevent the before-translated text being showed, by hiding the document.body by default, and then showing it when the page is fully translated:
(function(w, d) {
document.body.style.display = 'none';
/* (...) */
s.addEventListener('load', function() {
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
translate.apply(this, [].slice.call(arguments));
waitForTranslation(function() {
/* (...) */
document.body.style.display = 'block';
});
}
});
});
Take a look at the final fiddle I've created.
For me, this was the solution:
on your < style > section add this class
.LTRStyle { display: none !important }
Also, if you are invoking the translation widget this way:
Microsoft.Translator.Widget.Translate('en', lang, null, null, TranslationDone, null, 3000);
then add this to your callback (in this example is TranslationDone) function:
function TranslationDone() {
Microsoft.Translator.Widget.domTranslator.showHighlight = false;
Microsoft.Translator.Widget.domTranslator.showTooltips = false;
document.getElementById('WidgetFloaterPanels').style.display = 'none';
};
This is a section of my view in which I want the result to show.
Can any one solve this problem?
When this.waitlist works, it should return the container like div#sntq-waitlist but it gives object[ ] instead.
Can anyone tell me why this is?
JavaScript
initLiveWaitList: function() {
this.waitlist_ = $('sntq-waitlist');
this.daily_status_ = $('sntq-daily_status');
this.waiting_ = $('sntq-waiting');
this.seated_ = $('sntq-seated');
this.oneFour_ = $('sntq-one-four');
this.fiveSix_ = $('sntq-five-six');
this.seven_ = $('sntq-seven');
this.running_ = true;
this.loadWaitList_();
this.intervalId_ = this.loadWaitList_.periodical(1200000, this);
window.addEventListener('focus', function() {
if (!this.running_) {
this.loadWaitList_();
this.intervalId_ = this.loadWaitList_.periodical(1200000, this);
}
}.bind(this));
window.addEventListener('blur', function() {
clearInterval(this.intervalId_);
this.running_ = false;
} .bind(this));
},
View
<div id="sntq-daily_status">
<div class="loading"></div>
</div>
I don´t think I completely understood your question, but to me it looks like you are using jQuery to get the containers at the top of your code.
If this is the case you are probably just missing the ID selector.
Try to change the code to
this.waitlist_ = $('#sntq-waitlist');
this.daily_status_ = $('#sntq-daily_status');
//[...]
(note the "#" selector if you want to look for elements by ID, which seems to be the case in your example).
There are several textareas on my page and I need the text of the one someone is clicking on. I would know how to do it in jQuery but I need a prototype/javascript solution. What I tried so far:
$$("textarea").each(function (el) {
el.observe('click', respondToClick);
function respondToClick(event) {
var element = Event.element(event);
var text = element.innerHTML();
console.log(text);
}
});
There are no errors in the console but also not the text I need. So how to get it?
EDIT:
That's the solution. I forgot the document.ready-equivalent in prototype and thanks to bruchowski I could edit the correct prototype method to get the text:
document.observe("dom:loaded", function () {
$$("textarea").each(function (el) {
el.observe('click', respondToClick);
function respondToClick(event) {
var element = Event.element(event);
var text = element.value;
console.log(text);
}
});
});
P.S.: Prototype Vesion is 1.7.0
You can use Form.Element.getValue(), or its $F() alias:
var element = Event.element(event);
var text = $F(element);
console.log(text);