I'm trying to create notifications system in my company's ERP, similar to Facebook one. For now, after few hours of work, it looks like this:
Each menu item is a lielement. Each element can have one of classes that will modify it's background color:
selected is blue, shown on a picture
restricted is red
Now, what I'm trying to achieve is to make li background blink on some events (when new message comes in and list is not opened (and also selectedclass is not present)).
The problem is: it won't blink. :(
here's snap of my html (excluding messagebox)
<li class="notifications-topmenu-button selected">
<a href="#">
<div class="notifications-topmenu-button-wrapper">
<div class="notifications-topmenu-button-icon">
<img class="transparent" width="13" height="13" align="absmiddle" src="/images/icons/notifications.png" title="Powiadomienia" alt="Powiadomienia">
</div>
<div class="notifications-topmenu-button-counter" style="display: block;">3</div>
</div>
</a>
<span class="divider"> : </span>
</li>
<li class="selected">
Strona główna
<span class="divider"> : </span>
</li>
Also, there's some JavaScript initiating object (don't mind comments):
function notificationsObject(){
var nl = new Object();
//atrybuty klasy
nl.liElement = $('.notifications-topmenu-button');
nl.menuButton = $('.notifications-topmenu-button-wrapper');
nl.menuButtonCounter = nl.menuButton.find('.notifications-topmenu-button-counter');
nl.notificationsCount = jQuery.trim(nl.menuButtonCounter.text());
nl.notificationsList = $('.notifications-list-wrapper');
nl.blinkingInterval = null;
nl.startBlinking = function(){
nl.blinkingInterval = setInterval(function(){
if(nl.liElement.hasClass('restricted') == false){
console.debug(nl.liElement.addClass('restricted'));
}
else {
nl.liElement.removeClass('restricted');
}
}, 1000);
}
nl.stopBlinking = function(){
if(nl.blinkingInterval != null) nl.blinkingInterval = null;
}
(more 'class' functions)
return nl;
}
Now to test it, I simply call
$(document).ready(function(){
var notifications = notificationsObject();
notifications.startBlinking();
});
Of course I call it after function declaration.
funny fact is that when I change nl.startBlinking function setInterval internals to only add restrictedclass, it works. I'm pretty sure it must be some typo or stupid error, but I can't find it.
Please, help!
Try to use the toggleClass function instead of checking classes yourself like:
setInterval(function(){
nl.liElement.toggleClass('restricted');
}, 1000);
jQuery reference: http://api.jquery.com/toggleClass/
I put all your code into a Fiddle here and it worked. Not sure what the problem is.
added css
.restricted{
visibility:hidden;
}
Also removed (more 'class' functions) line. But I assume you just added that to the post and it's not part of your code.
Ok, problem solved.
the thing was that this function
nl.startBlinking = function(){
nl.blinkingInterval = setInterval(function(){
if(nl.liElement.hasClass('restricted') == false){
console.debug(nl.liElement.addClass('restricted'));
}
else {
nl.liElement.removeClass('restricted');
}
}, 1000);
}
started executing on declaration.
so when I called
$(document).ready(function(){
var notifications = notificationsObject();
notifications.startBlinking();
});
I had not one, but two intervals working at the same time.
Add and remove the 2 classes in stead of only restricted
if(nl.liElement.hasClass('restricted') == false){
nl.liElement.addClass('restricted');
nl.liElement.removeClass('selected');
}
else {
nl.liElement.removeClass('restricted');
nl.liElement.addClass('selected');
}
Related
I want to add a class to the download button of all the posts of my wordpress site, but without having to do it in each post
I have umami software running, where I track my traffic, I would like to add events every time someone presses the download button
For that event to be registered, I must add the class "umami--click--download-button" to each button.
I have already tried in many ways but nothing seems to work
the last thing i did was add the following script but it doesn't work either
<script>
$( "div" ).addClass(function( index, currentClass ) {
var addedClass;
if ( currentClass === "wp-block-button" ) {
addedClass = "umami--click--download-button";
}
return addedClass;
});
</script>
In the element inspector the button appears as follows
<div class="wp-block-button has-custom-font-size has-large-font-size">
<a class="wp-block-button__link has-white-color
has-vivid-cyan-blue-to-vivid-purple-gradient-background
has-text-color has-background wp-element-button" href="https://earnlink.click/"
style="border-radius:10px" target="_blank"
rel="noreferrer noopener">DOWNLOAD</a></div>
Thank you very much in advance to whoever answers
Here is the correct code. Try this and let me know if it works fine or not. If you see any error in console please provide the error message for debugging
<script>
(function ($) {
$('div.wp-block-button .wp-block-button__link').each(function () {
const classToAdd = 'umami--click--download-button';
const button = $(this);
if (!button.hasClass(classToAdd)) {
button.addClass(classToAdd);
}
});
})(jQuery);
</script>
you need to test the entire class list. see example below. This will add the class to the <div> tag not the <a> tag.
$("div").addClass(function(index, currentClass) {
var addedClass;
if (currentClass === "wp-block-button has-custom-font-size has-large-font-size") {
addedClass = "umami--click--download-button";
}
return addedClass;
});
.umami--click--download-button {
color: red;
}
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<div class="wp-block-button has-custom-font-size has-large-font-size">this is a test
<a class="wp-block-button__link has-white-color
has-vivid-cyan-blue-to-vivid-purple-gradient-background
has-text-color has-background wp-element-button" href="https://earnlink.click/" style="border-radius:10px" target="_blank" rel="noreferrer noopener">DOWNLOAD</a></div>
<div class="wp-block-button has-custom-font-size has-large-font-size">this is a test another test</div>
<div class="wp-block-button ">and another</div>
An assignment I have is to make a FAQ page for a website that displays an answer when you click on a question and also only allows one question to be visible at a time. I did this so far:
<li button onclick="answerOne();">question</li>
<span id="FAQA1" style="visibility: hidden; color: red;">answer</span>
<li button onclick="answerTwo();">question</li>
<span id="FAQA2" style="visibility: hidden; color: red;">answer</span>
<li button onclick="answerThree();">question</li>
<span id="FAQA3" style="visibility: hidden; color: red;">answer</span>
And my Javascript looks like this:
function answerOne() {
document.getElementById("FAQA1").style.visibility = "visible";
document.getElementById("FAQA2").style.visibility = "hidden";
document.getElementById("FAQA3").style.visibility = "hidden";
}
function answerTwo() {
document.getElementById("FAQA1").style.visibility = "hidden";
document.getElementById("FAQA2").style.visibility = "visible";
document.getElementById("FAQA3").style.visibility = "hidden";
}
function answerThree() {
document.getElementById("FAQA1").style.visibility = "hidden";
document.getElementById("FAQA2").style.visibility = "hidden";
document.getElementById("FAQA3").style.visibility = "visible";
}
Now this is all well and good but if the page ever gets bigger, you'd have to change every single function. I know there must be a better way to be able to achieve the same result but I seem to have hit a wall. If anyone knows a way to do this, can you point me in the right direction or to a source where I can find it? Many thanks.
You could try something like this:
var current = false;
function makeActive( key ) {
if( current !== false ) {
document.getElementById( "FAQ" + current ).style.visibility = "hidden";
}
document.getElementById( "FAQ" + key ).style.visibility = "visible";
current = key;
}
calling makeActive( "A1" ); would make FAQ item "A1" be visible and the previously active one become invisible
There's a number of ways you can do this. Here's one that doesn't involve so many functions.
Set up your HTML like this:
<li onclick="showAnswer('FAQA1')">question</li>
<span id="FAQA1" class="answer" style="visibility: hidden; color: red;">answer</span>
<li onclick="showAnswer('FAQA2')">question</li>
<span id="FAQA2" class="answer" style="visibility: hidden; color: red;">answer</span>
<li onclick="showAnswer('FAQA3')">question</li>
<span id="FAQA3" class="answer" style="visibility: hidden; color: red;">answer</span>
Notice that all the li elements use the same function and simply pass a string to it. The answer spans all have the same class and a unique id.
Then the Javascript:
function showAnswer(ele) {
[].forEach.call(document.querySelectorAll('.answer'), function(el) {
el.style.visibility = 'hidden';
});
document.getElementById(ele).style.visibility = 'visible';
}
So here, there's a forEach loop on all the elements with class answer (the answer spans). This loops through all the answers and hides them. Then, the last line selects the element with a particular id (that we've passed into the function as a string from the onclick) and sets that answer visible.
A fiddle: https://jsfiddle.net/dsmw0abe/2/
Also, just FYI, keep in mind that visibility is different from display.
You could create a function that allows you to have an unlimited number of questions. By giving every answer span the same class, you do not have to explicitly define each one in your code.
Because your answers start at 1, I am starting the loop at 1 instead of 0.
Example:
window.answerQuestion = function answerQuestion(id) {
var questionEls = document.getElementsByClassName("answer");
for (var x = 1; x <= questionEls.length; x++) {
var question = questionEls[x-1];
if (x === id) {
question.style.visibility = 'visible';
} else {
question.style.visibility = ' hidden';
}
}
};
Demo:
https://jsfiddle.net/j3k89o5a/
One approach is to to start w/ all answers hidden then listen for an event within the div at which time you can capture which item was clicked and toggle visibility of nearest following answer. If it is clicked again, it will toggle that answer closed. This allows the user to open each question as they see fit and prevents the page from jumping around - i.e. closing previous answer when a new question is clicked.
For Example
HTML
<div class="faq">
<h1>First Question</h1>
<p>Answer to the question</p>
<h1>Second Question</h1>
<p>Answer to the question</p>
<h1>Third Question</h1>
<p>Answer to the question</p>
</div>
CSS
.faq {
display: none
}
Javascript/jQuery (could be done w/ vanilla js, if needed)
$(function() {
$('.faq h1').click(function() {
$(this).next('p').slideToggle(400);
});
});
I'm trying to modify this pen I found on CodePen. I'd like to be able to open a specific list on the page from another page. Clicking the link should open the corresponding section on the next page on page load.
I'm a bit of a newbie when it comes to jQuery, so I appreciate any help I can get. I've tried searching around and have an idea of what I need to target, but I haven't been able to make it happen. Here is my code:
HTML:
<!--Link on Previous Page-->
Click Here
<!--Target List-->
<div class="integration-list">
<ul>
<li class="integration">
<a class="expand" id="list">
<div class="expand_intro"><h3 class="teal_bold">Click Here</h3></div>
<div class="right-arrow">▼</div>
</a>
<div class="detail">
<div><p>Lorem Ipsum Dolor...</p></div>
</div>
</li>
</ul>
</div>
JS:
$(function() {
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "▼") {
$expand.text("▲");
} else {
$expand.text("▼");
}
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
$('.expand').find('a[href*='+ thash + ']').trigger('click');
});
});
Few things that I did to get it to work:
The trigger event is probably firing before the handler is actually attached. You can use setTimeout as a way around this.
Also, even with setTimeout around $('.expand').find('a[href*='+ thash + ']').trigger('click'); it didn't work for me. I changed that to simply $(thash).click();.
The complete code of the "expand.js" file:
$(function() {
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
setTimeout(function() {
$(thash).click();
}, 10);
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "â–¼") { //If you copy/paste, make sure to fix these arrows
$expand.text("â–²");
} else {
$expand.text("â–¼");
}
});
});
Apparently the arrows don't display properly here, so watch that if you copy/paste this.
im trying to make a switch wich will change two images. I once solved ths, but then i lost some important files, the one containing the final script being one.
The idea is that when the button is clicked, it will change image 1 for image 2 and will change its own image from on to off. Then, when clicked again it will change image 2 for image 1 and its own image from off to on.
I been trying something like this, buts not working, not sure why. I think i got the wrong declaration for the if which determines if the switch is on or off, but again not sure.
Before you read the code and realize its poorly done, consider i dont know a thing about javascript, i only have a vague idea of how it works.
<script type="text/javascript">
var vswitch = false;
if (document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif") {
vswitch = true
}
else {
vswitch = false
}
function change(){
if (vswitch == true){
function changelamp() {
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
}
function changeSwitch() {
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
}
} else {
function changelamp() {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
}
function changeSwitch() {
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
}
}
<div id="main_img">
<img id="lamp" src = "http://www.sampleweb.com/image1.gif">
</div>
<div id="container">
<img id="switchh" src = "http://www.sampleweb.com/on.gif" onclick='change();'>
</div>
</script>
Thank you
/////////////////////EDIT///////////////////////////
Thanks a lot.
Having those two functions there was a result of the previous code, i dont understand how i didnt realize it until you pointed out, heh. (Sleepyness maybe?)
#renuka, that code worked perfectly. I only changed the calling div, from the div "toggle" you created to the div "container" since the button has to switch the images itself, but other than that was sweet. Thanks.
Thanks for the help!
There are a couple of problems here :)
First:
if (document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif")
^ this assigns a variable
You want to change = to === so that a comparison is done
Second, you're creating functions changelamp and changeSwitch but you're never actually calling them. I think you want to get rid of the function declarations completely:
if (vswitch == true){
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
} else {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
Finally, there are some minor syntax errors such as missing semi-colons
vswitch = true; // <- like this
Please check the updated code below:
<script type="text/javascript">
function change(){
var vswitch = false;
if (document.getElementById("switchh").src == "http://www.sampleweb.com/on.gif") {
vswitch = true
}
else {
vswitch = false
}
if (vswitch == true){
document.getElementById("lamp").src = "http://www.sampleweb.com/image2.png";
document.getElementById("switchh").src = "http://www.sampleweb.com/off.gif";
}
else {
document.getElementById("lamp").src = "http://www.sampleweb.com/image1.gif";
document.getElementById("switchh").src = "http://www.sampleweb.com/on.gif";
}
}
</script>
<div id="main_img">
<img id="lamp" src = "http://www.sampleweb.com/image1.gif"/>
</div>
<div id="container">
<img id="switchh" src = "http://www.sampleweb.com/on.gif"/>
</div>
<div id="toggle">
<input type="button" value="On/Off" onclick='change();'/>
</div>
The '=' assigns the value to the "src" of the image. Replace it with '==' for comparison.
Additionally from what jasonscript says, you are never switching the vswitch variable to the opposite state, so you'd need to add
vswitch = !vswitch;
after the if in the change() function, that way, the next time you click in the switch, it takes the "other" path through the if
Another point is that if you have the code layout as you have it in your post (script first and then the HTML code) the first if will actually not find the #switchh img, so you need to either move the if inside the change() function or move your script after the HTML
Major problem is that you are unnecessarily creating functions inside script which are never called.
No need for
changelamp() and changeSwitch()
You can directly post the code after the if condition check.
<script> tags should be closed. = assigns and === does comparison, and you need to change the value of vswitch.
Here is a fiddle that accomplishes what you're after with some random images
Very simply put : the line currentItem.toggleClass('open'); doesn't seem to work.
More precisely, when inspecting the results with firebug, I can see the class "open" flashing (appearing and immediately disappearing) on the relevant element. So it's like the function is actually triggered twice (of course I only click once).
Can somebody explain me why this is and how to prevent it?
Here is my jQuery code :
$('div.collapse ul.radio_list li input[type=radio]').click(function (event) {
var currentTree = $(this).parent().parent().parent();
var currentItem = $(this).parent().parent();
var currentGroup = currentItem.attr('rel');
$(this).parents('ul').children('li').removeClass('select');
if ($(this).is(':checked')) {
currentItem.addClass('select');
}
currentItem.toggleClass('open');
var currentLevel = 0;
if (currentItem.is('.level1')) {currentLevel = 1;}
if (currentItem.is('.level2')) {currentLevel = 2;}
if (currentItem.is('.level3')) {currentLevel = 3;}
var nextLevel = currentLevel + 1;
currentTree.children('li').filter('li[rel ^=' + currentGroup + '].level' + nextLevel).animate({'height': 'show', 'opacity': 'show'}, 250).addClass('currentChild');
});
And here is a part of my HTML code, slightly simplified for better readability (not very pretty I know, but I only have a limited control on the HTML output) :
<div class="col_left collapse">
<ul class="radio_list" rel="7">
<li class="onglet level0" rel="group1">
<span class="onglet level0">
<input type="radio" />
<label>Services Pratiques</label></span>
<input type="hidden" value="1">
</li>
Thanks in advance.
Problem solved: the JS file was actually included twice in the HTML head, which caused the function to be triggered twice with each click.
I had a similar problem on my site, and I found that I had accidently duplicated the toggleclass hook all the way at the bottom, when first messing around with it. Oops! Make sure to look for double calls!
I had a similar problem doing this:
html:
<a>JS-link</a>
js:
$('a').click(function(event) {
... my stuff ...
# Forgot to do event.preventDefault(); !!
}
results in clicks being register twice!
I had the same issue and realized I had accidentally bound the function twice. I had originally meant to move the code from one javascript file to another but accidentally left the original in its place.