Good day.
I don't know the right terminology about my question but what I want to ask is how to ask is this:
//functionA
$(document).on('click', '.classA1, .classA2, .classA3', function(event) {
//i want to call the functionB when functionA is used.
//if possible, when I use the onclick on classB2
}
//functionB
$(document).on('click', '.classB1, .classB2', function(event) {}
note, I am new to JavaScript and was suddenly given a task by my boss. I cant really ask them about this since they are also new to the project/JavaScript since we just received the project from previous developer.
$('.classA1, .classA2, .classA3').on('click', ()=> {
console.log('function A called');
$('.classB1, .classB2').trigger('click');
});
$('.classB1, .classB2').on('click', ()=> {
console.log('function B called');
});
a {
display: inline-block;
background: teal;
padding: .5rem;
border-radius: 5px;
color: white;
font: 16px Arial, sans-serif;
cursor: pointer;
}
.b {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="classA1">class A1</a>
<a class="classA2">class A2</a>
<a class="classA3">class A3</a>
<a class="classB1 b">class B1</a>
<a class="classB2 b">class B2</a>
If I would be thinking simply about it, I would declare two methods first and then use them as callbacks in the listeners.
function functionA(event) {
// implement your logic here
// and call functionB as well
functionB(event);
}
function functionB(event) {
// implement your B logic here
}
$(document).on('click', '.classA1, .classA2, .classA3', functionA);
$(document).on('click', '.classB1, .classB2', functionB);
This is actually not much else to be done as you can't delegate an event in such way as you wish it.
Imagine following scenario. Pink rectangle would be e.g. a span within a div (black rectangle) If you would add a click listener to the "div", then the click event would fire when you click the "div" and even if you click the "span". The click event propagated.
Otherwise you might want to add multiple click listeners to the same object. Then depending on your desire you can either interrupt the propagation (blocking the other listeners) by e.g. invoking the event.stopPropagation() method.
I would like the community to add more explanations if I missed something critical.
Related
So I am making a clicker game and am kind of stuck. I want a popup like cookieClicker has when you get an achievement. It pops up and tells you what happened, you can click the x or it will just fade away after a few seconds.
I tried making something with pure javascript and CSS to no avail, it would fade away nicely but not automatically.
So how do I make it so whenever X element is made/displayed then it goes away after 3 seconds?
Also, if it matters the element would be created by a javascript function, and multiples might be created at the same time.
P.S. I tried searching and found something about auto-fading in javascript but nothing in there seemed to work either.
EDIT: After trying to view cookieclicker source and playing the game again it appears it doesn't even have this functionality. The closest thing I can compare it to is when you would add something to your cart on a website, then it alerts you the item was added and then fades away.
Here is one approach which uses Javascript to trigger a CSS transition:
var button = document.getElementsByTagName('button')[0];
var div = document.getElementsByTagName('div')[0];
function autoFader() {
if (window.getComputedStyle(div).getPropertyValue('display') === 'none') {
div.style.display = 'block';
setTimeout(function(){
div.style.opacity = '0';
},10);
setTimeout(function(){
div.removeAttribute('style');
},4010);
}
}
button.addEventListener('click',autoFader,false);
div {
display: none;
width: 200px;
height: 100px;
margin: 20px auto;
padding: 6px;
font-size: 20px;
color: rgb(255,255,255);
text-align: center;
border: 3px solid rgb(127,0,0);
background-color: rgb(255,0,0);
opacity: 1;
transition: opacity 3s linear 1s;
}
<button type="button">Click Me</button>
<div>
<p>Hi, I'm an auto-fading pop-up.</p>
</div>
So, your openPopup function might look like this:
function openPopup(/* options here */) {
const popup = actuallyOpenPopup();
waitSomeTimeAndCloseIfNotClosedYet(popup);
}
where 2nd function should take a popup instance (which has .close method probably, or dismiss)
and start a timeout. You need to keep that timeout, so if close was called, you need to cancel it.
Something like this:
function waitSomeTimeAndCloseIfNotClosedYet(popup) {
const originalClose = popup.close;
/* monkey patching, decorating,
separate method - whatever you prefer */
popup.close = function () {
clearTimeout(this.timeout);
originalClose.call(this);
};
popup.timeout = setTimeout(() => popup.close(), 3000);
}
So, if was closed manually - it wont be called twice, if not, will fire up a timeout and close automatically.
Via CSS you can only achieve visible closing, but not removal of nodes. (Google for transition visibility, fade out modal etc.)
Hope this helps!
// color pattern function
function colorPattern(color_Pattern_box)
{
var color_Board = $("#colorBoard");
var rtrnVal = ""; //default to standard syntax
var color_temp = ("");
for(var c = 0; c < color_Pattern_box.length; c++){
var color_Split = color_Pattern_box[c].split(":");
var color_Name = color_Split[0];
var color_Value = color_Split[1];
color_temp += "<div id="+color_Value+"; data-title="+color_Name+" onclick='' class='mycolor_warpper'; style='background: "+color_Value+";'></div>";
var color_inset = $(".mycolor_warpper");
colorpattern_attachEvent(color_inset, "click", updateNumberText, JsonSave);
}
// //input option to parent
color_Board.html(color_temp);
}
function colorpattern_attachEvent(element, event, callbackFunction1, callbackFunction2) {
if(typeof(element.addEventListener)=='function') {
element.addEventListener(event, function(){
callbackFunction2(this.getAttribute("id"));
callbackFunction1();
}, false);
}
}
I have function with loop, and I want to to use the loop to add eventListener to my class.
Basically, the loop will create div and class name "mycolor_wrapper". How do I attach each class with addEventListener() click, here is the code I tested it and it doesn't work.
i have function with loop, and I want to to use the loop to add eventlistener to my class.
There's an easier way to go about adding less and getting more, especially with jQuery as Dinglemeyer was explaining.
Basically the loop will create div and class name "mycolor_wrapper". How do I attach each class with addeventlistner click, here is the code i tested it won't work.
Ok, while clumping things together in a code lump might sound great, you should try coding for one portion of your code, test it and see if it works, then move on to the next. Like when you build a house you don't start on the roof and build the foundation then the frame.
So I'll answer this question:
…How do I attach each class with addeventlistner click…
generically with generic JavaScript.
First part of answer, as I have commented (and probably others have as well), you don't want to go that route. Adding multiple eventListeners of the same eventType is unnecessary and messy. Instead you can utilize the properties that will help you control the event bubbling:
event.target: The element that is clicked.
event.currentTarget: The element that you added an eventListener to. In a simple setup, this would be the same as the event.target. But in your situation it'll be different because we will add one eventListener to the parent element (i.e. #colorBoard) of multiple event.targets (i.e. .colorWrap(I hate underscores .colorWrap = .mycolor_warpper)).
event.stopPropagation(): This method will stop the propagation of the click event from bubbling up to the rest of the elements in the event chain (e.g. #colorBoard), thereby we will isolate the click event to just one element.
SNIPPET
// Reference the parent #colorBoard
var parent = document.getElementById('colorBoard');
// Add eventListener to parent
parent.addEventListener('click', trueColor, false);
// Create trueColor(event) eventHandler
function trueColor(event) {
// If event.target is not event.currentTarget then...
if (event.target !== event.currentTarget) {
// Store event.target in the variable 'clicked'
var clicked = event.target;
// Next change clicked background-color to it's id.
clicked.style.backgroundColor = clicked.id;
}
// Use event.stopPropagation() to prevent event bubbling so #colorBoard will never hear the event.
event.stopPropagation();
}
.colorBoard {
border: 3px dashed black;
width: 300px;
height: 300px;
}
h1 {
font-size: 20px;
color: orange;
}
.colorWrap {
height: 100px;
width: 300px;
cursor: pointer;
font-size: 15px;
color: white;
background: black;
border: 1px solid white;
}
<section id="colorBoard">
<h1>Color Board</h1>
<div id="red" class="colorWrap">RED</div>
<div id="green" class="colorWrap">GREEN</div>
<div id="blue" class="colorWrap">BLUE</div>
</section>
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
Is it possible for you to include the JQuery library in your project/site?
You could use a JQuery event handler on the class instead of iterating through objects to attach the event handler?
This would select all objects of your class "my_color_warpper" with a click event handler to call your logic
$(".mycolor_warpper").on ("click", function () {
// your logic
callbackFunction2(this.getAttribute("id"));
callbackFunction1();
});
Rather than looping through by adding event handler in this way you only declare it once and it slams them all out.
There are a bunch of div elements on the page.
I have a nested div inside of them.
I want to be able to add a class to the clicked element, and .show() the child div.
$('.container').on('click', function(){
$(this).toggleClass('red').children('.insideItem').slideToggle();
});
I can click on it, it drops down.
Click again, it goes away.
So, now I need some method to removeClass() and slideUp() all of the other ones in the event of a click anywhere except the open div. Naturally, I tried something like this:
$('html').on('click', function(){
$('.container').removeClass('red').children('div').slideUp();
});
Well, that just stops the effect from staying in the first place. I've read around on event.Propagation() but I've read that should be avoided if possible.
I'm trying to avoid using any more prebuilt plugins like accordion, as this should be a pretty straightforward thing to accomplish and I'd like to know a simple way to make it work.
Would anyone be able to show a quick example on this fiddle how to resolve this?
Show only one active div, and collapse all others if clicked off
https://jsfiddle.net/4x1Lsryp/
One way to go about it is to update your code with the following:
1) prevent the click on a square from bubbling up to the parent elements
2) make sure to reset the status of all the squares when a new click is made anywhere.
$('.container').on('click', function(){
$this = $(this);
$('.container').not($this).removeClass('red').children('div').slideUp();
$this.toggleClass('red').children('div').slideToggle();
return false;
});
See the updated JSfiddle here: https://jsfiddle.net/pdL0y0xz/
You need to combine your two approaches:
for (var i = 0; i < 10; i++) {
$('#wrap').append("<div class='container'>" + i + "<div class='insideDiv'>Inside Stuff</div></div>");
}
$('.container').on('click', function() {
var hadClassRed = $(this).hasClass('red');
$('.container').removeClass('red').children('div').slideUp();
if (!hadClassRed) {
$(this).toggleClass('red').children('div').slideToggle();
}
});
.container {
width: 200px;
height: 200px;
float: left;
background: gray;
margin: 1em;
}
.insideDiv {
display: none;
}
.red {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap"></div>
I'm trying to make a blue div that turns red when clicking on it and the red div turns back to blue ( so I can add more events on the click after clicking, so .css isn't really an option)
When clicking on the div when it's blue, it turns red. But when I click the red div it doesn't respond, even when I add a simple alert()
Does anyone know what I'm doing wrong?
This is my current code and a JSFiddle
code:
$("#Blue").click(function(){
$("#Blue").attr("id","Red");
});
$("#Red").click(function(){
$("Red").attr("id","Blue");
});
If anyone could tell me what Exactly I'm doing wrong that would be great, thank you in advance
You need to use event delegation -- your click handlers are bound to the matching elements at the time the code is first run, and only then. Since there's no #Red element at that point in time, that second click handler isn't bound to anything.
$(document).on('click',"#Blue", function(){
$("#Blue").attr("id","Red");
});
$(document).on('click',"#Red", function(){
$("#Red").attr("id","Blue");
});
http://jsfiddle.net/mblase75/HDFyn/
http://api.jquery.com/on
That said, the "proper" way to do this would be to add and remove a class, not change the ID:
$('#btn').on('click', function(){
$(this).toggleClass("red blue");
});
http://jsfiddle.net/mblase75/mKMW6/
.click() binds only to existing elements at the time you call it; it will not bind to a later-created element or an element to which you assign the id later.
The fix is to use event delegation. See here and here for more information.
Also, use classes, instead -- much more flexible.
HTML
<div class="Test blue">Test</div>
jQuery
$(".blue, .red").click(function(){
$(this).toggleClass('red blue')
});
CSS
.Test{
width: 50px;
height: 50px;
}
.blue{
background-color: blue;
}
.red{
background-color: red;
}
Fiddle: http://jsfiddle.net/8FmSt/3/
You could use the class and update the ID like below instead of having 2 function to do that action,
$('.Test').on('click', function () {
this.id = (this.id == 'Blue')?'Red':'Blue';
});
DEMO: http://jsfiddle.net/8FmSt/2/
If it is all about changing color, then use a css to change to color like below,
$('.Test').on('click', function () {
$(this).toggleClass('Red Blue');
});
http://jsfiddle.net/8FmSt/5/
Try:
$(".Test").click(function(){
var id = $(this).attr("id");
if(id == "Red"){
$(this).attr("id","Blue");
}
else{
$(this).attr("id","Red");
}
});
Updated fiddle here.
Let's uncomplicate
HTML
<div class="Test">Test</div>
JQUERY
$(".Test").on('click', function () {
$(this).toggleClass("red");
});
CSS
.Test {
width: 50px;
height: 50px;
background: blue;
}
.red {
background: red;
}
having a problem, I have a javascript content switcher on a page, but I can't seem to get one thing working - how to make a clicked button stay active after it's clicked?
Here's a code:
JS
<script type="text/javascript">
function switch1(div) {
var option=['one','two','three'];
for(var i=0; i<option.length; i++) {
if (document.getElementById(option[i])) {
obj=document.getElementById(option[i]);
obj.style.display=(option[i]==div)? "block" : "none";
}
}
}
window.onload=function () {switch1('one');}
</script>
CSS
#switchables li a {
color: #262626;
text-decoration: none;
display: inline-block;
padding-top: 14px;
padding-right: 34px;
padding-bottom: 10px;
padding-left: 33px;
background-image: url(img/catButBcgr.jpg);
border-right-width: 1px;
border-left-width: 1px;
border-right-style: solid;
border-left-style: none;
border-right-color: #E1E1E1;
border-left-color: #FFF;
}
#switchables li a:hover {
background-image: url(img/catButBcgrH.jpg);
}
#switchables li a:active {
background-image: url(img/catButBcgrA.jpg);
}
HTML
<ul id="switchables">
<li><a class="active" href="javascript:void[0];" onclick="switch1('one');">OVERVIEW</a></li>
<li><a class="active" href="javascript:void[0];" onclick="switch1('two');">CATEGORY</a></li>
<li><a class="active" href="javascript:void[0];" onclick="switch1('three');">CATEGORY</a></li>
</ul>
You need to make an "Active" class and add it to the button when clicked.
#switchables a:active, #switchables a.active {
background-image: url(img/catButBcgrA.jpg);
}
It's easy using jQuery:
$(document).ready(function() {
myInit()
})
function myInit() {
$('#switchables a').click(function() {
$('#switchables a').removeClass('active')
$(this).addClass('active')
})
}
This is a nice opportunity to learn. Diodeus' answer is completely right, but his jQuery code does horrible things on the background, see the comments:
$(document).ready(function() {
myInit()
})
function myInit() {
// on the following line, jQuery creates an array of objects (a tags)
// (costly operation!) and adds click listener to each of them
$('#switchables a').click(function() {
// on the following line, jQuery creates the crazy God object again
// and throws it off after this command
// for each a tag and tries to remove class active from it
// in only one case it actually does something - mere class removal
// btw removeClass is ridiculous function if you dig into jQuery 1.10 source
$('#switchables a').removeClass('active')
// this = the source of click event, not jQuery object
$(this).addClass('active')
})
}
This is just a very short code, now imagine you write whole web this style. It will be observably slower, consuming much more resources.
If you insist on jQuery, try to write reusable code a little:
function myInit() {
// jQuery object is created only once
var $anchors = $('#switchables a');
$anchors.click(function() {
// ...and reused here
$anchors.removeClass('active')
$(this).addClass('active')
});
}
But you'd do much better job using native javascript
var items = document.querySelectorAll("#switchables a");
var prev = items[0];
[].forEach.call(items,function(item) {
item.addEventListener("click",function() {
// no need to loop every a tag here
prev.classList.remove("active");
item.classList.add("active");
// remember previous active a tag
prev = item;
});
});
document.querySelectorAll is a live collection which is something that can't be achieved by any javascript library, it is implemented in underlying and more effective code of the browser.
Advice Don't use jQuery until you know Javascript well. Without that knowledge, you will be able to implement just basic animations, copy&paste some plugins and nothing more. And when you know Javascript on some level, you will probably see very little reason to use jQuery anymore.
In the code above, jQuery can be easily removed:
1: $(document).ready(handler) -> document.addEventListener("readystatechange",handler);
2: $('#switchables a') -> document.querySelectorAll("#switchables a");
3: $(nodeList).click(handler) ->
[].forEach.call(nodeList,function(node) {
// you can reuse node here, unlike the jQuery
node.addEventListener("click",handler);
});
4: $(node).removeClass(className) -> node.classList.remove(className)
5: $(node).addClass(className) -> node.classList.add(className)
It is a few chars longer. But it is more reusable, readable, effective and it is not God object or Cargo cult programming.
The native codes above are javascript standards and are supported in any decent browser. Three years ago, when Diodeus provided his answer, IE8 was an issue here. But it is dead now (under 2% worldwide according to gs.statcounter). Help it die completely by not supporting it.