Pass "this" from a click event to a function - javascript

The following code is not working. I would like to pass "this" (which would be .dot) from the click event to the function, findTargetSlideOfDot but I'm not sure how to go about doing that. thanks
$(document).on('click', '.dot', function() {
var targetSlide = findTargetSlideOfDot;
changeSlide(targetSlide);
})
function findTargetSlideOfDot() {
// find the slide number the user wants to see
var get = $.grep(this.className.split(" "), function(v, i){
return v.indexOf('slide_') === 0;
}).join();
var targetSlide = '.' + get;
return targetSlide;
}
function changeSlide(targetSlide) {
// hide current slide and dot
$('.slide.active, .dot.active').removeClass('active');
$(targetSlide).addClass('active');
}

Here:
$(document).on('click', '.dot', function() {
var targetSlide = $(this);
changeSlide(targetSlide);
})
function changeSlide(targetSlide) {
// hide current slide and dot
//$('.slide.active, .dot.active').removeClass('active');
$(targetSlide).toggleClass('active');
}
.dot{
width: 100px; border: 1px solid black;
padding: 10px; margin: 5px;
}
.dot.active{
background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dot">test</div>

Give this a shot, modify your click function like this:
$(document).on('click', '.dot', function(e) {
// e.target should refer to the element with the dot class
})
Here's a functional code pen too: http://codepen.io/csavage1994/pen/Mppxaa

You may want to pass it as a parameter an actually call that function. And the improvement shown by Colton should be applied as well:
$(document).on('click', '.dot', function(e) {
var targetSlide = findTargetSlideOfDot( e.target );
changeSlide(targetSlide);
})
function findTargetSlideOfDot( element ) {
// find the slide number the user wants to see
var get = $.grep(element.className.split(" "), function(v, i){
return v.indexOf('slide_') === 0;
}).join();
var targetSlide = '.' + get;
return targetSlide;
}
function changeSlide(targetSlide) {
// hide current slide and dot
$('.slide.active, .dot.active').removeClass('active');
$(targetSlide).addClass('active');
}

You can choose between:
$(document).on('click', '.dot', function(e) {
findTargetSlideOfDot(e.target);
});
which gives you the element that triggered the event (was clicked)
and:
$(document).on('click', '.dot', function(e) {
findTargetSlideOfDot(e.currentTarget);
});
which gives you the element that had the event listener registered.

Related

why do these similiar functions not work?

I have some divs and if i hover them I want an popup to show. I have six divs and six popups to show but not all at once instead only one per one.
The first function works fine but then the other do not work how can I move them all to one snippet?
<script>
document.addEventListener('DOMContentLoaded', function() {
let elements = document.querySelectorAll('#Mitarbeiter1Punkt');
let popupposts = ['647'];
elements.forEach(function(e, i) {
e.addEventListener('mouseenter', function() {
elementorProFrontend.modules.popup.showPopup({
id: popupposts[i]
});
});
e.addEventListener('mouseleave', function(event) {
jQuery('body').click();
});
});
});
document.addEventListener('DOMContentLoaded', function() {
let elements = document.querySelectorAll('#Mitarbeiter2Punkt');
let popupposts = ['656'];
elements.forEach(function(e, i) {
e.addEventListener('mouseenter', function() {
elementorProFrontend.modules.popup.showPopup({
id: popupposts[i]
});
});
e.addEventListener('mouseleave', function(event) {
jQuery('body').click();
});
});
});
</script>
An alternative option would be to make this data-driven rather code-driven - ie the data is in the HTML, not the js. And as you're using jquery already, make use of jquery.
It's unlikely this will fix the root-cause of your issue as that's not been established (still waiting for complete sample) - this is to show how to combine this into a single function that doesn't need to be changed as you add new HTML.
$(".punkt").on("mouseenter", function() {
var id = $(this).data("popup-id");
$(".popup[data-popup-id='" + id + "']").show();
});
$(".punkt").on("mouseleave", function() {
var id = $(this).data("popup-id");
$(".popup[data-popup-id='" + id + "']").hide();
});
div {
border: 1px solid rebeccapurple;
width: 50px;
height: 50px;
text-align: center;
}
.popup {
display: none;
}
<div class='punkt' data-popup-id='A'>
1
</div>
<div class='punkt' data-popup-id='B'>
2
</div>
<div class='popup' data-popup-id='A'>
A
</div>
<div class='popup' data-popup-id='B'>
B
</div>
I would use an array of objects that maps the div IDs to the popup IDs. Loop over the array and set up all the event listeners.
document.addEventListener('DOMContentLoaded', function() {
let popupMap = [{
div: '#Mitarbeiter1Punkt',
popup: 647
},
{
div: '#Mitarbeiter2Punkt',
popup: 646
}
];
popupMap.forEach(({div, popup}) => {
let e = document.querySelector(div);
e.addEventListener('mouseenter', () => elementorProFrontend.modules.popup.showPopup(popup));
e.addEventListener('mouseleave', () => jQuery('body').click());
});
});
okay so actually i figgered it out myself:
<script>
document.addEventListener('DOMContentLoaded', function() {
let elements = document.querySelectorAll( '.mitarbeiterPunkt' );
let popupposts = [ '647', '656', '660', '664', '664', '668', '672'];
elements.forEach(function(e,i){
e.addEventListener( 'mouseenter', function(){
elementorProFrontend.modules.popup.showPopup( { id: popupposts[i] } );
} );
e.addEventListener( 'mouseleave', function(event){
jQuery('body').click();
});
});
});
</script>

A function that runs on the second click

I'm running a function that shows a left menu when I click a button.
I need that the menuColapsado() function to run on the first click of the ID menu_button but the function shows the html element on the second click instead of the first.
My code is below
function myFunctionxxx() {
var xxx = document.getElementsByTagName("BODY")[0];
xxx.style.backgroundColor = "red";
}
$(document).ready(function() {
$('#menu_links').css({
width: '50px'
});
$('.collapse-menu').addClass('hidden');
$('ul#menu_links li').hover(function() {
$('span', this).addClass('show');
$('span', this).removeClass('hidden');
}, function() {
$('span', this).addClass('hidden');
$('span', this).removeClass('show');
});
$("#menu_button").click(function() {
menuColapsado();
});
$('a.test').on("click", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
// });
var clic = 1;
function menuColapsado() {
if (clic == 1) {
$('#menu_links').animate({
width: '50px'
}, 350);
clic = clic + 1;
$('.collapse-menu').removeClass('show');
$('.collapse-menu').addClass('hidden');
$('ul#menu_links li').hover(function() {
$('span', this).addClass('show');
$('span', this).removeClass('hidden');
}, function() {
$('span', this).addClass('hidden');
$('span', this).removeClass('show');
});
} else {
$('#menu_links').animate({
width: '200px'
}, 350);
clic = 1;
$('.collapse-menu').addClass('show');
$('.collapse-menu').removeClass('hidden');
$('ul#menu_links li').hover(function() {
}, function() {
$('span', this).addClass('show');
$('span', this).removeClass('hidden');
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="menu_button" onclick="myFunctionxxx();"></button>
So, from what I understand, you have a button and you want to run a function the first time it is clicked and another function the second time it is clicked.
Here is a simple solution with a counter and an If statement:
var timesClicked = 0;
$("#menu_button").click(function() {
timesClicked++;
if (timesClicked>1) {
//run second function
} else {
//run first function
}
})
The above code will run the second function for every other time the button is clicked. You can easily change it to suit your needs if you do not want this to happen.
If you want to use every 3rd, 5th, 7th etc click as a first click and every 4th, 6th, 8th etc click as a second click, you can change the If statement and use modulo division:
var timesClicked = 0;
$("#menu_button").click(function() {
timesClicked++;
if (timesClicked%2==0) {
//run second function
} else {
//run first function
}
})
Check modulo division: How can I use modulo operator (%) in JavaScript?

How can I detect if a selector clicked?

What is the best way to detect if a jQuery-selector clicked. i mean:
var elem = 'foo'
var action = $(elem ).mouseenter(function(){
$(this).css('background-image',url(elem +'.png'))
});
var elem = 'bar'
//do the same action with new elem
var elem = 'blah'
//do the same action with new elem
the problem is how can i shorten this code to one line:
$('.far').mouseenter(function(){$(this).css('background-image',url(far.png'))});
$('.foooo').mouseenter(function(){$(this).css('background-image',url(foooo.png'))});
$('.bar').mouseenter(function(){$(this).css('background-image',url(bar.png'))});
$('.some').mouseenter(function(){$(this).css('background-image',url(some.png'))});
try making this array
var arr = [ "far", "foooo", "bar", "some" ];
arr.forEach( function( item ){
$('.' + item ).mouseenter(function(){$(this).css('background-image','url('+ item +'.png'))});
//adding the click detection as well
$('.' + item ).click(function(){$(this).css('background-image','url('+ item +'.png'))});
});
$(function() {
$(document).on('mouseenter', 'div[data-background]', function() {
$(this).css({'background' : 'url('+$(this).data('background')+')',});
});
});
div {
width : 500px;
height : 320px;
border : 1px solid #A2A2A2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head></head>
<body>
<div data-background="https://cdn.pixabay.com/photo/2017/04/04/14/23/peacock-2201428_960_720.jpg"></div>
<div data-background="https://cdn.pixabay.com/photo/2013/07/12/18/59/peacock-154128_960_720.png"></div>
</body>
</html>
Works only in this situation.
Since you have single class selector,assuming you don't have multiple classes
$('.far','.foooo','.bar','.some').mouseenter(function(){
var selector = $(this).attr('class');
$(this).css('background-image',url(selector+'.png'));
});
You need something like this:
$(".foo").click(function (event) {
$(this).css("color", "red");
});
Again, you need click, not mouseenter. Because mouseenter is just a hover, which you could do with plain css.

keyup event resets input field

Every time I press a key on my keyboard, it sets $(this).val(""); to null and the score variable will be -2.
initialize: function() {
var score = 0;
var wrapper = $('<div>')
.css({
position:'fixed',
top:'0',
left:'0',
width:'100%',
height:'100%'
});
this.wrapper = wrapper;
var self = this;
var text_input = $('<input>')
.addClass('form-control')
.css({
'border-radius':'4px',
position:'absolute',
bottom:'0',
'min-width':'80%',
width:'80%',
'margin-bottom':'10px',
'z-index':'1000'
}).keyup(function() {
var words = self.model.get('words');
for(var i = 0;i < words.length;i++) {
var word = words.at(i);
var typed_string = $(this).val();
var string = word.get('string');
if(string.toLowerCase().indexOf(typed_string.toLowerCase()) === 0) {
word.set({highlight:typed_string.length});
if(typed_string.length === string.length) {
$(this).val("");
score+=10;
$("#dialog").dialog('option', 'title', 'Score : '+score);
}
}
else {
word.set({highlight:0});
$(this).val(""); // problem
score-=2; // problem
$("#dialog").dialog('option', 'title', 'Score : '+score); // problem
}
}
});
$(this.el)
.append(wrapper
.append($('<form>')
.attr({
role:'form'
})
.submit(function() {
return false;
})
.append(text_input)));
text_input.css({left:((wrapper.width() - text_input.width()) / 2) + 'px'});
text_input.focus();
this.listenTo(this.model, 'change', this.render);
},
When I remove the code that causes the problem, it works perfectly every time. inputting the right word and giving the var score score of +10.
How the keyup event works?
The keyup event is triggered every time a key is released.
This means that if the target word is haromy, when typing the h, the event is triggered and the code in the callback is run.
It means that the following will always be false if typing the first letter wrong.
"haromy".toLowerCase().indexOf("f".toLowerCase()) === 0
So the user types a letter, it's not the same first letter, so the field is emptied immediatly by $(this).val("").
Maybe use another event?
If you want to check once the user unfocus the input, the blur event would work.
If you want to make the check when the user clicks a button, use a click event on a new button.
How to stylize a JavaScript application?
Do not set the initial CSS using jQuery's css function. Keep the styling in a CSS file linked in the HTML.
Using the css function only clutters your application logic, makes it difficult to maintain and delay the application of the style to after the JavaScript execution.
How to bind jQuery events with Backbone?
I removed the backbone.js tag from the question as it's irrelevant, but seeing that you're using it and that it could be improved a lot, I'll throw additional information here.
When using Backbone, don't bind events using jQuery directly. Use the Backbone view's events hash.
Your view could look like this:
var View = Backbone.View.extend({
template: '<div class="wrapper"><input class="form-control" /></div>'
events: {
"blur input": "onInputBlur"
},
onInputBlur: function() {
var words = this.model.get('words').each(function(word) {
var typed_string = this.$input.val(),
string = word.get('string');
// Check each word and score here
}, this);
},
initialize: function() {
this.score = 0;
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html(this.template);
this.$wrapper = this.$('.wrapper');
this.$input = this.$('input').focus();
return this;
},
});
With styles out, the CSS file would be:
.wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.input {
border-radius: 4px;
position: absolute;
bottom: 0;
min-width: 80%;
width: 80%;
margin-bottom: 10px;
z-index: 1000;
}

mootools toggle button problem

I'm trying to code a function that let me toggle in and out all thumbnails in a list depending on their classes.
e.g., if I click "print" on my menu bar, I need all thumbs with the "print" class to be hidden. If I click it a second time, the hidden thumbs are showing up.
Here is what I came up with :
window.addEvent('domready', function(){
$$('.menu_button').toggle(
function() {
this.fade(0.5);
var buttonId = this.id;
$('slider_list').getElements('.'+buttonId).each(function(li) {
li.tween('width','0');
});
},
function() {
this.fade(1);
var buttonId = this.id;
$('slider_list').getElements('.'+buttonId).each(function(li) {
li.tween('width','100');
});
}
);
});
//toggle (emulate JQuery's toggle)
(function() {
var toggled = 0;
Element.implement({
toggle: function(fn1, fn2) {
var fns = [fn1, fn2];
return this.addEvent('click', function(){
fns[toggled].apply(this, arguments);
toggled = toggled == 0 ? 1 : 0;
});
}
});
})();
I've found the toggle function here
Now I experience some issues.
First no matter what I do there will always be a thumb left at the end of the list.
Then some clicks on the menu won't do anything. Generally when I click on a button in a different state (hidden/shown) than the previous one, there will always be a null click...
Anybody ?
I implemented it in a way that allows multiple functions, although not at all MooTools like, it will work. The problem with the code you are using is that each element which uses toggle is toggling the same toggled variable
Element.implement({
toggle: function() {
this.store('toggle_options', {
fn: arguments,
cur: 0
});
this.addEvent('click', function(e) {
e.stop();
var opts = this.retrieve('toggle_options');
console.log(opts.fn.length, opts.cur);
opts.fn[opts.cur++].apply(this);
if(opts.cur >= opts.fn.length) opts.cur = 0;
});
}
});
$('button').toggle(
function() {
this.set('text', 'foo 1');
},
function() {
this.set('text', 'bar 2');
}
);
fiddle here: http://jsfiddle.net/94FFj/
Although I would recommend you implemented your code as this:
$$('.menu_button').each(function(button) {
button.store('toggle_active', 0);
button.addEvent('click', function(e) {
e.stop();
var active = this.retrieve('toggle_active');
var opts = [{opacity: 1, width: 0}, {opacity: 0.5, width: 100}];
this.fade(opts[active].opacity);
$$('slider_list .' + this.get('id')).tween('width', opts[active].width);
this.store('toggle_active', active ? 0 : 1);
});
})

Categories