Everything works here but I need to keep moving act up and down while mouse button is pressed, without repeated clicks.
Any help?
$('button').on('click', function(){
let a = $('.act');
a.insertBefore(a.prev());
});
$('button').on('contextmenu', function(e){
e.preventDefault();
let a = $('.act');
a.insertAfter(a.next());
});
.act{background:gold;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class='title act'>LOREM</div>
<div class='title'>IPSUM</div>
<div class='title'>DOLOR</div>
<div class='title'>SIT</div>
<div class='title'>AMET</div>
</div>
<br>
<button>CLICK</button>
Instead of the click and contextmenu events you'll have to use mouse events, here is an example:
let intervalId;
const a = $('.act');
$('button').on('mousedown', function(event) {
function fn () {
if (event.button == 0) {
a.insertBefore(a.prev());
} else if (event.button == 2) {
a.insertAfter(a.next());
}
return fn;
};
intervalId = setInterval(fn(), 500);
});
$(document).on('mouseup', function(event) {
clearInterval(intervalId);
});
$('button').on('contextmenu', function(event) {
event.preventDefault();
});
.act {
background: gold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class='title act'>LOREM</div>
<div class='title'>IPSUM</div>
<div class='title'>DOLOR</div>
<div class='title'>SIT</div>
<div class='title'>AMET</div>
</div>
<br>
<button>CLICK</button>
In this example, I'm using an interval to move the element every 500 milliseconds while the mouse pointer is down, I'm also preventing the contextmenu event so that the context menu will not consume the mouseup event itself.
I've made a fiddle to illustrate:
https://jsfiddle.net/10cgxohk/
html:
<p class="">x</p>
css:
.move {
animation: MoveUpDown 1s linear infinite;
position: relative;
left: 0;
bottom: 0;
}
#keyframes MoveUpDown {
0%, 100% {
bottom: 0;
}
50% {
bottom: 15px;
}
}
javascript:
$('body').on('mousedown', function() {
$('p').addClass('move');
$('body').on('mouseup', function() {
$('p').removeClass('move');
$('body').off('mouseup');
console.log('here');
})
});
This is really rough and creates an issue if you have other 'mouseup' callbacks on the body, but if that's not a worry for you then it should work. The javascript is adding a class to the element, and the class is animated in css
Related
This question already has answers here:
jQuery click event not working after adding class
(7 answers)
Closed 2 years ago.
I have some card to flip and check if one is equal to another (memory game).
If I flip the card, I don't want that is possible to click and run function if I click on the same card (that is .flipped) or on another that is flipped. But jQuery .not() and :not not working. Maybe I must read another time the DOM after .toggleClass?
$(".card:not('.flipped')").on("click", function () {
$(this).toggleClass("flipped");
if (first) {
firstCard = $(this).attr("game");
first = false;
} else {
secondCard = $(this).attr("game");
first = true;
checkGame();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The code is binding the events when it is called. So whatver the classes are at that moment in time, is what it finds and binds the event.
So you need to check for the class inside of the method and exit it
$(".card").on("click", function() {
var card = $(this);
if (card.hasClass("flipped")) return;
console.log(this);
card.addClass("flipped");
});
.wrapper {
display: flex;
}
.wrapper > .card {
flex: 1;
text-align: center;
line-height: 50px;
font-size: 30px;
}
.card.flipped {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
</div>
Other option is using event delegation where you bind the event to the parent and element and have jQuery do the checking if the class is added yet.
$(".wrapper").on("click", ".card:not('.flipped')", function() {
console.log(this);
var card = $(this);
card.addClass("flipped");
});
.wrapper {
display: flex;
}
.wrapper > .card {
flex: 1;
text-align: center;
line-height: 50px;
font-size: 30px;
}
.card.flipped {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
</div>
Apply the click event to all cards.
On click, check if the card is flipped. If it is, do nothing.
Cache your jQuery objects.
$(".card").on("click", function() {
const $card = $(this);
if ($card.hasClass("flipped")) return;
$card.toggleClass("flipped");
// .........
});
you have to check it inside your event 'click'. if the card has class 'flipped' break it
$(".card").on("click", function () {
if($(this).hasClass('.flipped')) return;
$(this).toggleClass("flipped");
if (first) {
firstCard = $(this).attr("game");
first = false;
} else {
secondCard = $(this).attr("game");
first = true;
checkGame();
}
});
Consider the following markup and script:
<div id="container">
<div draggable="true">
<button type="button" id="button">Drag me!</button>
</div>
<div draggable="true"></div>
<div draggable="true"></div>
<div draggable="true"></div>
<div draggable="true"></div>
</div>
let dragged;
document.getElementById("button").addEventListener("dragstart", function(e)
{
dragged = e.parentNode;
// What to do here?
});
let divs = document.querySelectorAll("#container div");
for (let i=0; i<div.length; i++)
{
divs[i].addEventListener("dragleave", function(e)
{
if (this.nextSibling == dragged) // move downwards
{
this.parentNode.insertBefore(dragged, this);
}
else // move upwards
{
this.parentNode.insertBefore(dragged, this.nextSibling);
}
});
}
I have several of these div elements below each other inside a container. The button element is only appended to one div at a time.
1) I want the div element with the button inside it to pop out of its place and follow the mouse cursor on drag.
2) When the div moves on top of a neighbor div, I want that div to slide into the empty space.
Is there a vanilla JS solution?
From MDN, posting here because OP owner cannot access.
var dragged;
/* events fired on the draggable target */
document.addEventListener("drag", function(event) {
}, false);
document.addEventListener("dragstart", function(event) {
// store a ref. on the dragged elem
dragged = event.target;
// make it half transparent
event.target.style.opacity = .5;
}, false);
document.addEventListener("dragend", function(event) {
// reset the transparency
event.target.style.opacity = "";
}, false);
/* events fired on the drop targets */
document.addEventListener("dragover", function(event) {
// prevent default to allow drop
event.preventDefault();
}, false);
document.addEventListener("dragenter", function(event) {
// highlight potential drop target when the draggable element enters it
if (event.target.className == "dropzone") {
event.target.style.background = "purple";
}
}, false);
document.addEventListener("dragleave", function(event) {
// reset background of potential drop target when the draggable element leaves it
if (event.target.className == "dropzone") {
event.target.style.background = "";
}
}, false);
document.addEventListener("drop", function(event) {
// prevent default action (open as link for some elements)
event.preventDefault();
// move dragged elem to the selected drop target
if (event.target.className == "dropzone") {
event.target.style.background = "";
dragged.parentNode.removeChild(dragged);
event.target.appendChild(dragged);
}
}, false);
#draggable {
width: 200px;
height: 20px;
text-align: center;
background: white;
}
.dropzone {
width: 200px;
height: 20px;
background: blueviolet;
margin-bottom: 10px;
padding: 10px;
}
<div class="dropzone">
<div id="draggable" draggable="true" ondragstart="event.dataTransfer.setData('text/plain',null)">
This div is draggable
</div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
I'm working on a site that has buttons that are generated dynamically.
I'm using jQuery to toggle classes of hidden elements $('.toggle-button').on('click') (i.e. off-canvas cart, sidebar, etc.) based on data attributes
I'm using trigger('click') for the dynamic buttons and passing data through to trigger the correct hidden element. The problem is trigger() is bubbling to other buttons that have class toggle-button or that's what I think the problem is...
I've tried event.stopPropagation() but it doesn't seem to be working.
Here's a simplified version of the code I'm working with.
jQuery(document).ready(function($){
$('.toggle-button').on('click', function(event, triggerData){
console.log('toggle button triggered');
toggleClass = '';
targetSelector = '';
targetElement = '';
if ( !triggerData ) {
toggleClass = $(this).attr('data-toggle');
targetSelector = $(this).attr('data-target');
} else {
toggleClass = triggerData.toggleClass;
targetSelector = triggerData.targetSelector;
}
targetElement = $(targetSelector);
targetElement.toggleClass(toggleClass);
});
$(document).on('click', '.view-cart', function(event){
event.preventDefault();
console.log('view cart button clicked');
$('.toggle-button').trigger('click', {
toggleClass : 'show',
targetSelector : '.cart'
});
});
});
jQuery(document).ready(function($) {
$('.toggle-button').on('click', function(event, triggerData) {
console.log('toggle button triggered');
toggleClass = '';
targetSelector = '';
targetElement = '';
if (!triggerData) {
toggleClass = $(this).attr('data-toggle');
targetSelector = $(this).attr('data-target');
} else {
toggleClass = triggerData.toggleClass;
targetSelector = triggerData.targetSelector;
}
targetElement = $(targetSelector);
targetElement.toggleClass(toggleClass);
});
$(document).on('click', '.view-cart', function(event) {
event.preventDefault();
console.log('view cart button clicked');
$('.toggle-button').trigger('click', {
toggleClass: 'show',
targetSelector: '.cart'
});
});
});
.cart,
.info {
display: block;
padding: 30px;
width: 200px;
border: 1px solid #000;
visibility: hidden;
}
.cart.show,
.info.show {
visibility: visible;
}
.product {
display: inline-block;
width: 150px;
margin: 15px;
background: #e3e3e3;
text-align: center;
}
.product a {
display: block;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<button class="toggle-button" data-toggle="show" data-target=".cart">View Cart</button>
<button class="toggle-button" data-toggle="show" data-target=".info">View Info</button>
<hr>
<div class="product">
<img src="https://via.placeholder.com/150">
View Cart
</div>
<div class="product">
<img src="https://via.placeholder.com/150">
View Cart
</div>
<div class="product">
<img src="https://via.placeholder.com/150">
View Cart
</div>
<div class="product">
<img src="https://via.placeholder.com/150">
View Cart
</div>
<div class="cart">
<span>This is your cart</span>
</div>
<div class="info">
<span>This is additional info</span>
</div>
</body>
</html>
there are two button with class toggle-button ...whose click event is being triggered correctly - while the problem is, that probably only one of them should be triggered. either select the element to click by a combined class attribute or by id attribute. those events are not bubbling at all, the selector just matches two elements - and that's why it subsequently clicks onto two elements.
Your code has two .toggle-button element, so $('.toggle-button').trigger() is running two times.
I recommend to name different class names of these basically.
But there is a other way not to do so, you can use :first selector as shown below.
https://api.jquery.com/first-selector/
jQuery(document).ready(function($){
$('.toggle-button').on('click', function(event, triggerData){
console.log('toggle button triggered');
toggleClass = '';
targetSelector = '';
targetElement = '';
if ( !triggerData ) {
toggleClass = $(this).attr('data-toggle');
targetSelector = $(this).attr('data-target');
} else {
toggleClass = triggerData.toggleClass;
targetSelector = triggerData.targetSelector;
}
targetElement = $(targetSelector);
targetElement.toggleClass(toggleClass);
});
$(document).on('click', '.view-cart', function(event){
event.preventDefault();
console.log('view cart button clicked');
$('.toggle-button:first').trigger('click', {
toggleClass : 'show',
targetSelector : '.cart'
});
});
});
I know the question of closing a pop-up by clicking outside of it has been asked before. I have a somewhat complex pop-up and the solution offered by Phillip Walton isn't working for me.
His code simply made my page blurry but stopped the popup from appearing.
$(document).on('click', function(event) {
if (!$(event.target).closest('.maincontainer').length) {
popup.classList.remove('popup--open');
popup.style.display = 'none';
popupAccessory.style.display = 'none';
popupAccessory.classList.remove('popup--accessory--open');
maincontainer.classList.remove('blurfilter');
}
});
I also tried:
window.addEventListener('click', function(event) {
if (event.target != popup) {
popup.classList.remove('popup--open');
popup.style.display = 'none';
popupAccessory.style.display = 'none';
popupAccessory.classList.remove('popup--accessory--open');
maincontainer.classList.remove('blurfilter');
}
}, true);
This closes the popup when I click anywhere, including on the popup itself. I want it to close only when I click on part of the screen that isn't the popup.
The code to open the popup:
function openpopup() {
popup.style.display = 'initial';
setTimeout(function(){
popup.classList.add('popup--open');
popup.style.boxShadow = '0 0 45px 2px white';
maincontainer.classList.add('blurfilter')}, 10);
for (let i = 0; i < listitems.length; i++ ) {
setTimeout(function() {
listitems[i].classList.add('visible');
}, 100);
}
}
I added the event listener to a button
popupOpenbtn.addEventListener('click', openpopup);
The HTML structure:-
<div class="maincontainer>
...all my page content...
</div>
<div class="popup">
...popup contents...
</div
I would suggest using only css classes to style your popup and use JS only to add, remove and toggle that class. Not sure how close to your working exercise is this fiddle but I've prepared this to show how the document/window click event can be checked to successfully open/close the popup window.
var popupOverlay = document.querySelector('#popup__overlay');
var popupOpenButton = document.querySelector('#popupOpenButton');
var popupCloseButton = document.querySelector('#popupCloseButton');
var mainContainer = document.querySelector('main');
function closestById(el, id) {
while (el.id != id) {
el = el.parentNode;
if (!el) {
return null;
}
}
return el;
}
popupOpenButton.addEventListener('click', function(event) {
popupOverlay.classList.toggle('isVisible');
});
popupCloseButton.addEventListener('click', function(event) {
popupOverlay.classList.toggle('isVisible');
});
mainContainer.addEventListener('click', function(event) {
if (popupOverlay.classList.contains('isVisible') && !closestById(event.target, 'popup__overlay') && event.target !== popupOpenButton) {
popupOverlay.classList.toggle('isVisible');
}
});
#popup__overlay {
display: none;
background-color: rgba(180, 180, 180, 0.5);
position: absolute;
top: 100px;
bottom: 100px;
left: 100px;
right: 100px;
z-index: 9999;
text-align: center;
}
#popup__overlay.isVisible {
display: block;
}
main {
height: 100vh;
}
<aside id="popup__overlay">
<div class="popup">
<h2>Popup title</h2>
<p>
Lorem ipsum
</p>
<button id="popupCloseButton">Close popup</button>
</div>
</aside>
<main>
<div class="buttonWrapper">
<button id="popupOpenButton">Open popup</button>
</div>
</main>
On Click Of the Try Again Button , is it possible to show some processing happening on the device
My jsfiddle
My code as below
$(document).on("click", ".getStarted", function(event) {
// Simulating Net Connection here
var a = 10;
if (a == 10) {
$('#mainlabel').delay(100).fadeIn(300);
$('#nonetconnmain').popup({
history : false
}).popup('open');
event.stopImmediatePropagation();
event.preventDefault();
return false;
}
});
$(document).on('click', '.nonetconnmainclose', function(event) {
$('#nonetconnmain').popup('close');
$(".getStarted").trigger("click");
event.stopImmediatePropagation();
event.preventDefault();
return false;
});
$(document).on("popupbeforeposition", "#nonetconnmain", function(event, ui) {
$('#mainlabel').hide();
});
With my code , the functionality is working , but it seems that the application is not doing any action
So my question is it possible to show any indication (For example , delay , progressbar , anything )
Here ya go
$(document).on("click", ".getStarted", function(event) {
$.mobile.loading("show", {
text: "",
textVisible: true,
theme: "z",
html: ""
});
// Simulating Net Connection here
var a = 10;
if (a == 10) {
setTimeout(function() {
$.mobile.loading("hide");
$('#mainlabel').fadeIn(300);
}, 1000);
$('#nonetconnmain').popup({
history: false
}).popup('open');
event.stopImmediatePropagation();
event.preventDefault();
return false;
}
});
$(document).on('click', '.nonetconnmainclose', function(event) {
$('#nonetconnmain').popup('close');
$(".getStarted").trigger("click");
event.stopImmediatePropagation();
event.preventDefault();
return false;
});
$(document).on("popupbeforeposition", "#nonetconnmain", function(event, ui) {
$('#mainlabel').hide();
});
.popup {
height: 200px;
width: 150px;
}
.popup h6 {
font-size: 1.5em !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<link href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" rel="stylesheet" />
<div data-role="page">
<div data-role="popup" id="nonetconnmain" data-dismissible="false" class="ui-content" data-theme="a">
<div class="popup_inner popup_sm">
<div class="popup_content" style="text-align:center;">
<p class="">Please check net connectivcty</p>
<label id="mainlabel" style="margin:100px auto 60px auto;color:Red; line-height:40px;font-size:medium;display:none">Please check</label>
</div>
<div class="popup_footer nonetconnmainclose">
<a class="">Try Again</a>
</div>
</div>
</div>
<button class="getStarted btn btn-a get_btn">Click Here</button>
</div>
You can use a small function (with time as parameter) and use jQuery animate() to create the process effect like below.
var updateProgress = function(t) {
$( "#p" ).css("width",0);
$( "#p" ).show();
$( "#p" ).animate({ "width": "100%" }, t , "linear", function() {
$(this).hide();
});
}
Do notice that the time that is chosen when calling updateProgress() is relevant with the delay and the fade in effect of the text message
updateProgress(3500);
$('#mainlabel').delay(3400).fadeIn(600);
Check it on the snippet below
var updateProgress = function(t) {
$( "#p" ).css("width",0);
$( "#p" ).show();
$( "#p" ).animate({ "width": "100%" }, t , "linear", function() {
$(this).hide();
});
}
$(document).on("click", ".getStarted", function(event) {
var a = 10;
if(a==10)
{
updateProgress(3500);
$('#mainlabel').delay(3400).fadeIn(600);
$('#nonetconnmain').popup({history: false}).popup('open');
event.stopImmediatePropagation();
event.preventDefault();
return false;
}
});
$(document).on('click', '.nonetconnmainclose', function(event) {
$('#nonetconnmain').popup('close');
$(".getStarted").trigger("click");
event.stopImmediatePropagation();
event.preventDefault();
return false;
});
$(document).on("popupbeforeposition", "#nonetconnmain",function( event, ui ) {
$('#mainlabel').hide();
});
.popup {
height: 200px;
width: 400px;
}
.popup h6 {
font-size: 1.5em !important;
}
#p {
border:none;
height:1em;
background: #0063a6;
width:0%;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<link href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" rel="stylesheet"/>
<div data-role="page">
<div data-role="popup" id="nonetconnmain" data-dismissible="false" class="ui-content" data-theme="a">
<div class="popup_inner popup_sm">
<div class="popup_content" style="text-align:center;">
<p class="">Please check net connectivcty</p>
<div id="p"></div><br>
<label id="mainlabel" style="margin:100px auto 60px auto;color:Red; line-height:40px;font-size:medium;display:none">Please check </label>
</div>
<div class="popup_footer nonetconnmainclose">
<a class="">Try Again</a>
</div>
</div>
</div>
<button class="getStarted btn btn-a get_btn">Click Here</button>
</div>
Fiddle
Probably when you click on try again , you can have a setinterval triggered which can check for online connectivity and when found can close the popup and get started again, also when we do retries in the interval the progress can be shown as progressing dots..
Below is the code, i haven't tried to run the code, but it shows the idea
$(document).on('click', '.nonetconnmainclose', function(event) {
var msgUI = $("#mainlabel");
msgUI.data("previoustext",msgUI.html()).html("retrying...");
var progress = [];
var counter = 0 ,timeout = 5;
var clearIt = setInterval(function(){
var online = navigator.onLine;
progress.push(".");
if(counter > timeout && !online){
msgUI.html(msgUI.data("previoustext"));
counter=0;
}
if(online){
$('#nonetconnmain').popup('close');
$(".getStarted").trigger("click");
counter=0;
clearInterval(clearIt);
}
else{
msgUI.html("retrying" + progress.join(""));
counter++;
}
},1000);
event.stopImmediatePropagation();
event.preventDefault();
return false;
});
Sure,
try appending a loader GIF to one of the div and remember to remove the same when your process is finished.
Kindly refer to StackOverflow
And try appending this
$('#nonetconnmain').append('<center><img style="height: 50px; position:relative; top:100px;" src="cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/images/…; alt="loading..."></center>');
This will append a loader to your HTML to show some kind of processing.