why do these similiar functions not work? - javascript

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>

Related

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.

Pass "this" from a click event to a function

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.

Hover father div > show child div. OnMouseOut > hide child div after X seconds

Trying to show the <span> when mouseover the <div> and after 5 seconds hide the <span>. Can't get this to work.
$(document).ready(function() {
altDiv = $(this).attr('alt');
var timeout;
$('.ShowCat').on("mouseover", function(e) {
$('#' + altDiv).show();
clearTimeout(timeout);
});
$('.ShowCat').on("mouseout", function() {
timeout = setTimeout(function() {
$('#' + altDiv).hide();
}, 5000);
});
});
.hide {
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div alt="REF-C000000" class="ShowCat">C000000</div>
<span id="REF-C000000" class="hide">C1 C2 C3</span>
<br>
<div alt="REF-C000001" class="ShowCat">C000001</div>
<span id="REF-C000001" class="hide">C4 C5 C6</span>
Thanks for any info.
No need to reference the ID of the <span> in the <div> if the markup is always going to be a <div> followed by a <span>. Use jQuery next() method to get the immediate next sibling element.
var $show = $( '.ShowCat' );
$show.on( 'mouseover', function ( e ) {
var $this = $( this );
clearTimeout( $this.data( 'tID' ) );
$this.next().show();
} );
$show.on( 'mouseout', function ( e ) {
var $this = $( this );
$this.data( 'tID', setTimeout( function () {
$this.next().hide();
}, 5000 ) );
} );
.hide {
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="ShowCat">C000000</div>
<span id="REF-C000000" class="hide">C1 C2 C3</span>
<br>
<div class="ShowCat">C000001</div>
<span id="REF-C000001" class="hide">C4 C5 C6</span>
With my solution I'm assuming you always want the <span> to hide five seconds after they mouseout the <div>. To do this I had to re-work how setTimeout() was being handled. Your original code was canceling the five second setTimeout() whenever another .ShowCat was hovered, effectively leaving it visible.
Example of Original Side Effect
var $show = $( '.ShowCat' ),
tID;
$show.on( 'mouseover', function ( e ) {
var $this = $( this );
clearTimeout( tID );
$this.next().show();
} );
$show.on( 'mouseout', function ( e ) {
var $this = $( this );
tID = setTimeout( function () {
$this.next().hide();
}, 5000 );
} );
.hide {
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="ShowCat">C000000</div>
<span id="REF-C000000" class="hide">C1 C2 C3</span>
<br>
<div class="ShowCat">C000001</div>
<span id="REF-C000001" class="hide">C4 C5 C6</span>
Hover the first <div> then hover the second <div> without re-hovering the first <div>, first <span> stays red while second <span> disappears.
If you do need to reference the <span> ID on the <div> I'd recommend using a data- attribute as alt is not a valid attribute for a <div>. alt is valid for the following elements: <applet>, <area>, <img>, <input>.
your code does work, you are assigning the value of altDiv in the wrong place...
change your JS to:
$(document).ready(function () {
let altDiv = ""
var timeout;
$('.ShowCat').on("mouseover", function(e) {
altDiv = $(this).attr('alt');
//console.log(altDiv);
$('#' + altDiv).show();
clearTimeout(timeout);
});
$('.ShowCat').on("mouseout", function() {
timeout = setTimeout(function() { $('#' + altDiv).hide(); }, 5000);
});
});
This line of code
altDiv = $(this).attr('alt');
is not doing what you think. this points to the parent function scope, in this case, the function that .ready is calling; it is not referencing the element that you are hovering. Instead, you should capture the value of the alt attribute within your handler:
$('.ShowCat').on("mouseover", function(e) {
var altDiv = $(this).attr('alt');
$('#' + altDiv).show();
clearTimeout(timeout);
});
Note alt attribute on the div element is invalid, so I'd recommend instead using data-alt="..." and getting it with .data instead:
var altDiv = $(this).data('alt');
In this solution a timeout is associated to each ShowCat element, not sure if this applies to your requirements:
$(document).ready(function () {
$('.ShowCat').on("mouseover", function(e) {
var timeout = $(this).data('timeout');
clearTimeout(timeout);
var altDiv = $(this).attr('alt');
$('#' + altDiv).show();
});
$('.ShowCat').on("mouseout", function() {
var altDiv = $(this).attr('alt');
var timeout = setTimeout(function() { $('#' + altDiv).hide(); }, 5000);
$(this).data('timeout', timeout);
});
});
.hide {
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div alt="REF-C000000" class="ShowCat">C000000</div>
<span id="REF-C000000" class="hide">C1 C2 C3</span>
<br>
<div alt="REF-C000001" class="ShowCat">C000001</div>
<span id="REF-C000001" class="hide">C4 C5 C6</span>

How to fire event after 3 sec of hovering

I have a div and I want to fire an event only after user continuous hovers his mouse for 3 sec. My code doesn't work well because it fires right after hover and doesn't "wait".
Code:
$(".inner_pic").mouseenter(function () {
setTimeout(function () {
alert('testing');
}, 3000);
}).mouseleave(function () {
alert('finish');
});
You need to store timeout id somewhere and clear it on mouseout. It's convenient to use data property to save this id:
$(".inner_pic").mouseenter(function () {
$(this).data('timeout', setTimeout(function () {
alert('testing');
}, 3000));
}).mouseleave(function () {
clearTimeout($(this).data('timeout'));
alert('finish');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inner_pic">PICTURE</div>
You can achieve this by delay option:
Working demo
$('#elem').popover({
trigger: "hover",
delay: {show : 3000, hide : 0} });
Checkout the below code
var myVar;
$( "div#container" )
.mouseover(function() {
myVar = setTimeout(function(){ alert("Hello"); }, 3000);
})
.mouseout(function() {
clearTimeout(myVar);
});
div {
background: red;
margin: 20px;
height: 100px;
width: 100px;
display:block;
cursor: pointer;
}
div:hover {
background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
var st;
$(".inner_pic").mouseenter(function(e) {
var that = this;
st = setTimeout(function() {
alert('testing');
}, 3000);
}).mouseleave(function() {
clearTimeout( st );
alert('finish');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inner_pic">
<h3>Picture Here - Hover me</h3>
</div>
Assuming you have a div with id of myelement, you can do this:
var divMouseOver;
$('#myelement').mouseover(function() {
divMouseOver = setTimeout(function() {
alert("3 seconds!"); //change this to your action
}, 3000);
});
$('#myelement').mouseout(function() {
if (divMouseOver) {
clearTimeout(divMouseOver);
}
});
BTW, tere's a helpful clarifying question re: using mouseenter and mouseover right here: Jquery mouseenter() vs mouseover(). Consider this when choosing which to use.

Masonry images overlapping issue

the title pretty much says everything, I did look into the images plugin from masonry yet I had no luck, I wonder if anyone could help?
The script does many things, it has the filter bit, the animation, show/hide, ajax to get the content etc etc. I'd be happy if anyone could investigate into why it is overlapping and how i could solve it based on the code below:
jQuery(function(){
jQuery('#container').masonry({
itemSelector: '.box',
animate: true
});
});
(function ($) {
// Get all menu items with IDs starting with "filter-" and loop over them
$(".menu li[id|=filter]").each(function () {
// Get the ID add extract the page class name from it (remove "filter-" from it)
var type = $(this).attr("id").replace("filter-", "");
// Get the items in the "webbies" list with that class name
var items = $("#container div[class~=" + type + "]");
// Don't do anything if there aren't any
if (items.length == 0) return;
// Get a list of the other items in the list
var others = $("#container>div:not([class~=" + type + "])");
// Add a click event to the menu item
$("a", this).click(function (e) {
// Stop the link
e.preventDefault();
// Close open item
if (openItem) {
close(openItem);
}
items.removeClass("inactive").animate({opacity: 1});
others.addClass("inactive").animate({opacity: 0.2});
});
});
$(".reset-filter a").click(function (e) {
e.preventDefault();
if (openItem) close(openItem);
$("div.box.inactive").removeClass("inactive").animate({opacity: 1});
});
var openItem;
// Opens an item
var open = function (item) {
// Close open item
if (openItem) close(openItem);
item.addClass("loading");
$("img", item).first().hide();
item.width(340);
item.height(600);
if (!item.data('loaded')) {
$("div.fader", item).load($("a", item).first().attr("href") + " #content", function () {
stButtons.locateElements();
stButtons.makeButtons();
stWidget.init();
$("#container").masonry('reloadItems', function () {
$("div.fader", item).animate({opacity: 1}, function () {
item.removeClass("loading");
$('Close"').appendTo(this).click(function (e) {
e.preventDefault();
close(item);
$(document).scrollTo( $("#navigation-block"), 600, {offset:-50} );
});
$("div.info", item).fadeIn("slow", function () {
$(document).scrollTo( $(".info"), 600, {offset:80} );
});
});
});
item.data('loaded', true);
});
} else {
item.removeClass("loading");
$("#container").masonry('reloadItems', function () {
$("div.fader", item).animate({opacity: 1}, function () {
$("div.info", item).fadeIn("slow", function () {
$(document).scrollTo( $(".info"), 600, {offset:80} );
});
});
});
}
// Set open item
openItem = item;
};
// Closes an item
var close = function (item) {
$("div.fader", item).animate({opacity: 0});
$("div.info", item).hide();
item.animate({width: 150, height: 100}, function () {
$("img", item).first().fadeIn("slow");
$("#container").masonry('reloadItems');
});
// Reset open item
openItem = null;
};
$("#container div.box").each(function () {
var item = $(this);
item.data('loaded', false);
$("div.fader", item).css("opacity", 0);
$("a.close", item).click(function (e) {
e.preventDefault();
close(item);
$(document).scrollTo( $("#navigation-block"), 600, {offset:-50} );
});
$("a.showMe", item).click(function (e) {
e.preventDefault();
if (item.hasClass("inactive")) return;
open(item);
});
});
})(jQuery);
</script>
I've experienced the same problem and I developed 2 methods to combat it. First off reload the container after you have appended the onclick-image.
1. container.masonry('reload');
Second, and probably more important, dynamically correct the height of the surrounding div to match the height of the image:
2. // bricks correct height
var brick = $("#marker #container .brick");
brick.each(function() {
var content = $(this).find(">div");
var img = $(this).find("img");
content.css({
height: img.attr("height")
});
});
So my brick is looking like this:
<div style="height: 284px; position: static; top: -133px;" class="test">
<a class="arrow" href="#" target="_self"><img class="img" src="test.jpg" width="374" height="284"></a>
</div>
Edit: In your code you have the same problem, there is no height in the style.
<div style="position: absolute; left: 330px; top: 280px;" class="box item 3d">
And it seems to me you have a problem with the width, too. I think you need to use a smaller width for the column. A good value would be the width of the small image and some border.
jQuery(function(){
var $container = $('#container');
$container.imagesLoaded( function () {
itemSelector: '.box',
animate: true
});
});
Source: jQuery Masonry Images

Categories