how to prevent bubbling event when use Turbolinks.visit(path) - javascript

I use aspnetmvcturbolinks in own project and I have reload page with
Turbolinks.visit(path) when user add text in input . but,when page changed I check this keyup event of input is fire more one and I add return false but not work .
$(document).on("ready page:load", function() {
$('input[name=keyword]').keyup(function (e) {
alert();
var $text = $(this).val();
if ($text.length > 1) {
$('html, body').animate({ scrollTop: 0 }, 600, function() {
Turbolinks.visit('#searchUrl' + '?keyword=' + $text);
});
}
if ($text.length == 0) {
Turbolinks.visit('#searchUrl');
}
return false;
});
$(document).on('change', 'select[name="order"]', function() {
Turbolinks.visit('#searchUrl');
});
$(document).on('change', 'select[name="count"]', function() {
Turbolinks.visit('#searchUrl');
});
});
what is solution?
thanks

Try to use
e.stopPropagation();
instead of
return false;
http://api.jquery.com/event.stoppropagation/

Try This,
if(e.stopPropagation)e.stopPropagation();
else e.cancelBubble=true; // where e is an event object
$('input[name=keyword]').keyup(function (e) {
alert();
var $text = $(this).val();
if ($text.length > 1) {
$('html, body').animate({ scrollTop: 0 }, 600, function() {
Turbolinks.visit('#searchUrl' + '?keyword=' + $text);
});
}
if ($text.length == 0) {
Turbolinks.visit('#searchUrl');
}
if(e.stopPropagation)e.stopPropagation();
else e.cancelBubble=true;
});

Related

how to make an animation only 1 time on scroll

This is my code: Fiddle
countEach()
$(window).on('scroll', function(e) {
countEach()
})
function countEach() {
$('.count').each(function() {
if (showOnScreen(this) && $(this).attr('show') != 'false') {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
function showOnScreen(target) {
if ($(window).scrollTop() + $(window).height() >= $(target).offset().top)
return true;
else
return false;
}
function numberAnimate(target) {
var $this = $(target);
jQuery({
Counter: 0
}).animate({
Counter: $this.text()
}, {
duration: 1000,
easing: 'swing',
step: function() {
$this.text(this.Counter.toFixed(1));
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count">5.6</span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<p>Scroll up and then scroll down again</p>
<span class="count">5.6</span>
The problem is, the increasing number animation will run again, if i scroll up and scroll down again. What is the thing that i need to change to stop it? I tried a lot of things, but i am not good at Javascript.
You need to declare a global var as stopNow = 2 so your animation can only run twice and decrement it when animation runs.
var stopNow = 2;
Update the countEach function as follows
function countEach() {
$('.count').each(function() {
//also check stopNow != 0
if (showOnScreen(this) && $(this).attr('show') != 'false' && stopNow != 0) {
console.log($(this).text())
console.log($(this).attr('show'))
$(this).attr('show', 'false')
numberAnimate(this)
stopNow = stopNow - 1; //decrement stopNow
} else if (!showOnScreen(this)) {
$(this).attr('show', 'true')
}
})
}
Here's your updated working fiddle - https://jsfiddle.net/6w8ubh5y/7/
Use a global variable. Set it to false at the beginning. In the scroll event, check it and if it is still false, run the countEach() function then change the variable to true. Like this:
var stop = false;
countEach();
$(window).on('scroll', function(e) {
if(!stop){
countEach();
stop = true;
}
})
Change the event binding code from:
$(window).on('scroll', function(e) {
countEach()
})
to
$(window).on('scroll', countEach);
and change countEach function like this...
function countEach() {
$('.count').each(function() {
...
});
$(window).off('scroll', countEach); // add this line
}

jQuery change page and show tab on menu entry click

var tab = null;
var menuSelector = null;
jQuery(function ($) {
console.log('test');
//howtos tab
function changeMenuSelector() {
if ($( document ).width() > 967) {
menuSelector = 'top-menu-nav';
} else {
menuSelector = 'mobile_menu';
}
}
changeMenuSelector();
$( window ).resize(function() {
changeMenuSelector();
});
$('#'+menuSelector+' a[href*="howtos"]').on('click', function(event){
var e = event;
var $ = jQuery;
setTimeout(function () {
e.preventDefault();
console.log('pluto');
window.localStorage.setItem('tab', 'et_pb_tab_0');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
window.localStorage.removeItem('tab');
}
},1000);});
$('#'+menuSelector +' a[href*="projects"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_1');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="reviews"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_2');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="elearning"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_3');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
$('#'+menuSelector +' a[href*="others"]').on('click', function(e){
e.preventDefault();
console.log('pluto');
localStorage.setItem('tab', 'et_pb_tab_4');
if(window.location.pathname.indexOf('blog-posts') === -1)
{
window.location.href='http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li."+tab+">a")[0].click();
localStorage.removeItem('tab');
}
});
if (!!localStorage.getItem('tab')) {
tab = localStorage.getItem('tab');
console.log(tab);
setTimeout(function(){$("li."+tab+">a")[0].click();}, 1)
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
localStorage.removeItem('tab');
}
});
I have created a script to show tabs in Divi when you click on a menu entry. Divi does not use ids and hrefs for this, so I had to use a script.
The problem that I am facing is that this script that I made does not work with Divi's mobile menu.
I checked if menuSelector changed properly and if changeMenuSelector got executed as expected.
Furthermore, $('#'+menuSelector+' a[href*="howtos"]').length returns 1 in console and if I run $('#'+menuSelector+' a[href*="howtos"]')[0] in console I obtain the expected DOM element whehter I have the browser window sized for mobile or for desktop devices.
I also tried using setTimeout in case the issue was that it needed some time to accomplish an earlier action without any luck.
Therefore, is there anyone that could tell me why this does not work when the website is running in mobile mode?
I solved the issue by refactoring the code like this:
jQuery(function ($) {
console.log('test');
var tab = null;
var menuSelector = null;
var guard = false;
function changeMenuSelector() {
if ($(document).width() > 967) {
menuSelector = 'top-menu-nav';
guard = false;
initEventListeners(guard);
} else {
menuSelector = 'mobile_menu';
guard = true;
initEventListeners(guard);
}
}
function initEventListeners(guard) {
var localGuard = null;
if (localGuard != guard) {
var hrefs = ['howtos', 'projects', 'reviews', 'elearning', 'others'];
hrefs.forEach(
function (element, index, array) {
$('#' + menuSelector + ' a[href*="' + element + '"]').off();
console.log(element);
$('#' + menuSelector + ' a[href*="' + element + '"]').on('click', function (e) {
e.preventDefault();
console.log('pluto');
window.localStorage.setItem('tab', 'et_pb_tab_' + index);
if (window.location.pathname.indexOf('blog-posts') === -1) {
window.location.href = 'http://www.davidepugliese.com/blog-posts/';
} else {
tab = localStorage.getItem('tab');
$("li." + tab + ">a")[0].click();
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
window.localStorage.removeItem('tab');
}
});
});
localGuard = guard;
}
}
changeMenuSelector();
initEventListeners();
$(window).resize(function () {
changeMenuSelector();
});
if (!!localStorage.getItem('tab')) {
tab = localStorage.getItem('tab');
console.log(tab);
setTimeout(function(){$("li."+tab+">a")[0].click();}, 1)
$("html, body").animate({ scrollTop: $('.et_pb_module.et_pb_tabs.et_pb_tabs_0').offset().top },
1000);
localStorage.removeItem('tab');
}
});

Adding additional case to script for onClick event

I have a pop-up for a website that asks the user to sign up if they aren't already signed in. I'm using a script called "subscribe-better.js" (https://github.com/peachananr/subscribe-better) and this works great for loading the popup when the user first enters the site.
However, I want this pop-up to show when a user clicks a button. This is my button:
<div id="popClick" class="button btn">Sign Up to Proceed</div>
and here is how I am calling the pop-up:
<script>
$(document).ready(function() {
$(".subscribe-me2").subscribeBetter({
trigger: "onclick",
animation: "fade",
delay: 0,
showOnce: true,
autoClose: false,
scrollableModal: false
});
});
</script>
<div class="subscribe-me2">
Sample Pop Up Content Here
</div>
And the code to make it pop-up. You'll see I've added the case for onclick but nothing is happening when I click my button. I also tried instead of document.ready() to call the pop-up within a $('#popClick').click() but that didn't make the pop-up appear either. How can I fix the switch statement to make the pop-up appear when the #popClick button is clicked?
!function($){
var defaults = {
trigger: "atendpage", // atendpage | onload | onidle
animation: "fade", // fade | flyInRight | flyInLeft | flyInUp | flyInDown
delay: 0,
showOnce: true,
autoClose: false,
scrollableModal: false
};
$.fn.subscribeBetter = function(options){
var settings = $.extend({}, defaults, options),
el = $(this),
shown = false,
animating = false;
el.addClass("sb");
$.fn.openWindow = function() {
var el = $(this);
if(el.is(":hidden") && shown == false && animating == false) {
animating = true;
setTimeout(function() {
if (settings.scrollableModal == true) {
if($(".sb-overlay").length < 1) {
$("body").append("<div class='sb-overlay'><div class='sb-close-backdrop'></div><div class='sb sb-withoverlay'>" + $(".sb").html() + "</div></div>");
$(".sb-close-backdrop, .sb-close-btn").one("click", function() {
$(".sb.sb-withoverlay").closeWindow();
return false;
});
$(".sb.sb-withoverlay").removeClass("sb-animation-" + settings.animation.replace('In', 'Out')).addClass("sb-animation-" + settings.animation);
setTimeout(function(){
$(".sb.sb-withoverlay").show();
$("body").addClass("sb-open sb-open-with-overlay");
}, 300);
}
} else {
if ($(".sb-overlay").length < 1) {
$("body").append("<div class='sb-overlay'><div class='sb-close-backdrop'></div></div>");
$(".sb").removeClass("sb-animation-" + settings.animation.replace('In', 'Out')).addClass("sb-animation-" + settings.animation);
$(".sb-close-backdrop, .sb-close-btn").one("click", function() {
$(".sb").closeWindow();
return false;
});
setTimeout(function(){
$(".sb").show();
$("body").addClass("sb-open");
}, 300);
}
}
if (settings.showOnce == true) shown = true;
animating = false;
}, settings.delay);
}
}
$.fn.closeWindow = function() {
var el = $(this);
if(el.is(":visible") && animating == false) {
animating = true;
if (settings.scrollableModal == true) {
$(".sb.sb-withoverlay").removeClass("sb-animation-" + settings.animation).addClass("sb-animation-" + settings.animation.replace('In', 'Out'));
setTimeout(function(){
$(".sb.sb-withoverlay").hide();
$("body").removeClass("sb-open sb-open-with-overlay");
setTimeout(function() {
$(".sb-overlay").remove();
}, 300);
}, 300);
} else {
$(".sb").removeClass("sb-animation-" + settings.animation).addClass("sb-animation-" + settings.animation.replace('In', 'Out'));
setTimeout(function(){
$(".sb").hide();
$("body").removeClass("sb-open");
setTimeout(function() {
$(".sb-overlay").remove();
}, 300);
}, 300);
}
animating = false;
}
}
$.fn.scrollDetection = function (trigger, onDone) {
var t, l = (new Date()).getTime();
$(window).scroll(function(){
var now = (new Date()).getTime();
if(now - l > 400){
$(this).trigger('scrollStart');
l = now;
}
clearTimeout(t);
t = setTimeout(function(){
$(window).trigger('scrollEnd');
}, 300);
});
if (trigger == "scrollStart") {
$(window).bind('scrollStart', function(){
$(window).unbind('scrollEnd');
onDone();
});
}
if (trigger == "scrollEnd") {
$(window).bind('scrollEnd', function(){
$(window).unbind('scrollStart');
onDone();
});
}
}
switch(settings.trigger) {
case "atendpage":
$(window).scroll(function(){
var yPos = $(window).scrollTop();
if (yPos >= ($(document).height() - $(window).height()) ) {
el.openWindow();
} else {
if (yPos + 300 < ($(document).height() - $(window).height()) ) {
if(settings.autoClose == true) {
el.closeWindow();
}
}
}
});
break;
case "onload":
$(window).load(function(){
el.openWindow();
if(settings.autoClose == true) {
el.scrollDetection("scrollStart", function() {
el.closeWindow();
});
}
});
break;
case "onidle":
$(window).load(function(){
el.scrollDetection("scrollEnd", function() {
el.openWindow();
});
if(settings.autoClose == true) {
el.scrollDetection("scrollStart", function() {
el.closeWindow();
});
}
});
break;
case "onclick":
$('#popClick').click(function(){
el.openWindow();
});
break;
}
}
}(window.jQuery);
I believe the problem is that you're using 'showOnce' which globally limits the popup from showing more than once. So, your onclick probably is firing (I'd suggest adding a console.log in to be sure) but then if(el.is(":hidden") && shown == false && animating == false) { in the openWindow function is no longer true.

jQuery event.stopPropagation() and event issues

I'm creating a jQuery script that add a pin to a map on click event, the problem is that i need that event to work only on the map not his sons too..
This is my code:
$("div#map").click(function (e) {
$('<div class="pin"></div>').css({
left: a_variable,
top: another_variable
}).appendTo(this);
$("div.pin").click(function (e) { e.stopPropagation(); });
})
Another problem is that under this code i have something like this:
$("div.pin").mousedown(function (e) {
if(e.which == 1) {
console.log("down");
moving = true;
$(this).addClass("moving");
} else if(e.which == 3) {
console.log("right");
}
});
Will this work with pins created after the script load too?
JsFiddle: http://jsfiddle.net/vB2Gb/
I made a number of adjustments to your code:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/vB2Gb/1/
$(function () {
var $map = $("div#map");
$map.click(function (e) {
var $pin = $('<div class="pin"></div>').css({
left: (((e.pageX + 3 - $map.position().left) * 100) / $map.width()) + "%",
top: (((e.pageY - 10 - $map.position().top) * 100) / $map.height()) + "%"
});
$pin.appendTo($map);
})
$map.on('click', "div.pin", function (e) {
e.stopPropagation();
});
var moving = false;
var pin_id;
var pin_left;
var pin_top;
$map.on('mousedown', "div.pin", function (e) {
if (e.which == 1) {
console.log("down");
moving = true;
$(this).addClass("moving");
} else if (e.which == 3) {
console.log("right");
}
});
$map.on('contextmenu', "div.pin", function (e) {
return false;
});
$(document).mousemove(function (e) {
if (moving) {
if (e.pageX <= $map.position().left) {
pin_left = 0;
} else if (e.pageY <= $map.position().top) {
pin_top = 0;
} else {
console.log("moving");
pin_id = 1;
pin_left = (((e.pageX + 3 - $map.position().left) * 100) / $map.width());
pin_top = (((e.pageY - 10 - $map.position().top) * 100) / $map.height());
$(".moving").css("left", pin_left + "%");
$(".moving").css("top", pin_top + "%");
}
}
});
$(document).mouseup(function (e) {
if (moving) {
console.log("up");
moving = false;
$(".moving").removeClass("moving");
dbMovePin(pin_id, pin_left, pin_top);
}
});
});
function dbMovePin(pin_id, pin_left, pin_top) {
$.post(
"mapsave.php", {
action: "move_pin",
id: pin_id,
left: pin_left,
top: pin_top
},
function (data, status) {
//alert("Data: " + data + "\nStatus: " + status);
});
}
This includes using delegated events (with on) for both the mouse down events and the pin click. Sharing a single variable for the map etc
Event Delegation does what i need:
I've changed
$("div.pin").mousedown(function (e) { ... });
with
$("div#map").on("mousedown", "div", function (e) {
Since you are dealing with dynamically added elements, you need to use event delegation.
$("#map").click(function (e) {
$('<div class="pin"></div>').css({
left: a_variable,
top: another_variable
}).appendTo(this);
}).on('click', '.pin', function (e) {
//have a single delegated click handler
e.stopPropagation();
}).on('mousedown', '.pin', function (e) {
//use a delegated handler for mousedown also
if (e.which == 1) {
console.log("down");
moving = true;
$(this).addClass("moving");
} else if (e.which == 3) {
console.log("right");
}
})
Also see
Event binding on dynamically created elements?

Navigating long un-ordered list

I have this long list with overflow: auto to scroll through it, i set it up for keyboard navigation, the problem is that when using the keyboard it doesn't scroll correctly!
check this jsFiddle
$('ul').keydown(function (e) {
if (e.keyCode == 38) { // up
var selected = $(".selected");
$listItems.removeClass("selected");
if (selected.prev().length == 0) {
selected.siblings().last().addClass("selected");
} else {
selected.prev().addClass("selected");
}
}
if (e.keyCode == 40) { // down
var selected = $(".selected");
$listItems.removeClass("selected");
if (selected.next().length == 0) {
selected.siblings().first().addClass("selected");
} else {
selected.next().addClass("selected");
}
}
})
});
$listItems.click(function () {
if ($(this).is('.selected')) {
return true;
} else {
$('li').removeClass('selected');
$(this).addClass('selected');
}
the behavior i'm looking for is the same behavior of the element when scrolling through a long list of elements using the keyboard this plugin SelectBoxIt show's what i'm looking for.
you can use this code instead, i used animate function to navigate inside the div if the list exceed the width of the ul tag :
http://jsfiddle.net/goldendousa/p6243/13/
$('ul').focus(function() {
if ($('ul li').is('.selected')) {
$('ul li').first().removeClass('selected');
} else {
$('ul li').first().addClass('selected');
}
});
$('ul').keydown(function(e) {
if (e.keyCode == 38) { // up
e.preventDefault();
var selected = $(".selected");
$("ul li").removeClass("selected");
if (selected.prev().length == 0) {
selected.siblings().last().addClass("selected");
var selectedTopOffset = selected.siblings().last().offset().top;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
} else {
selected.prev().addClass("selected");
var selectedTopOffset = $("div").scrollTop() + selected.position().top - $("div").height()/2 + selected.height()/2;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
}
}
if (e.keyCode == 40) { // down
e.preventDefault();
var selected = $(".selected");
$("ul li").removeClass("selected");
if (selected.next().length == 0) {
selected.siblings().first().addClass("selected");
if (selected.siblings().first().offset().top < 0) {
$('div').animate({
scrollTop: selected.siblings().first().offset().top
}, 200);
}
} else {
selected.next().addClass("selected");
var selectedTopOffset = $("div").scrollTop() + selected.position().top - $("div").height()/2 + selected.height()/2;
$('div').animate({
scrollTop: selectedTopOffset
}, 200);
}
}
});
$('li').click(function() {
if ($(this).is('.selected')) {
return true;
} else {
$('li').removeClass('selected');
$(this).addClass('selected');
}
});

Categories