I'm using a plugin which is called Sidr to create a Facebook like sidebar. It intialized with:
$('#menu_trigger').sidr({
name: 'sidr-right',
side: 'right'
});
Problem is, that I only want to have this effect at a specific viewport size. I know that many jQuery plugins come with a something like a destroy argument to unload the script. But this plugin does not.
Does anyone know how I could unbind this function off #menu_trigger when a specific browsersize is triggered.
Like:
enquire.register("screen and (max-width:560px)", {
$('#menu_trigger').sidr({
// unload, unbind
});
}
Thanks
http://jsbin.com/bemimu/8/edit
You can use unbind and pass in the plugin reference to the selected elements, then check the window size in JavaScript. $.sidr('close', 'sidr-right');
JS:
function clickForSidr() {
var ww = document.body.clientWidth;
if(ww < 560){
if(sidrIsOpen){
$.sidr('close', 'sidr-right');
}else {
$.sidr('open', 'sidr-right');
}
sidrIsOpen = !sidrIsOpen;
}
};
var sidrIsOpen = false;
$('.unbindme').on('click',function(){
clickForSidr();
});
MARKUP:
<div class="unbindme" >unbindme</div>
Related
I want to toggle events based on width. for mobile only click event should work. for desktop hover event should work. while page loading my code working properly when resize my code is not working.
please help me why my code is not working. Thanks in advance
$(document).ready(function(){
function forDesktop(){
$(".popover-controls div").off('click');
$(".popover-controls div").on('hover');
$(".popover-controls div ").hover(function(e){
//popup show code
});
}
function forMobile(){
console.log("mobile");
$(".popover-controls div").off('hover');
$(".popover-controls div").on('click');
$(".popover-controls div").click(function(e){
//popop show
});
}
function process(){
$(window).width() > 600?forDesktop():forMobile();
}
$(window).resize(function(){
process()
});
process();
});
Its very simple, 1st you cant write this much of code for every event. We have to come up with very simple solution, here is how it works
1st check the width of the Page in JS and assign Desktop/Mobile Class on body :
function process(){
if( $(window).width() > 600){
$("body").removeClass("mobile").addClass("desktop");
}else{
$("body").removeClass("desktop").addClass("mobile");
}
}
$(window).resize(function(){
process()
});
Now, you have execute the command for hover and click:
$(document).on('mouseover', 'body.mobile .popover-controls div',function(e){
alert("hover");
});
$(document).on('click', 'body.desktop .popover-controls div',function(e){
alert("click");
console.log("click");
});
I Hope this will work for you. :)
Check the Js fiddle Example: http://jsfiddle.net/asadalikanwal/xcj8p590/
I have just created for you, also i have modified my code
You could use a JavaScript Media Query to determine the width of the screen as detailed here.
var mq = window.matchMedia( "(min-width: 500px)" );
The matches property returns true or false depending on the query result, e.g.
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}
First Detect the Mobiles/Tablets Touch Event:
function is_touch_device() {
return 'ontouchstart' in window // works on most browsers
|| 'onmsgesturechange' in window; // works on ie10
};
Then Try like this:
function eventFire() {
var _element = $(".popover-controls div");
// True in Touch Enabled Devices
if( is_touch_device() ) {
_element.click(function(e) { .... });
}
else {
// apply Hover Event
_element.hover();
}
}
No need to detect width of devices ;)
There is one more solution with third party and Most popular library is Modernizr
This worked for me. It's a combination of the matchMedia() functionality #Ḟḹáḿíṅḡ Ⱬỏḿƀíé shared as well setTimeout() functionality #Jeff Lemay shared at TeamTreeHouse.com
The primary thing I contributed to was the use of the .unbind() functionality. It took me quite a while to figure out that this was necessary so the .hover() and .click() functions don't cross wires.
//Add/remove classes, in nav to show/hide elements
function navClassHandler(){
if($(this).hasClass('active')){
$('.dropdown').removeClass('active');
}else{
$('.dropdown').removeClass('active');
$(this).addClass('active');
}
}
function handleNav() {
//instantanteous check to see if the document matches the media query.
const mqM = window.matchMedia('(max-width: 1025px)');
const mqD = window.matchMedia('(min-width: 1025px)');
$('.dropdown').unbind(); //necessary to remove previous hover/click event handler
if (mqM.matches) {
console.log("Handling mobile");
$('.dropdown').click(navClassHandler);
} else {
console.log("Handling desktop");
$('.dropdown').hover(navClassHandler);
}
}
// we set an empty variable here that will be used to clearTimeout
let id;
/* this tells the page to wait half a second before making any changes,
we call our handleNav function here but our actual actions/adjustments are in handleNav */
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(handleNav, 500);
});
//As soon as the document loads, run handleNav to set nav behavior
$(document).ready(handleNav);
I have an image, the src of which I am rapidly changing. I have a handler attached to the image element's load event. Is there a way to get the src corresponding to the load event being fired, without instantiating a new image object every time I load an image?
You probably have something like this:
function eventHandler(event) {
// event.currentTarget holds your element, query it to get info
}
as function bound to the event, if you use jQuery you could do something like
$(event.currentTarget).attr('src');
to get the current src.
First, it's easier to handle the event if it's in the handler's definition:
function image_load(event) {
//...
}
Then, you will need to access the element that just fired the event, which is possible to obtain like this:
function image_load(event) {
var src=event.target.src;
//...
}
BUT, nothing is that simple.. you have to deal with cross-browser incompatibilies:
function image_load(event) {
var evt=event||window.event; // data is either in event or window.event
var img=evt.target||evt.srcElement; // eiter in .target or .srcElement
var src=img.src; // :)
//...
}
I assumed that you wanted a plain js solution as jQuery isn't tagged. In jQuery, incompatibilities are greatly reduced while dealing with the event chain, but it also reduces performances, it's up to you to use it or not.
Hope this helps.
I guess it's not possible to trigger a certain onload handler corresponding to the src, but you can store (all) previous src(s) to the image, and then choose a function to execute. Something like this:
window.onload = function () {
var n,
images = document.images,
imgOnload = function (e) {
var target = e.target || e.srcElement;
// do something with target.previousSrc
target.previousSrc = target.src;
// target.previousSrc.push(target.src);
return;
};
for (n = 0; n < images.length; n++) {
if (images[n].addEventListener) {
images[n].addEventListener('load', imgOnload, false);
} else {
images[n].attachEvent('onload', imgOnload);
}
images[n].previousSrc = images[n].src;
// images[n].previousSrc = [];
// images[n].previousSrc.push(images[n].src);
}
return;
}
document.images here contains all the images in the document, but ofcourse you can create your own collection of the images you need.
A live demo at jsFiddle (using only the latest src).
Have the following code:
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
});
});
Works all fine, but now I would like the load() / show() function only be called if #content does not already contain blogs.html.
In other words: I would like to check if blogs.html is already loaded and if yes, simply do nothing and only if not there yet I would load and show it.
Have tried some things with hasClass() and some if-formulas but struggle to get this check.
Tried stuff like this:
$("#content section").hasClass("check_blog").hide().load("blogs.html", function(){
$("#content").show("slide");
Basically I just need to know how I can check if blogs.html is already the contents of #content.
Thanks a lot for any help. Regards, Andi
Add an ID to some element in blogs.html, say blogsloaded, then you can check for it with:
if (!$("#blogsloaded").length)
$("#content").hide().load("blogs.html" ...
Another method would be to store in a variable if you already loaded it:
if (!this.blogsloaded)
{
this.blogsloaded=true;
$("#content").hide().load("blogs.html" ...
}
I would split up your mouseover events into two namespaced events. One which will only run once.
// This event will only run once
$("#blogs").on("mouseover.runonce", function () {
$("#content").load("blogs.html");
});
// because this event will unbind the previous one
$("#blogs").on("mouseover.alwaysrun", function () {
$(this).off("mouseover.runonce");
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
$("#content").hide();
});
Update a data attribute on #content that contains the url or id of the currently loaded content. Also, you should handle the case where the user hovers over a different section before the previous is done loading.
var request; // use this same var for all, don't re-declare it
$("#blogs").mouseover(function () {
// exit event if the blog is the current content in #content
if ( $("#content").data("current") == "blog") return;
$("#content").data("current","blog");
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
// if a previous request is still pending, abort it
if ($.isFunction(request.abort) && request.state() == "pending") request.abort();
// request content
request = $.get("blogs.html");
$("#content").hide();
// when content is done loading, update #content element
request.done(function(result){
$("#content").html(result);
});
});
I strongly suggest against using hover for loading content with ajax.
Also, in it's current form, this code is not very re-usable, you'll have to have one for each link. I suggest instead using classes and having only one event binding handling all of the links.
You can do it like this using .has() to detect descendants of content
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home,#homepages,#apps,#facebook,#kontakt").removeClass("hover");
var $c = $("#content");
if($c.has('.check_blog')){ // if content contains an element with that class
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
}
});
});
You could do something like this:
$("#blogs").mouseover(
function () {
$(this).addClass("hover");
$("#home").removeClass("hover");
$("#homepages").removeClass("hover");
$("#apps").removeClass("hover");
$("#facebook").removeClass("hover");
$("#kontakt").removeClass("hover");
if($('#content').html() == '') {
$("#content").hide().load("blogs.html", function(){
$("#content").show("slide");
});
}
});
I need to set some contextData for a popup window from its parent. I try this:
var some contextData = {};
$(function() {
$('#clickme').click(function() {
var w = window.open('http://jsfiddle.net');
w.contextData = contextData
//w.context data is null in the popup after the page loads - seems to get overwritten/deleted
});
});
It doesn't work, so my next thought, wait until content is loaded
var some contextData = {};
$(function() {
$('#clickme').click(function() {
var w = window.open('http://jsfiddle.net');
w.onload = function() {
//Never Fires
w.contextData = contextData;
}
});
});
See this fiddle. My onload method never fires.
This works:
var some contextData = {};
$(function() {
$('#clickme').click(function() {
var w = window.open('http://jsfiddle.net');
setTimeout(function(){
if(w.someVariableSetByThePageBeingLoaded) {
w.contextData = contextData;
}
else{
setTimeout(arguments.callee, 1);
}
}, 1);
});
});
But has obvious elegance problems (but is the current work around).
I know you can go the other way (have the popup call back to a method on the opener/parent, but this forces me to maintain some way of looking up context (and I have to pass the key to the context to the popup in the query string). The current method lets me capture the context in a closure, making my popup a much more reusable piece of code.
I am not trying to do this cross domain - both the parent and popup are in the same domain, although the parent is an iframe (hard to test with jsfiddle).
Suggestions?
If you are doing this with an iframe try it this way
HTML
<button id="clickme">Click Me</button>
<iframe id="framer"></iframe>
Javascript
$(function() {
$('#clickme').click(function() {
$("#framer").attr("src","http://jsfiddle.net");
$("#framer")[0].onload = function(){
alert('loaded');
};
});
});
I updated your jsfiddle http://jsfiddle.net/HNvn3/2/
EDIT
Since the above is completely wrong this might point you in the right direction but it needs to be tried in the real environment to see if it works.
The global variable frames should be set and if you
window.open("http://jsfiddle.net","child_window");
frames["child_window"] might refer to the other window
I got javascript access errors when trying it in jsfiddle - so this might be the right track
EDIT2
Trying out on my local dev box I was able to make this work
var w = window.open("http://localhost");
w.window.onload = function(){
alert("here");
};
the alert() happened in the parent window
I have the following code in a JavaScript file:
$(document).ready(function() {
detectscreen();
});
$(window).resize(function(){
detectscreen();
});
function windowWidth() {
if(!window.innerWidth) {
// user is being a git, using ie
return document.documentElement.clientWidth;
} else {
return window.innerWidth;
}}
function detectscreen() {
if (windowWidth()>1280) {
$('body').append('<div id="gearsfloat"></div>');
}}
Basically, what it does is append an object to the end of the document if the width is less than 1280 pixels, however what this does is append it every single time the page is resized.
I don't think I can use the once function because it would only run it once and then the next time it is resized, it's dead. Anything I can do?
NOTE: I, in fact, DO want it to be checked on the resize of the page, but the effect is that it happens over and over again.
if (windowWidth()>1280 && !$('gearsfloat')) {
$('body').append('<div id="gearsfloat"></div>');
}
The above (by Jason) works does not work but then it won't delete it when it gets less than 1280. Is there anything I can do?
Keep track of whether the element exists or not, and add/remove it when the condition changes. That way you will only add it once, it will be removed when it shouldn't be there, and you don't do any unneccesary adding or removing:
var gearsExists = false;
function detectscreen() {
var shouldExist = windowWidth() > 1280;
if (shouldExist != gearsExists) {
if (shouldExist) {
$('body').append('<div id="gearsfloat"></div>');
} else {
$('#gearsfloat').remove();
}
gearsExists = shouldExist;
}
}
if (windowWidth()>1280 && !$('gearsfloat')) {
$('body').append('<div id="gearsfloat"></div>');
}
Check if the element already exists first?
if you dont want the function to be called when the window is resized, then why are you binding the resize function?
wont the document ready function always be called before the resize function anyway, so you are guaranteed to have your element appended?