Change the popover location dynamically while resizing browser window - javascript

I am using Twitter Bootstrap popover and I don't know how would be able to change the popover location dinamic while resizing browser window. The problem is that when i resize the window, popover stays fixed on position. I want to delay the popover like other html elements.
Code:
$('#popover1').popover({
html : true,
content: function() {
return $("#form").html();
},
placement: "top"
});

This works for me. It calls the show event for all visible popovers:
$(window).off("resize").on("resize", function() {
$(".popover").each(function() {
var popover = $(this);
if (popover.is(":visible")) {
var ctrl = $(popover.context);
ctrl.popover('show');
}
});
});

Have a look at the following questions and answers:
Bootstrap Popover showing at wrong place upon zoom in/out or resizing Browser window
jQuery position element based on window resize
You need to use an event handler for the resize event:
$(window).resize(function() {
// your positioning code here
});
Within this code you must reposition your element.

Related

TinyMCE: Center dialog window (WindowManager.open) in Editor

When I use editor.WindowManager.open to open a dialog window in tinyMce, it is centered on the screen.
I would like it to be centered inside the Editor.
How to approach this? Can I control the window location?
I found a solution by adding centering CSS dynamically to the web-page Head when the form opens.
In the "editor.windowManager.open" function of the dialog, I added this code:
id: 'xxx-dialog',
onopen: function() {
// Forcibly center dialog
if ($("head #added-xxx-dialog-CSS").length == 0) // only once
{
$("#xxx-dialog .mce-dragh").remove(); // disable dragging of dialog
var mceHeight=$(".mce-tinymce").height();
var mceTop=$(".mce-tinymce").position().top;
var thisHeight=$("#xxx-dialog").height();
var newTop=mceHeight/2+mceTop-thisHeight/2;
$("head").append('<style id="added-xxx-dialog-CSS"
type="text/css">#xxx-dialog {top:'+newTop+'px !important;}</style>');
}
}, // etc...
This code only centers the Dialog vertically, as in my application the Dialog is centered horizontally automatically anyway, but it is very easy to add a few more lines in the same way to center it horizontally as well.

jQuery media queries for toggle button - different action depending on screen width

I have a toggle button which basically shows/hides a list of filters on a Product Index page. Desktop is simple, when clicking the button the panel is shown or hidden with the following script:
$(".filter-toggle").click(function(){
$(".grid").toggleClass("hide-filters");
});
When the browser is below 1024px I use the mmenu plugin to duplicate the filters content and move it into an off-canvas panel. The code for that looks like this:
$(document).ready(function() {
$(".filters").mmenu({
// Options
navbar: {
title: "Filters"
}
}, {
// Configuration
clone: true,
offCanvas: {
pageSelector: ".page"
},
classNames: {
selected: "active"
}
});
var API = $(".filters").data("mmenu");
var $icon = $(".filter-toggle");
$icon.on("click", function() {
API.open();
});
});
Obviously (at the minute) when the toggle button is clicked it will show/hide the content on the page but also trigger the slide-out menu at the same time.
My question is how can I only run the relevant script when it's needed. Is it also possible to do this on resize on not just on pageLoad/refresh?
I tried using matchMedia. Here's a quick CodePen showing where I'm at...
https://codepen.io/moy/pen/wymvjN
It looked like it worked to begin with. Above 1024px the toggle worked. Shrinking the browser down meant the button triggered the slide-out panel - great! But when scaling back up to desktop the slide-out menu is triggered whenever the toggle is clicked. On refresh it works again ...until you shrink the browser down and back up again.
Any ideas?
You can listen for window resize events, and fire functions accordingly. For example, in jQuery:
$(window).on('resize', function(e) {
var windowWidth = $(window).width();
if (windowWidth < 1024) {
// initialize small viewport functionality
} else {
// initialized large viewport functionality
}
});
But, you'll need a way to disable that mmenu plugin when switching back to desktop, and include it in whatever script you run during that condition.
Alternatively, the mmenu "Responsive Layout" documentation provides an example for using CSS media queries to hide the cloned menu at certain breakpoints.

jQuery resetting scroll of window after scrollTop() call

I have an off canvas menu that slides in from the right and sits on top of the page. To prevent a scroll bar I am setting the content section's position to fixed while the menu is open. Problem is, when I close the menu the scroll position on the page is lost, the user is returned to the top of the page.
I am trying to store the scroll position of the page and then set the scroll when the window is closed, but its not working. If I debug the code I can see the scrollTop() functioning as expected, but then it goes into the jQuery.js script and after several function calls it resets the scroll to the top of the page.
What am I doing wrong?
var scrollPos;
function openMenu() {
$('body').addClass('open');
}
function closeMenu(compat) {
$('body').removeClass('open');
}
/*** Event Handlers ***/
$('#js-menu-toggle').on('click', function() {
scrollPos = $(window).scrollTop();
openMenu();
});
$('#js-menu-close').on('click', function() {
closeMenu();
$(window).scrollTop(scrollPos);
});
My apologies for not providing enough of an MCVE.
It turns out the problem was the events were bound to an <a> link with a "#" href, so adding in
return false;
as the last line of the .on events solved my problem.

Prevent parent page from scrolling when mouse is over embedded iframe in Firefox

...without limiting the scroll inside the iframe or the need to specifically name/tag all scrollable elements.
Imagine google maps widget embedded in parent page. When you zoom in the widget you don't want the parent page to scroll, obviously.
I thought an answer to my previous question solved the problem:
While scrolling inside an iframe, the body doesn't know anything about
what happens there. But when iframe scroller reach the bottom or the
top, it pass scrolling to body.
Cancel the event that propagates from the iframe.
But the solution does not work in Firefox because Firefox will not - by design - propagate events captured by iframe to the parent page, yet strangely it will scroll the parent page. See jsfiddle here.
$('body').bind('mousewheel DOMMouseScroll', onWheel);
function onWheel (e){
if (e.target === iframe)
e.preventDefault();
console.log(e);
}
So, how do I prevent page from scrolling when user zooms content in embedded iframe, in Firefox?
Since it is a bug in Firefox, the workaround is to work directly with the scroll event, instead of the mousewheel / DOMMouseScroll ones.
The way I did: When user enters the mouse over the iframe, I set a flag to true, and when he leaves the mouse out there, I set it back to false.
Then, when user tries to scroll, but the mouse arrow is inside the iframe, I prevent the parent window scrolling. But, unfortunately, you can't prevent the window scrolling with the usual e.preventDefault() method, so we still need another workaround here, forcing the window to scroll exactly to the X and Y positions it was already before.
The full code:
(function(w) {
var s = { insideIframe: false }
$(iframe).mouseenter(function() {
s.insideIframe = true;
s.scrollX = w.scrollX;
s.scrollY = w.scrollY;
}).mouseleave(function() {
s.insideIframe = false;
});
$(document).scroll(function() {
if (s.insideIframe)
w.scrollTo(s.scrollX, s.scrollY);
});
})(window);
I've created an immediately executed function to prevent defining the s variable in the global scope.
Fiddle working: http://jsfiddle.net/qznujqjs/16/
Edit
Since your question was not tagged with jQuery (although inside it, you've showed a code using the library), the solution with vanilla JS is as simple as the above one:
(function(w) {
var s = { insideIframe: false }
iframe.addEventListener('mouseenter', function() {
s.insideIframe = true;
s.scrollX = w.scrollX;
s.scrollY = w.scrollY;
});
iframe.addEventListener('mouseleave', function() {
s.insideIframe = false;
});
document.addEventListener('scroll', function() {
if (s.insideIframe)
w.scrollTo(s.scrollX, s.scrollY);
});
})(window);
Given all the prerequisites, I think the following is the sanest way to make this work in Firefox.
Wrap your iframe with a div which is a little bit shorter to enable vertical scrolling in it:
<div id="wrapper" style="height:190px; width:200px; overflow-y: auto; overflow-x: hidden;">
<iframe id="iframeid" height="200px" width="200px" src="about:blank">
</iframe>
</div>
Now you can center the iframe vertically and re-position it every time
the wrapper receives a scroll event (it will occur when a user tries to scroll away at frame edges):
var topOffset = 3;
wrapper.scrollTop(topOffset);
wrapper.on("scroll", function(e) {
wrapper.scrollTop(topOffset);
});
Combine this with your previous fix for Chrome, and it should cover all major browsers. Here is a working example - http://jsfiddle.net/o2tk05ab/5/
The only outstanding issue will be the visible vertical scrollbar on a wrapper div. There are several ways to go about it, for instance - Hide scroll bar, but still being able to scroll
I think that will solve your problem
it solved mine
var myElem=function(event){
return $(event.toElement).closest('.slimScrollDiv')
}
$(document).mouseover(function(e){
window.isOnSub=myElem(e).length>0
})
$(document).on('mousewheel',function(e){
if(window.isOnSub){
console.log(e.originalEvent.wheelDelta);
if( myElem(e).prop('scrollHeight')-myElem(e).scrollTop()<=myElem(e).height()&&(e.originalEvent.wheelDelta<0)){
e.preventDefault()
}
}
})
replace '.slimScrollDiv' with the element selector you want to
prevent parent scroll while your mouse is on it
http://jsbin.com/cutube/1/edit?html,js,output

Drag Leave and Drag Enter

When I drag a file over to my window I wish to show an overlay, and when the file is dragged off the window I wish to remove the overlay.
$(window).on('dragleave', this.onDragLeave);
$(window).on('dragenter', this.onDragEnter);
p.onDragEnter = function(e) {
console.log('ENTER');
};
p.onDragLeave = function(e) {
console.log('LEAVE');
};
The above works fine, when I enter and leave the window it logs correctly.
The problem starts when I start fading in and out my overlay:
p.onDragEnter = function(e) {
console.log('ENTER');
$('#drag-overlay').fadeIn();
};
p.onDragLeave = function(e) {
console.log('LEAVE');
$('#drag-overlay').fadeOut();
};
With the above, it just fades in and out again and again. I'm not sure whats going on, it's as if when the overlay fades in it fires a drag leave, i'm not sure why?
The overlay is just an absolute div, width and height 100%.
The problem is that by showing an overlay, you are causing the dragged item to leave the parent and drag into the overlay. Then hiding the overlay causes drag to trigger in the parent.
Fortunately, the solution is simple and can be done in css:
#drag-overlay
{
pointer-events: none;
...
}
See this jsfiddle for a working solution.
If you remove pointer-events:none you get the same behaviour. pointer-events:none just means that the parent ondragleave method isn't fired when dragging over the overlay.

Categories