Вопрос по jquery, javascript, css, callback – JS для отслеживания изменения свойства CSS, например «display: none» => «display: block»?

4

Я хочу запустить некоторый код JS, когда свойство CSS изображения "display" был изменен любым другим JS-скриптом / функциями. Есть ли способ контролировать это изменение и настроить функцию обратного вызова?

<code>$(this).bind.('propertychange', function(){}) 
</code>

не может сделать это, и setInterval также плохая идея.

Что еще можно сделать?

Я понимаю (поверьте мне), но вы могли бы перезаписать эту функцию, сделать условный дескриптор и затем вызвать исходную функцию, не затрагивая другую систему. Я делал это бесчисленное количество раз без проблем. Jeff
Почему вы не можете переопределить / перехватить другую функцию JS вместо того, чтобы связываться с изменениями свойств CSS? Jeff
@Jeff Спасибо за ваши комментарии. Причина в том, что я не могу изменить их код, или их код слишком сложен для изменения. С другой стороны, поддерживать чистоту между различными системами - это хорошая практика. Alix

Ваш Ответ

4   ответа
1

// this is your original, unmodified function
function originalFunction(sel) {
    alert(sel);
    $(sel).css("display","none");
}

Это в вашем коде:

// here is a sample callback function you pass into the extended function below
function myCallback(s) {
    alert("The image with src = '" + $(s).attr("src") + "' has been modified!");
}


// here is how you can extend the function to do what you want 
  // without needing to modify the actual code above
originalFunction = (function(legacyFn, callback) {

    // 1 arg function to be returned and reassigned to originalFunction
    return function(sel) {

        // call "original" originalFunction, with alert and image hide.
        legacyFn(sel);  

        if(callback) callback(sel);  // invoke your callback
    }

})(originalFunction, myCallback);

ПеременнаяoriginalFunction назначается функция, которая принимает один аргумент. Функция, которая принимает один аргумент, возвращается анонимной, автоматически выполняющейся функцией, которая принимает 2 аргумента, ссылку наoriginalFunction прежде чем он будет изменен, и ссылка наcallback функция. Эти две ссылки на функции становятся «заблокированными» внутри закрытия, так что когдаoriginalFunction затем присваивается новое значение самовыполняющейся функцией,legacyFn параметр по-прежнему содержит ссылку наoriginalFunction до его изменения.

Таким образом, на более высоком уровне,originalFunction а такжеmyCallback передаются в качестве параметров самозапускающейся анонимной функции и передаются в переменные legacyFn и callback, а затем назначается новая функцияoriginalFunction.

Теперь, когда вы звонитеoriginalFunction('.someClassOnAnImage'), legacyFn сработает, что предупредит селектор и установит для свойства display значение none. После этого сработает функция обратного вызова, если она существует, и вы увидите:

The image with src = '.someClassOnAnImage' has been modified!

Хотя это не так хорошо, как гипотетический или специфичный для платформы addEventListener, он позволяет вам изменять поведение функций в унаследованном коде без необходимости физически открывать эти файлы и изменять их. Это просто расширяет функции для выполнения дополнительных действий, но без необходимости изменять исходные функции или даже оригинальные файлы в этом отношении.

Вы можете аккуратно включить все свои расширения в отдельный файл JavaScript (или любой другой файл JavaScript, в котором вы работаете), и если вы когда-нибудь захотите вернуться к исходному поведению, вы просто удалите свои расширенные функции.

Хорошая точка зрения! Забавно, что ты упоминаешь это. Мне действительно нужно вернуться и изменить некоторые методы, чтобы они были названы. Хотя я думаю, что это хорошая практика для меня и моего сценария, я вижу, как это решение может быть ограничено в вашем конкретном сценарии. Спасибо за продолжение!
Да. Это полезный ответ, но не работа для меня. Потому что это решение имеет 2 условия. 1-е: их функция должна быть не анонимной, а именной (даже в глобальном пространстве имен). 2-й: я должен знать все имена их функций (возможно, более одной функции), которые изменили этот CSS. Эти условия смешивают это решение с их кодом и логикой. Как только они изменили свой код, мы должны обновить этот код. Спасибо за вашу помощь. :) Alix
1

я бы порекомендовал написать одну функцию, которая изменяет свойство стиля изображения, а затем использовать эту функцию в качестве узкого места, через которое все другие функции должны пройти, чтобы изменить это свойство стиля изображения.

function showImage(selector, callback) {
    $(selector).css("display","block");
    if(callback)
        callback();
}

function hideImage(selector, callback) {
    $(selector).css("display","none");
    if(callback)
        callback();
}

Нечто подобное вышеперечисленным двум функциям может быть вызвано из любого места вашего JavaScript, когда вы должны изменить свойство CSS изображения. Функции также принимают функцию в качестве параметра, который впоследствии будет выполняться при условии, что функция была передана как 2-й параметр.

Вы могли бы еще больше упростить это до единой функции, но я оставлю это вам, так как не знаю точно, каковы ваши цели в этом.

Этот метод работает. Но я хочу знать, сможем ли мы решить эту проблему без каких-либо изменений в другом коде. Благодарю. Alix
8

Это то, что вы ищете:

document.documentElement.addEventListener('DOMAttrModified', function(e){
  if (e.attrName === 'style') {
    console.log('prevValue: ' + e.prevValue, 'newValue: ' + e.newValue);
  }
}, false);
@ marian-zburlea - я получил тот же результат, что и jmort253. Этот код работает только для Firefox, а не для Chrome. Это правда? Alix
Большой! Это то, что я ищу. Благодарю. Alix
альтернатива - использовать setInterval и прослушивать изменение свойства, сравнивая значение по умолчанию с текущим, но это потребляет ресурсы
@Marian - отличное решение, но я не могу заставить его работать в моем отладчике Chrome? Ты знаешь, чего мне не хватает? Я добавил идентификатор в изображение вашего профиля и попытался скрыть его, используя$('#testt').attr("style","display:none"); и я не вижу никаких записей журнала. Является & quot; documentElement & quot; должен быть заполнителем для фактического элемента? Не могли бы вы также включить ссылку, которая описывает это более подробно? Спасибо.
1

есть ли альтернатива DOMAttrModified, которая будет работать в webkit

Рэнт: События DOM Mutation содержат ключ к вашей проблеме. Однако в новой волне браузерных войн Wekit и Gecko не могут договориться о вещах. В то время как в Gecko есть DOMAttrModified, в webkit есть нечто, называемое наблюдателем мутаций (что нарушает схему привязки обработчиков событий к событиям, но кто же заботится о согласованности, когда мы хотим заблокировать пользователей / кодировщиков правильно?;)

П.С .: Просто добавлю это сюда для будущих искателей той же мудрости.

Похожие вопросы