I have a responsive design with multiple breakpoints. Some of the block dimensions in the content are calculated with jQuery. When the viewport changes these dimensions change thus the calculation should be run. How can I fire these events when the dimension of the reference element changes? The reference element changes when a breakpoint is crossed.
I've looked at the "orientationchange" event but it's not having the results I need.
You provide very little specifics and no code so all we can do is answer very generally.
Usually, you install a .resize() event handler and on every resize of the containing window, you check to see if the resulting dimensions have changed such that you need to recalculate and modify the layout.
$(window).resize(function(e) {
// check dimensions here to decide if layout needs to be adjusted
});
jQuery mobile supports the orientationchange event like this which also gives you e.orientation as "portrait" or "landscape":
$(window).on( "orientationchange", function(e) {
// check dimensions here to decide if layout needs to be adjusted
});
There are no DOM events for watching a size change on a specific element in the page other than a window object. Instead, you have to watch whatever other events might cause a given element to get resized which might be a resize of the window, an orientation change or some other action in the page that modifies the page (a button press or click on something, for example). Then, when those other events fire and get processed, you can then check the size of your target element and see if it changed.
Here's a jQuery plugin that debounces the resize event so it only tells you about a resize when the size has stopped changing:
(function($) {
var uniqueCntr = 0;
$.fn.resized = function (waitTime, fn) {
if (typeof waitTime === "function") {
fn = waitTime;
waitTime = 250;
}
var tag = "resizeTimer" + uniqueCntr++;
this.resize(function () {
var self = $(this);
var timer = self.data(tag);
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
self.removeData(tag);
fn.call(self[0]);
}, waitTime);
self.data(tag, timer);
});
}
})(jQuery);
Working demo: https://jsfiddle.net/jfriend00/k415qunp/
Sample usage:
$(window).resized(function() {
// put code here to act when window stopped getting resized
});
This page might help you. They talk about JS execution based on breakpoints and doing it with cross-browser support. Basically you'll be using a hidden pseudo element using the "content" property of .myClass:after.
Related
onresize can be used for knowing window has been resized. Is there any similar notification/event before window resizes.
I want to set will-change on some elements before window resize starts and subsequently remove that after window has resized.
It seems there are no direct solutions but you can achieve both start|end events with some workaround using window.addEventListener("resize",yourFunction); and some global variables (it is a workaround, it is not perfect).
//Accesible variables
var atStart = true;
var timer;
function yourFunction(){
return ()=>{
if(atStart){
console.log("START");
//Some code to be executed once at start
atStart = false;
}
console.log("WHILE");
//Some code to be executed while resizing
if (timer) clearTimeout(timer);
timer= setTimeout(atEnd, 500);
}
}
function atEnd(){
//Some code to be executed at the end of resizing
//..well some 500ms after the end of resizing
console.log("END")
atStart = true;
}
window.addEventListener("resize",yourFunction());
Hope it helps someone.
There are no events that fire before resize. Only during resize. Most solutions to do something on rezise use setTimeout to check when a certain amount of time passed since the last resize event. So I guess you're out of luck.
I am making a Tampermonkey script, and I want to create an event listener to listen for when a video's width is changed, specifically when a video is made full-screen. This is what I have right now:
var htmlVideos = document.getElementsByTagName('video');
function checkVidWidth() {
for (i = 0; i < htmlVideos.length; i++) {
if ($(htmlVideos[i]).width() != vidWidths[i]) {
vidWidths[i] = $(htmlVideos[i]).width();
checkVidChange(true);
return;
}
}
}
setInterval(checkVidWidth, 3);
vidWidths is an array defined elsewhere of the prior widths of the video. But I don't want to use setInterval I want to make an event that occurs when $(htmlVideos[i]).width() changes.
These events already exist - there's no need to build your own logic to achieve this, and certainly not by running your code every 3ms.
You can use the fullscreenchange event, like this using jQuery:
$('video').on('fullscreenchange webkitfullscreenchange mozfullscreenchange', function(e) {
var videoIsFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
if (videoIsFullScreen) {
// video is full screen, do something...
}
else {
// video was full screen, has now been restored to default size
}
});
Note that I also bound the webkit and moz variations of the event for full compatibility.
You can use fullscreen change event to detect fullscreen :
$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange',
And use resize evet to detect width change
$('#video').resize(function() {
});
EDIT
Resize event CAN be applied on elements other than the window using jquery, check this example.
I'm using scrollTo() for page scrolling. One problem I found is, when I resize browser, page don't scroll again to element I specified, but it stays somewhere in middle, so I have to click 'scroll' button again to align the page. Is there any way to align page when user resize browser.
I tried using this:
window.onresize = function() {
scrollToPosition(section[position]);
}
// position is variable which I declared above this event
But this makes scrolling crazy, the page start to move right/left really fast which is not normal. I believe it binds onresize event every time I resize browser.
Is there any solution for my problem
EDIT:
This is jsFiddle, but it seems I don't know how to use jsFiddle since nothing works here: http://jsfiddle.net/52eRj/1/
You can avoid reruning function everytime the resize event is executed by writing code as below. scrollToPosition function will be executed every 1 second when scrolling.
var last = new Date().getTime();
var interval = 1000; // Set your own time.
window.addEventListener('resize', function() {
var curr = new Date().getTime();
if (curr - last > interval) {
last = curr;
scrollToPosition(section[position]);
}
});
The problem might be that you are calling your scrollToPosition function on every resize event, which can be fired 100 times in a normal manual resize.
To avoid this you can use clearTimeout like this:
$(window).resize(function () {
clearTimeout(resizeId);
resizeId = setTimeout(doneResizing, 500);
});
function doneResizing() {
scrollToPosition(section[position]);
}
This way the doneResizing function would only be called after 500 miliseconds since the window has stopped resizing, avoiding therefore, those tens or hundreds of unnecessary calls.
I have some code that listens to the scrolling of a page and it's responsible for two things, performing the necessary action (which works) when the "page" has changed but also animate the scrollTop to the nearest "page" but in doing so the scroll event is fired so it sequentially crawls through all the "pages" until it reaches the end of the document.
How can I stop animate scrollTop from firing the scroll event? Is it even possible?
"pages" because this is an iPad html page and each 1024x768 view is a "page"
You can find a answer at this post : https://stackoverflow.com/a/1659231/237838
You could make write your own code to set the animation value, and set
a flag indicating that the change comes from an animation.
For example: (Untested)
var scrollAnimating = false
jQuery.fx.step.scrollTop = function(E) {
scrollAnimating = true;
E.elem.scrollTop = E.now;
scrollAnimating = false;
};
$('#gototop').click(function() {
$('body').animate({scrollTop:0},3000);
$(window).scroll(function () {
if (!scrollAnimating)
$('body').stop();
});
return false;
})
People!
This is the first time I come here to ask something, so far, always when I had a problem, I could find a good answer here. So, in first place, thanks for this amazing community!
Now let's go to the problem:
I'm doing a responsive menu that check the window.resize event and, when it fits the minimum browser width, a click function for a button is allowed. If the browser width is greater, then the click function is unbound. I need to do this because the same element that is the button on the mobile version, is a visual element on the desktop version.
The problem is that, with the code that I have now, when the page is loaded, the click function works fine. But, if I resize the browser and click on the element again, it triggers more than once the state, sometimes leaving the impression that the function isn't triggered. And, if I resize the browser again, it triggers the click function more than the last time I clicked. Really annoying.
To help understand what is happening, I've made a simple example. Here's is the simple code (just to check the click function issue):
HTML:
<ul>
<li><span class="sub-toggle">Testing 01</span></li>
<li><span class="sub-toggle">Testing 02</span></li>
<li><span class="sub-toggle">Testing 03</span></li>
</ul>
CSS:
.sub-toggle{
display:block;
padding: 20px;
}
.sub-toggle.active{
background-color: #ffcc00;
color: #fff;
}
Javascript (jQuery):
jQuery(function($){
var i = 1;
// check if browser size is compatible with click event
onResize = function() {
// if browser size is ok, do the click function
if($(window).width() <= 480){
// click function
$('.sub-toggle').click(function(){
alert('click');
if($(this).hasClass('active')){
alert('active');
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
} else{
// if browser size is greater than expected, unbind the click function
$('.sub-toggle').removeClass('active').unbind('click');
}
// just checking how many times the resize function is triggered
console.log('resize: '+ i);
i++;
}
$(document).ready(onResize);
var timer;
$(window).bind('resize', function(){
timer && clearTimeout(timer);
timer = setTimeout(onResize, 500);
});
});
(Edited to remove some unnecessary code)
If you want to see it in action, I've made a Fiddle (try resize the output frame to see it working): http://jsfiddle.net/C7ppv/1/
Maybe I've missing something really stupid, since I don't have a huge knowledge in JavaScript. But what I want to do is just trigger the click event once, even if multiple resizes.
I hope I could explain well my problem. I've searched and didn't found a solution for this issue (or maybe I just didn't know really well what to look for).
Any help would be appreciated!
Your code currently binds a new click events every time the method onResize is called and the window width is less than or equal to 480px.
Simply unbind any existing click events on the .sub-toggle element before binding a new one.
$('.sub-toggle').unbind('click').click(function() {
...
});
DEMO
The resize event is triggered multiple times during resizing, and each time you're binding a new click handler. My suggestion: bind only once, from outside the resize handler, and set a flag while resizing to let the click handler know if it should do something or not.
Then you won't even need to defer the handling of resize with setTimeout as you're doing.
DEMO
jQuery(function($){
var i = 1;
// flag to allow clicking
var clickAllowed = true;
// click function
$('.sub-toggle').click(function(){
if(clickAllowed) {
alert('click');
if($(this).hasClass('active')){
alert('active');
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
}
});
// check if browser size is compatible with click event
onResize = function() {
//if browser size is ok, do the click function
if($(window).width() <= 480){
clickAllowed = true;
}
else{
// if browser size is greater than expected, disallow clicking
clickAllowed = false;
}
// just checking how many times the resize function is triggered
console.log('resize: '+ i);
i++;
}
$(document).ready(onResize);
var timer;
$(window).bind('resize', onResize);
});
Move $('.sub-toggle').click(function(){...} outside the onResize event handler and move if($(window).width() <= 480){...} into the click handler.