When scrolling flashing background color - javascript

My code is to apply div background-color when user touchstart on each div. that's clear for you.
Then when user scrolling, I use $(window).scroll.. event to reset or remove background-color for all div's.
But my problem is: when user (touch + scrolling) at div's, background-color is flashing out color! I want to: don't change div background-color when (tap, touch + scrolling). if you don't understand my question, you can see: (facebook messenger friend conversations, snapchat conversations, stories ..etc)
Flashing div's:
My code: https://www.w3schools.com/code/tryit.asp?filename=GLUIAUU64MDX - RUN ON TOUCH DEVICES.
$(window).scroll(function() {
resetBg();
});
$(".❄").on('touchstart', function() {
$(this).css("background-color", "#7bffea");
});
$(".❄").on('touchend mouseleave mouseup blur click', function() {
resetBg();
});
function resetBg() {
$(".❄").css("background-color", "");
}
div.❄ {
display: block;
height: 150px;
border: 1px solid black;
margin: 10px 0px;
padding: 0px;
border-radius: 8px;
background-color: #ffffff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>
<div class="❄"></div>

Instead of setting background on touchstart, you can get the pointer position at touchstart and on touchend check if pointer position is changed or not. If not, change the div background and set a timeout function to reset it. If the position of pointer is changed then it's a scroll so you don't need to change the background
let initialY = null;
$(".❄").on('touchstart', function(e) {
initialY = e.clientY;
});
$(".❄").on('touchend', function(e) {
if(e.clientY===initialY){
$(this).css("background-color", "#7bffea");
setTimeout(()=>{ //This is optional
resetBg();
},100);
}
});
function resetBg() {
$(".❄").css("background-color", "");
}

try this
$(window).scroll(function() {
resetBg();
});
//----------------------------------------------
$(document).on('touchstart', '.❄', function(evt) {
var that = this;
var oldScrollTop = $(window).scrollTop();
window.setTimeout(function() {
var newScrollTop = $(window).scrollTop();
if (Math.abs(oldScrollTop - newScrollTop) < 3) $(that).css("background-color", "#7bffea");
}, 200);
});
$(".❄").on('touchend touchmove mouseleave mouseup blur click', function() {
resetBg();
});
function resetBg() {
$(".❄").css("background-color", "");
}

Related

SlideToggle open only one container at a time Vanilla JS

Maybe someone know how to open only one container at a time? Now in this example you can open all three? I would like to open only one and when it's opened change text to "Close". Any ideas?
Here is the link with a code to codepen: code https://codepen.io/jorgemaiden/pen/YgGZMg
I'll be really apreciate for any help and tips!
You can do it in many ways, but according to your reference, I would just add function that loop through your elements which is not your clicked element, then remove active class if it's present
var linkToggle = document.querySelectorAll(".js-toggle");
for (i = 0; i < linkToggle.length; i++) {
linkToggle[i].addEventListener("click", function(event) {
event.preventDefault();
var container = document.getElementById(this.dataset.container);
this.innerText = "Close";
toggleSlide(container);
});
}
function toggleSlide(container) {
for (i = 0; i < linkToggle.length; i++) {
let el = document.getElementById(linkToggle[i].dataset.container);
if (el != container && el.classList.contains("active")) {
el.style.height = "0px";
linkToggle[i].innerText = "Click";
el.addEventListener(
"transitionend",
function() {
el.classList.remove("active");
}, {
once: true
}
);
}
}
if (!container.classList.contains("active")) {
container.classList.add("active");
container.style.height = "auto";
var height = container.clientHeight + "px";
container.style.height = "0px";
setTimeout(function() {
container.style.height = height;
}, 0);
} else {
container.style.height = "0px";
container.addEventListener(
"transitionend",
function() {
container.classList.remove("active");
}, {
once: true
}
);
}
}
.box {
width: 300px;
border: 1px solid #000;
margin: 10px;
cursor: pointer;
}
.toggle-container {
transition: height 0.35s ease-in-out;
overflow: hidden;
}
.toggle-container:not(.active) {
display: none;
}
<div class="box">
<div class="js-toggle" data-container="toggle-1">Click</div>
<div class="toggle-container" id="toggle-1">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>
<div class="box">
<div class="js-toggle active" data-container="toggle-2">Click</div>
<div class="toggle-container open" id="toggle-2">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>
<div class="box">
<div class="js-toggle" data-container="toggle-3">Click</div>
<div class="toggle-container" id="toggle-3">I have an accordion and am animating the the height for a show reveal - the issue is the height which i need to set to auto as the information is different lengths.<br><br> I have an accordion and am animating the the height fferent lengths.
</div>
</div>

Disable element scrolling with keyboard arrows

Fiddle
So I'm trying to disable scrolling of a div when another div is visible.
The code bellow I'm using does just that, but only when using mousewheel to scroll.
If I click the scrollbar and drag it, or if I focus the div and use keyboard down button, the scrolling still happens.
Why is that and how can I solve my problem (possibly without overlaying a transparent element over my scrollbar or similar "hacks")?
$('#element').on('scroll mousewheel keydown keypress keyup', function (event) {
const element = $(event.currentTarget);
const shouldScroll = false;
if (!shouldScroll) {
event.preventDefault();
event.stopPropagation();
return false;
}
});
Why don't you do it like this?
var scrollEnabled = true;
var scrollX = 0;
var scrollY = 0;
$(document).ready(function() {
$('div.outer').on('scroll', function(event) {
if (!scrollEnabled) this.scrollTo(scrollX, scrollY);
});
$('#tglBtn').on('click', function(event) {
if (scrollEnabled == true) {
scrollEnabled = false;
scrollX = $('div.outer').scrollLeft();
scrollY = $('div.outer').scrollTop();
} else {
scrollEnabled = true;
}
});
});
div.outer {
height: 500px;
width: 500px;
background-color: red;
overflow-y: scroll;
}
div.inner {
height: 200px;
width: 500px;
}
div.inner:nth-child(odd) {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="tglBtn" value="Enable/Disable scrolling" />
<div class="outer">
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
<div class="inner">
</div>
</div>

Trigger multiple click events while a button or anchor is pressed using JQuery

I have a situation in which I click the button, and it does some action like the following:
var pos = 1;
$('.right').click(function(){
$('.box').css({'left': pos++ });
});
$('.left').click(function(){
$('.box').css({'left': pos-- });
});
.box{
background-color: gray;
height:20px;
width: 20px;
left: 0;
position: relative;
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="left" button-held>Left</button>
<button class="right" button-held>Right</button>
<div class="box"></div>
What I need is that when the user clicks on the button and leave it pressed, that it do this action multiple times until the button is released.
Any ideas on how to do this? I have already search the internet for a while but it's quite difficult to find an answer as there are lots of questions about events, also I found an Angular solution if someone wants to check it out (Angular solution).
Thanks in advance.
Instead of listening for click, do this:
Listen for mousedown and mouseup.
On mousedown, perform the action and set a timer to perform it again in a moment via setTimeout. Remember the timer handle (the return value).
When the timer goes off and you do the action again, schedule it to happen again in a moment, again via setTimeout, again remembering the handle.
When you see mouseup, cancel the outstanding timer using the handle with clearTimeout.
Example:
var pos = 1;
var handle = 0;
function move(delta) {
$('.box').css({'left': pos += delta });
}
function moveRight() {
move(1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveRight, 50);
}
function moveLeft() {
move(-1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveLeft, 50);
}
$('.right').on("mousedown", moveRight);
$('.left').on("mousedown", moveLeft);
$('.left, .right').on("mouseup", function() {
clearTimeout(handle);
handle = 0;
});
.box{
background-color: gray;
height:20px;
width: 20px;
left: 0;
position: relative;
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="left" button-held>Left</button>
<button class="right" button-held>Right</button>
<div class="box"></div>
In a comment you've said:
I just noticed a bug within this, if I leave one of the buttons pressed, and then slide out of it while still keeping it pressed and then releasing it, it move the box indefinitely until you press again one of the buttons, do you maybe know why this is happening?
It's because we're only listening for mouseup on the button, so when you release it, we don't get that event. Silly mistake on my part. :-)
Two solutions:
Either listen for mouseup on document, or
Listen for mouseleave on the button as well as mouseup.
I think #1 is probably best, especially since when I just tried it on Chrome, it even gracefully handled the case where I pressed the mouse down over the button, then slid it right out of the browser window entirely (!) and released it. Chrome still gave us the mouseup on `document. :-)
Implementing #1 is just a matter of hooking mouseup on document instead of .left, .right:
var pos = 1;
var handle = 0;
function move(delta) {
$('.box').css({'left': pos += delta });
}
function moveRight() {
move(1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveRight, 50);
}
function moveLeft() {
move(-1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveLeft, 50);
}
$('.right').on("mousedown", moveRight);
$('.left').on("mousedown", moveLeft);
// ONLY CHANGE is on the next line
$(document).on("mouseup", function() {
clearTimeout(handle);
handle = 0;
});
.box{
background-color: gray;
height:20px;
width: 20px;
left: 0;
position: relative;
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="left" button-held>Left</button>
<button class="right" button-held>Right</button>
<div class="box"></div>
Implementing #2 is just a matter of adding mouseleave to the mouseout handler; but note that the button retains its "pushed" appearance even though we stop doing the movement as soon as the mouse leaves the button:
var pos = 1;
var handle = 0;
function move(delta) {
$('.box').css({'left': pos += delta });
}
function moveRight() {
move(1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveRight, 50);
}
function moveLeft() {
move(-1);
clearTimeout(handle); // Just in case
handle = setTimeout(moveLeft, 50);
}
$('.right').on("mousedown", moveRight);
$('.left').on("mousedown", moveLeft);
// ONLY CHANGE is on the next line
$('.left, .right').on("mouseup mouseleave", function() {
clearTimeout(handle);
handle = 0;
});
.box{
background-color: gray;
height:20px;
width: 20px;
left: 0;
position: relative;
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="left" button-held>Left</button>
<button class="right" button-held>Right</button>
<div class="box"></div>
Something like this? Here you go
var pos = 1;
$('.right').mousedown(function(){
myVar = setInterval(function(){ $('.box').css({'left': pos++ }); }, 100);
});
$('.right').mouseup(function(){
clearInterval(myVar);
});
$('.left').mousedown(function(){
myVar = setInterval(function(){ $('.box').css({'left': pos-- }); }, 100);
});
$('.left').mouseup(function(){
clearInterval(myVar);
});

Detect MouseUp while something is following the cursor

I have been working on a online file system and I want to have users be able to drag and drop files to a new location. I don't really like how the default drag and drop visuals look so I am not using the conventional methond. This is what I have so far.
This code is in a .php file which is loaded onto the main page with jQuery
<td draggable = "true" ondragstart="dragFolder(event, \''.$folderId.'\', \''.$folderName.'\')">
<div class = "single-folder" onMouseUp = "folderDropUp(event, \''.$folderId.'\');">
<div class = "single-folder-name" id = "single-folder-name-'.$folderId.'">
<span id = "single-folder-rename-'.$folderId.'" class = "rename-folder-hover">
'.$folderName.'
</span>
</div>
</div>
</td>
Here is the dragFolder function that I have being fired from "ondragstart".
function dragFolder(e, folderId, folderName) {
var posX, posY, clicked, isDown = false;
var newFolder;
document.getElementById("folder_drag_image").setAttribute("folderId", folderId);
$(".single-folder").mousedown(function() {
clicked = true;
isDown = true;
followCursor(event);
});
$(document).mouseup(function() {
clicked = false;
$('#folder_drag_image').hide();
if(isDown){
//dropOnFolder(event, document.getElementById("folder_drag_image").getAttribute("folderId"), )
isDown = false;
}
});
$(document).mousemove(function(e) {
if(clicked == true) {
$('#folder_drag_image').show();
$('#folder_drag_image').stop(true, true);
followCursor(event);
}
});
function followCursor(e) {
clicked = true;
posX = e.pageX;
posY = e.pageY;
$('#folder_drag_image').animate({left: posX, top: posY});
}
}
function folderDropUp(e, newFolderId) {
alert(newFolderId);
isDown = true;
}
Basically what it does is it does is when the mouse goes down over a folder div it shows a fake dragging folder with the id of "folder_drag_image" which follows the mouse until the mouse goes up.
The problem comes here when I want to release the folder ontop of the new folder it will be put in. Here is the function for that.
function folderDropUp(e, newFolderId) {
alert(newFolderId);
isDown = true;
}
I took out the ajax because that is not part of the problem. If you look back up the the first code snippet there is a "onMouseUp" listener which triggers a "folderDropUp" event.
The problem is that if I drag my mouse onto folder with the fake drag image the folderDropUp function does not fire. If I just drag my mouse from anywhere else and it does not have the fake drag image when the function will fire off.
I did try jQuery mouseup function but just got the same output.
I don't know how helpful this will be, but by using jQueryUI you could do something like this:
HTML:
<html>
<head>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css"/>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
</head>
<body>
<table>
<tr>
<td>
<div class="single-folder">
<div class="single-folder-name" id="single-folder-name-nhaca">
<div id="single-folder-rename-nhaca" class="rename-folder-hover">
<div>Folder 1</div><div class="folder-drag-image" id="nhaca-drag-image">Folder 1</div>
</div>
</div>
</div>
</td>
<td>
<div class="single-folder">
<div class="single-folder-name" id="single-folder-name-other">
<span id="single-folder-rename-other" class="rename-folder-hover">
<div>Folder 2</div><div class="folder-drag-image" id="other-drag-image">Folder 2</div>
</span>
</div>
</div>
</td>
</tr>
</table>
</body>
</html>
CSS:
.single-folder{
border: 1px solid black;
cursor: pointer;
width: 60px;
}
.folder-drag-image{
position: absolute;
height: 20px;
width: 60px;
border: 1px solid black;
display: none;
}
.droppable-ready-to-receive{
background-color: yellow;
}
JS:
$( document ).ready(function() {
//displaying draggable element based on hovered element
$(".single-folder").on("mouseenter", function(e){
var drag_image = $(this).find(".folder-drag-image");
drag_image.css({"display": "block", "top": $(this).offset().top + 20, "left": $(this).offset().left});
});
//resetting draggable element when moving outside the "single-folder" div
$(".single-folder").on("mouseleave", function(e){
var drag_image = $(this).find(".folder-drag-image");
drag_image.css("display", "none");
});
//resetting draggable element when not being dragged any longer
$(".folder-drag-image").draggable({
stop: function(e) {
var parent = $(this).parents(".single-folder");
$(this).css({"display": "none", "top": parent.offset().top, "left": parent.offset().left});
}
});
//defining what elements can be dropped and what to do when dropped
$(".single-folder").droppable({
accept: '.folder-drag-image',
hoverClass: "droppable-ready-to-receive",
drop: function(e, ui) {
console.log("Dropped folder " + ui.draggable.text() + " into " + $(this).find(".folder-drag-image").text());
//handle folder drop however you need from here
}
});
});
EXAMPLE:http://jsfiddle.net/skdfLk5b/3/
I'm guessing this is far from a good solution to this, but hopefully it helps somehow.

Scroll the page vertically and scroll big image inside div horizontally on mouse drag with jQuery

I have page that I want to scroll vertically on event mouse down, and I already have found the answer on this question link. In my case i have a div that contain image that user put on it and sometimes it have bigger size than my div size, with overflow:auto; i get horizontal scroll inside that div. So i need to apply drag scroll horizontally on that div.
HTML
<html>
<body>
<div id="container">
<div class="detail-title"> TITLE </div>
<div class="detail-content">
<img src="...." />
!-- long content --!
</div>
</div>
</body>
</html>
CSS
.detail-main-content-box {
background: none;
display: block;
left: 0;
min-height: 350px;
overflow: auto;
padding: 5px 5px 5px 5px;
width: auto;
}
jQuery from answer link
$(document).on({
'mousemove': function (e) {
clicked && updateScrollPos(e);
},
'mousedown': function (e) {
clicked = true;
clickY = e.pageY;
$('html').addClass('block-selection').css({ 'cursor': 'url(../img/closedhand.cur), default' });
},
'mouseup': function () {
clicked = false;
$('html').removeClass('block-selection').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$(window).scrollTop($(window).scrollTop() + (clickY - e.pageY));
};
how can i apply this on div? i have try to change $(document) to $('.detail-content') also change function scrollTop to scrollLeft but nothing happen. Here is the fiddle for current condition.
this has been left here unanswered for two long years, not even a useful comment. OK, here is my try. hope it can help ( le roi est mort vive le roi)
<script type="text/javascript">
var clicked = true;
var clickY = e.pageY;
$('.detail-content').on({
'mousemove': function (e) {
clicked && updateScrollPos(this,e);
},
'mousedown': function (e) {
clicked = true;
clickY = e.pageY;
$('html').addClass('block-selection').css({ 'cursor': 'grabbing' });
},
'mouseup': function () {
clicked = false;
$('html').removeClass('block-selection').css('cursor', 'auto');
}
});
var updateScrollPos = function(obj,e) {
$(obj).scrollTop($(obj).scrollTop() + (clickY - e.pageY));
clickY = e.pageY;
};
</script>

Categories