Javascript click event take place only after javascript has completely driven - javascript

I have javascript in my page and I use there the click event. The problem is that in ie the clicking doesnt't hapen right away, but only after the hole javascript has gone through.
Then it fires that click event!
I would need it to hapen right away, before the other javascript-code!
$(document).ready(function() {
// sorting the list
var myLink = document.getElementById('header3');
myLink.click();
// scrolling the list to where the modified row is
if ('${rowId}') {
var row = $('#row-${rowId}');
row.addClass("highlight");
var scrollParent = ((jQuery.browser.msie) ? row.parent().parent().parent()[0] : row.parent()[0]);
row[0].scrollIntoView(false);
if (scrollParent.scrollTop > 0)
scrollParent.scrollTop = scrollParent.scrollTop + (scrollParent.clientHeight / 2);
}
}
That sorting should happen before scrolling! In ie the clicking happens after scrolling and then the scrolling is in wrong place.
In Firefox this works!
Can you help me on this?

Assuming (never a good thing) that the code that is executing before the click event code is the code you enter here below the click() call, why don't you refactor that to a function and make it part of the code that happens when you call the click() code?

Try this. Place your code in a separate function and trigger that function within the click.
$(function(){
function yourfunction(event)
{
//code to be executed after the click
// scrolling the list to where the modified row is
if ('${rowId}') {
var row = $('#row-${rowId}');
row.addClass("highlight");
var scrollParent = ((jQuery.browser.msie) ? row.parent().parent().parent()[0] : row.parent()[0]);
row[0].scrollIntoView(false);
if (scrollParent.scrollTop > 0)
scrollParent.scrollTop = scrollParent.scrollTop + (scrollParent.clientHeight / 2);
}
return false;
}
});
$(document).ready(function() {
// sorting the list
$('#header3').click(yourfunction);
});
Hope it helps,
Cumps

Related

How to make an action on first click and another action on second click

My goal is to move a div element to the right side of the page on the first click and move it back to the left if I click it again and so on. How can I do this in javascript?
As enhzfelp said in their comment, the best solution would be to create a css class which moves your element to the right side of the page and to add / remove it with javascript.
If your goal is actually to perform one action and on next event call perform another, you can simply change a variable whenever the event is called.
Example code:
let right = false;
someElement.on('click', () => {
right = !right;
if (right) moveRight();
else moveLeft();
});
function moveRight() { ... }
function moveLeft() { ... }
You can also do this
<script>
var clickCount = 0;
function checkClick() {
if ( clickCount % 2 == 0 ) {
alert("first click");
} else {
alert("Second click");
}
clickCount++
}
</script>
<button onclick="checkClick()">Click me</button>
So, as I understood, you want to make so on click, the div element move to the opositive direction of left or right.
You can make this with an event listener, that listens to the click event and execute whatever you want on every click.
document.addEventListener('click', function(event) {
// your code that executes on every click
});
This event listener listens the click on all your webpage, so if you want to only listen the click when the use click your div, you need to get the div. There are several ways, but I recomend you to add an id to the div.
<div id="iAmYourElement"></div>
And then get the element in JavaScript
const element = document.getElementById("iAmYourElement");
element.addEventListener('click', function(event) {
// your code that executes on every click
});
Now that we have the way to deal with the click event, let's talk about the code that goes inside the listener.
One way to do this is creating two CSS classes, one is your div on the left and another whe div on your right. So, if we need the element to be on the right, we add the right-class, and if we need the div to be to the left, we add left-class and remove right-class.
Final javascript code will looks like that:
const element = document.getElementById("iAmYourElement");
let isDivOnLeft = true;
element.addEventListener('click', function (event) { // executes if you click on the div
isDivOnLeft = !isDivOnLeft // We negate the value of isDivOnLeft, so if it was true, it will now be false and vice versa.
if (isDivOnLeft) {
elementToRight()
} else {
elementToLeft()
}
});
function elementToRight() {
element.classList.remove("left-class")
element.classList.add("right-class")
}
function elementToLeft() {
element.classList.remove("right-class")
element.classList.add("left-class")
}
Hmm,
my English is kinda weak so I'll try my best to explain.
Let's assume that we have a div with id moveable
<div id="moveable"></div>
And we have button
<button id="move">Move</div>
And our goal is to move the div to the right in the first click, and in the second click, we will move it back to the right.
let button = document.getElementById("move");
let div = document.getElementById("moveable");
button.addEventListener("click", function () {
const dataMovedAttribute = div.getAttribute("data-moved");
if (dataMovedAttribute && dataMovedAttribute === "true") {
div.setAttribute("data-moved", "false");
div.style.float = "left";
} else {
div.setAttribute("data-moved", "true");
div.style.float = "right";
}
});
Checkout this example:
https://codesandbox.io/s/vigilant-rosalind-176by

Execute javascript only above certain width with resize

I'm currently developing a website which has a sticky menu function. I've got the normal javascript to work good, which adds some classes once the client scrolls past 150px.
I now face the problem that I don't want the classes to be added once people view the website below 725px, so I added a rule that it only executes the script above 725px but the problem is this:
If I resize the window back to full the function won't work anymore, so I created another rule with the javascript resize function but I can't get it to work..
Here is my script:
$(document).ready(function(){
var mainbottom = 150;
if($(window).innerWidth() > 725) {
$(window).on('scroll',function(){
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
});
}
});
$(window).resize(function() {
var mainbottom = 150;
if($(window).innerWidth() > 725) {
$(window).on('scroll',function(){
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
});
}
});
I'll hope somebody can help me with this problem.
First off, you should keep your code DRY. So preferably never copy paste any code around, bacause you will have to edit all the copies when you have to alter the behaviour or fix bugs.
You have not but your second $(window).resize() handler in the onready handler, so maybe that is why it is not triggered.
This should work:
$(document).ready(function(){
var mainbottom = 150;
function onScroll () {
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
}
var widthExceeded = false;
$(window).resize(function() {
$(window).innerWidth() > 725) {
if (!widthExceeded) {
$(window).on('scroll', onScroll);
}
widthExceeded = true;
} else {
if (widthExceeded) {
$(window).off('scroll', onScroll);
}
widthExceeded = false;
}
}).resize();
});
You are defining a scroll event listener inside a resize event listener, so basically you're declaring the scroll listener on every resive event (so the scroll listener is defined many many times if the user resize its browser). You need to correct this.
You could declare a flag (boolean) to indicate wether the viewport is below 725px or not. It should be initialized on $(document).ready(...) by testing the viewport dimensions.
Create a resize event listener which updates this flag by testing the viewport width, so you always know if you need to manage your classes or not.
At this point, console.log(your_flag) in your resize event listener to check if it works fine.
Then declare a scroll event listener, and in this listener the first thing you want to do is test the flag value. If viewport > 725, then manage the classes, otherwise do nothing.

JQuery: don't focus out when clicking on something

I have a div, #someDiv, on which I have some jQuery code to execute when focused on, and when focused out. But I want to achieve an action in which, if a certain other div is clicked on when div #1 is focused on, that focus remains on the div:
$(document).on("focus", "#someDiv", function() {
// Some code here to execute
}).on("focusout", "#someDiv", function() {
if (#someDiv2 was clicked on) { // DON'T focus out from #someDiv }
});
...however the issue is that jQuery is unable to distinguish that during the focus out, a click was made. How can I achieve this effect?
EDIT: Basically the idea I am trying to implement is a mock web-app in which you can customize a certain kind of div when it has focus, and upon that, an "options" div appears. I don't want the options bar to disappear when it is clicked, as otherwise none of the "options" can be chosen.
One half baked solution is to simply monitor the time for click / blur and correlate the two:
http://jsfiddle.net/ztA5F/
var lastBlur = new Date().getTime();
$("html").on("click", function() {
var now = new Date().getTime();
console.log(lastBlur);
console.log(now);
if (lastBlur >= (new Date().getTime() - 500))
$("#input").focus();
console.log("click");
});
$("#input").on("blur", function() {
lastBlur = new Date().getTime();
console.log("blur");
});
I am not certain I totally understand what you're after, but maybe this will be helpful:
var lastID;
$(document).on('click focus', function (e) {
var id = $(e.target).attr('id');
if (id === 'someDiv2' && lastID === 'someDiv') {
$('#someDiv').trigger('focus');
}
lastID = id;
});

Prevent 'click' event from firing multiple times + issue with fading

Morning folks. Have an issue with a simple jQuery gallery i'm making. It lets the user cycle through a collection of images via some buttons and at the same time, rotates through these images on a timer. My problem is that the user is able to click the button multiple times which queues up the fade in animation and repeats it over and over, e.g. user clicks button 5 times > same image fades in/out 5 times > gallery moves to next image.
I've tried using:
$('#homeGalleryImage li a').unbind('click');
After the click event is fired and then rebinding:
$('#homeGalleryImage li a').bind('click');
After it's done but this simply removes the click event after pressing a button once and never rebinds to it?
I've also tried disabling the button via:
$('#homeGalleryImage li a').attr('disabled', true);
To no avail... ?
There is a secondary issue where if you manage to click a button while the image is in a transition, the next image appears 'faded' as if the opacity has been lowered? Very strange... Here is the code for button clicks:
var i = 1;
var timerVal = 3000;
$(function () {
$("#homeGalleryControls li a").click(function () {
var image = $(this).data('image');
$('#galleryImage').fadeOut(0, function () {
$('#galleryImage').attr("src", image);
});
$('#galleryImage').fadeIn('slow');
$('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
$(this).find('img').attr("src", "/Content/Images/Design/btn_checked.gif");
i = $(this).data('index') + 1;
if (i == 4) {
i = 0;
}
timerVal = 0;
});
});
Here is the code that cycles through the images on a timer:
//Cycle through gallery images on a timer
window.setInterval(swapImage, timerVal);
function swapImage() {
$('#galleryImage').fadeOut(0, function () {
var imgArray = ["/Content/Images/Design/gallery placeholder.jpg", "/Content/Images/Design/1.jpg", "/Content/Images/Design/2.jpg", "/Content/Images/Design/3.jpg"];
var image = imgArray[i];
i++;
if (i == 4) {
i = 0;
}
$('#galleryImage').attr("src", image);
$('#galleryImage').fadeIn('slow');
});
var currentButton = $('#homeGalleryControls li a img').get(i - 1);
$('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
$(currentButton).attr("src", "/Content/Images/Design/btn_checked.gif");
}
I realise it might be a better idea to use a plugin but I'm very new to jQuery and I'd like to learn something rather than using some ready made code.
Any help at all, is much appreciated.
Thankyou
You could always try adding something to the element to cancel the click event?
For example
$(".element").click(function(e) {
if ( $(this).hasClass("unclickable") ) {
e.preventDefault();
} else {
$(this).addClass("unclickable");
//Your code continues here
//Remember to remove the unclickable class when you want it to run again.
}
}):
In your case you could try adding a check on the click.
$('#homeGalleryImage li a').attr('data-disabled', "disabled");
Then inside your click event
if ( $(this).attr("data-disabled" == "disabled") {
e.preventDefault();
} else {
//Ready to go here
}
Edit
Here is a working example showing the element becoming unclickable. http://jsfiddle.net/FmyFS/2/
if you want to make sure that the registered event is fired only once, you should use jQuery's one :
.one( events [, data ], handler ) Returns: jQuery
Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
see examples:
using jQuery: https://codepen.io/loicjaouen/pen/RwweLVx
// add an even listener that will run only once
$("#click_here_button").one("click", once_callback);
using vanilly JS: https://codepen.io/loicjaouen/pen/gOOBXYq
// add a listener that run only once
button.addEventListener('click', once_callback, {capture: true, once: true});

Prevent click event in jQuery triggering multiple times

I have created a jQuery content switcher. Generally, it works fine, but there is one problem with it. If you click the links on the side multiple times, multiple pieces of content sometimes become visible.
The problem most likely lies somewhere within the click event. Here is the code:
$('#tab-list li a').click(
function() {
var targetTab = $(this).attr('href');
if ($(targetTab).is(':hidden')) {
$('#tab-list li').removeClass('selected');
var targetTabLink = $(this).parents('li').eq(0);
$(targetTabLink).addClass('selected');
$('.tab:visible').fadeOut('slow',
function() {
$(targetTab).fadeIn('slow');
}
);
}
return false;
}
);
I have tried adding a lock to the transition so that further clicks are ignored as the transition is happening, but to no avail. I have also tried to prevent the transition from being triggered if something is already animating, using the following:
if ($(':animated')) {
// Don't do anything
}
else {
// Do transition
}
But it seems to always think things are being animated. Any ideas how I can prevent the animation being triggered multiple times?
One idea would be to remove the click event at the start of your function, and then add the click event back in when your animation has finished, so clicks during the duration would have no effect.
If you have the ability to execute code when the animation has finished this should work.
Add a variable to use as a lock rather than is(:animating).
On the click, check if the lock is set. If not, set the lock, start the process, then release the lock when the fadeIn finishes.
var blockAnimation = false;
$('#tab-list li a').click(
function() {
if(blockAnimation != true){
blockAnimation = true;
var targetTab = $(this).attr('href');
if ($(targetTab).is(':hidden')) {
$('#tab-list li').removeClass('selected');
var targetTabLink = $(this).parents('li').eq(0);
$(targetTabLink).addClass('selected');
$('.tab:visible').fadeOut('slow',
function() {
$(targetTab).fadeIn('slow', function(){ blockAnimation=false; });
}
);
}
}
return false;
}
);
Well this is how i did it, and it worked fine.
$(document).ready(function() {
$(".clickitey").click(function () {
if($("#mdpane:animated").length == 0) {
$("#mdpane").slideToggle("slow");
$(".jcrtarrow").toggleClass("arrow-open");
}
});
});
this is not doing what your code does ofcourse this is a code from my site, but i just like to point how i ignored the clicks that were happening during the animation. Please let me know if this is inefficient in anyway. Thank you.
I toyed around with the code earlier and came up with the following modification which seems to work:
$('#tab-list li a').click(
function() {
$('.tab:animated').stop(true, true);
var targetTab = $(this).attr('href');
if ($(targetTab).is(':hidden')) {
$('#tab-list li').removeClass('selected');
var targetTabLink = $(this).parents('li').eq(0);
$(targetTabLink).addClass('selected');
$('.tab:visible').fadeOut('slow',
function() {
$(targetTab).fadeIn('slow');
}
);
}
return false;
}
);
All that happens is, when a new tab is clicked, it immediately brings the current animation to the end and then begins the new transition.
one way would be this:
$('#tab-list ul li').one( 'click', loadPage );
var loadPage = function(event) {
var $this = $(this);
$global_just_clicked = $this;
var urlToLoad = $this.attr('href');
$('#content-area').load( urlToLoad, pageLoaded );
}
$global_just_clicked = null;
var pageLoaded() {
$global_just_clicked.one( 'click', loadPage );
}
As you can see, this method is fraught with shortcomings: what happens when another tab is clicked before the current page loads? What if the request is denied? what if its a full moon?
The answer is: this method is just a rudimentary demonstration. A proper implementation would:
not contain the global variable $global_just_clicked
not rely on .load(). Would use .ajax(), and handle request cancellation, clicking of other tabs etc.
NOTE: In most cases you need not take this round-about approach. I'm sure you can remedy you code in such a way that multiple clicks to the same tab would not affect the end result.
jrh.
One way to do this to use timeStamp property of event like this to gap some time between multiple clicks:
var a = $("a"),
stopClick = 0;
a.on("click", function(e) {
if(e.timeStamp - stopClick > 300) { // give 300ms gap between clicks
// logic here
stopClick = e.timeStamp; // new timestamp given
}
});

Categories

Resources