#jquery #media-queries
#jquery #медиа-запросы
Вопрос:
У меня есть функция jQuery, которая должна запускаться только тогда, когда определенный медиа-запрос имеет значение true (как при готовности, так и при изменении размера).
Я нашел классный трюк, чтобы проверить, является ли определенный медиа-запрос истинным:
HTML
<div id="isthin"></div>
CSS
#isthin {
display: inline-block;
content: '';
width: 1px;
height: 1px;
overflow: hidden;
}
@media only screen and (max-width: 1047px) {
#isthin {
display: none;
}
}
jQuery
$(document).ready(function(){
if ( $('#isthin').is(":visible") ) {
// function should be fired
} else {
// function should not be fired
}
});
$(window).resize(function(){
if ( $('#isthin').is(":visible") ) {
// function should be fired
} else {
// function should not be fired
}
});
Отдельная функция jQuery
$(function () {
$('nav li ul').hide().removeClass('sub-nav');
$('nav li').hover(function () {
$('ul', this).stop().slideToggle(300);
});
});
Это была моя логика, но каким-то образом функция все еще выполняется при изменении размера при изменении медиа-запроса.
Комментарии:
1. Вы когда-нибудь слышали о
matchmedia
?2. Да, но я должен поддерживать IE9 …
3. Это прискорбно…
4. Ну, у вас отсутствует скобка, но как только вы ее добавите, она заработает: jsfiddle.net/uLq5L
5. О, я добавил парантезис. Ваша скрипка работает, но если я не переопределяю или не останавливаю функцию, она каким-то образом все равно выполняется …
Ответ №1:
Основываясь на ваших фрагментах, я открыл этот скрипт в браузере:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<style type="text/css">
#isthin {
display: inline-block;
content: '';
width: 1px;
height: 1px;
overflow: hidden;
border: 1px solid red;
}
@media only screen and (max-width: 1047px) {
#isthin {
display: none;
}
}
</style>
<script type="text/javascript">
$(document).ready(function(){
if ( $('#isthin').is(":visible") ) {
// function should be fired
console.log("[doc ready] Media Query wide");
} else {
// function should not be fired
console.log("[doc ready] Media Query thin");
}
});
$(window).resize(function(){
if ( $('#isthin').is(":visible") ) {
// function should be fired
console.log("[Resize] Media Query wide");
} else {
// function should not be fired
console.log("[Resize] Media Query thin");
}
});
</script>
</head>
<body>
<div id="isthin"><id>
</body>
</html>
Если я снова сужу и расширяю браузер, я вижу сообщения консоли такими, какими они должны быть:
[doc ready] Media Query wide
[Resize] Media Query wide
[Resize] Media Query wide
[Resize] Media Query wide
[Resize] Media Query wide
...
...
[Resize] Media Query thin
[Resize] Media Query thin
[Resize] Media Query thin
[Resize] Media Query thin
...
[Resize] Media Query wide
...
...
Поэтому я думаю, что ваш способ обнаружения медиа-запроса правильный (и сложный). Я предлагаю вам проверить:
- если это проблема, связанная с браузером,
- как ваша отдельная функция jQuery связана с обратным вызовом изменения размера.
Тогда учтите, что в этом случае вы не экономите часть работы, используя CSS-запросы. Вам все равно нужен обратный вызов resize. Итак, посмотрите на этот другой элегантный способ, который я видел для решения этой проблемы. Это наоборот, избегая селекторов CSS, но делая то же самое:
$(window).resize(function(){
if ( $(window).width() < xxxx amp;amp; $(window).width() > yyyyy ) {
$('body').addClass('phone'); // <<<<<<<<<<<<<<
$('body').removeClass('tablet');
$('body').removeClass('workstation');
} else if ( ... ) {
$('body').removeClass('phone');
$('body').addClass('tablet'); // <<<<<<<<<<<<<<
$('body').removeClass('workstation');
}
...
...
}
Затем вы можете легко отличить в CSS, добавив .phone , .tablet и .workstation в селекторы и, возможно, удалить запросы. Далее:
$(window).resize(function(){
if ($('body').hasClass('phone')) {
...
...
} else if ( ... ) {
...
}
...
...
}
Таким образом, у вас есть все это на стороне JS и меньше на стороне CSS.
Идея принадлежит не мне, я видел ее в рамках, но я не уверен, какой она была.
Ответ №2:
Проблема заключается не в самом медиа-запросе, а в том, как вы привязываете свое событие.
Вы привязываете его при каждом изменении размера, когда запрос подходит. Вы действительно должны отключить все свои функции и использовать флаг. Вот так :
var flag = true;
$(window).resize(function(){
flag = $('#isthin').is(":visible");
if(flag){
$('nav li ul').hide().removeClass('sub-nav');
}else{
$('nav li ul').show().addClass('sub-nav');
}
})
$(document).ready(function(){
$(window).trigger('resize');
})
$(function () {
$('nav li').hover(function () {
if(flag){
$('ul', this).stop().slideToggle(300);
}
});
});
Комментарии:
1. Большое вам спасибо за вашу помощь!