问题
I am trying to use a function on mobile devices (less than 700px in this example) and another function on large devices. I use matchMedia in the following way:
var mql = window.matchMedia("(min-width: 700px)");
mql.addListener(handleResize);
handleResize(mql);
function handleResize(mql) {
if (mql.matches) {
$(".button").on("click", function(){
$(".hidden").slideToggle();
})
} else {
$(".button").on("click", function(){
$(".hidden").fadeToggle();
})
}
}
At first, the code behaves as expected, the problem occurs when I resize the window. For instance, if the window first loads under 700px and then is resized to more than 700px, the button fires fade first, then slide and vice versa. What I want to achieve off course is calling only slide on large sreens and only fade on small screens. Any help is greatly appreciated.
Cheers!
回答1:
The problem is that every time the handleResize
callback fires, it attaches another click event to the button. To prevent attaching a ton of events, you have to first remove it with off()
.
Here is an example that accomplishes what you wanted:
var $hidden = $('.hidden');
var $btn = $('button');
var mql = window.matchMedia("(min-width: 700px)");
function bindSlide() {
// Using `off()` is required in order not to end up attaching a lot of callbacks
$btn.off("click.mql").on("click.mql", function() {
$hidden.stop().slideToggle();
});
}
function bindFade() {
$btn.off("click.mql").on("click.mql", function() {
$hidden.stop().fadeToggle();
});
}
function handleScreen(mql) {
if (mql.matches) {
bindSlide();
} else {
bindFade();
}
}
// Handle media query 'change' event
mql.addListener(handleScreen);
handleScreen(mql);
Please note that window.matchMedia
isn't supported by all Browsers. For Browsers that don't support matchMedia natively you can use a polyfill: https://github.com/paulirish/matchMedia.js
Live example: http://jsfiddle.net/rhkLng9o
来源:https://stackoverflow.com/questions/28441314/matchmedia-calls-functions-twice