jquery - 检测 html 元素更改的 jQuery 最佳实践
问题描述
我有两个运行良好的代码选项,但我想知道什么是最好的选择,假设我有时会在高流量网站中同时触发几个此脚本。
该代码用于限制输入复选框的选择,以下脚本仅用于 1 个部分,但我将在每个页面中同时检查 4 个或更多部分(我仍在编码循环检查,所以这里只是一个部分)。
选项1
jQuery( function($){
var max_opcoes = 2;
var inputs_opcoes = "div.wc-pao-addon-container:has([data-addon-name='Opções']) input";
$('body').on('change', inputs_opcoes, function(){
var $inputs_opcoes = $(inputs_opcoes);
if($inputs_opcoes.filter(':checked').length == max_opcoes) {
$inputs_opcoes.attr('disabled', 'disabled');
$inputs_opcoes.filter(':checked').removeAttr('disabled');
} else {
$inputs_opcoes.removeAttr('disabled');
}
});
});
选项 2
jQuery( function($){
var onDomIsRendered = function(domString) {
return new Promise(function(resolve, reject) {
function waitUntil() {
setTimeout(function() {
if($(domString).length > 0){
resolve($(domString));
}else {
waitUntil();
}
}, 100);
}
//start the loop
waitUntil();
});
};
onDomIsRendered("div.wcpt-product-form.wcpt-modal").then(function(element){
var max_opcoes = 2;
var $inputs_opcoes = $("div:has([data-addon-name='Opções']) > input");
$inputs_opcoes.change(function() {
//$( $inputs_opcoes ).on( 'change', function() {
if($inputs_opcoes.filter(':checked').length == max_opcoes) {
$inputs_opcoes.attr('disabled', 'disabled');
$inputs_opcoes.filter(':checked').removeAttr('disabled');
} else {
$inputs_opcoes.removeAttr('disabled');
}
});
因此,两种代码的基本区别是:
$('body').on('change', inputs_opcoes, function(){
(... function here ...)
和
var onDomIsRendered = function(domString) {
return new Promise(function(resolve, reject) {
function waitUntil() {
setTimeout(function() {
if($(domString).length > 0){
resolve($(domString));
}else {
waitUntil();
}
}, 100);
}
//start the loop
waitUntil();
});
};
onDomIsRendered("div.wcpt-product-form.wcpt-modal").then(function(element){
(... function here ...)
解决方案
你可能不应该像这样使用 setTimeout,因为它每 100 毫秒使用一次 CPU,而且我看不到这一点,因为从它的外观来看,当它到达 onDomIsRendered 时,jQuery 的 ready 事件已经被触发,所以有什么意义?
另一个观察是你应该使用 prop 而不是 attr 因为它更快。您还可以通过将“body”替换为 document.body 并将您的第一次调用保存到 $inputs_opcoes.filter(":checked") 来加速它。这就是我的意思:
jQuery( function($){
var max_opcoes = 2, inputs_opcoes = 'div.wc-pao-addon-container:has([data-addon-name="Opções"]) input';
$(document.body).on("change", inputs_opcoes, function(){
var $inputs_opcoes = $(inputs_opcoes), $checked = $inputs_opcoes.filter(":checked");
if ($checked.length == max_opcoes) {
$inputs_opcoes.prop("disabled", true);
$checked.prop("disabled", false);
}
else {
$inputs_opcoes.prop("disabled", false);
}
});
});
Promise 在旧版浏览器中也不可用。如果你真的需要使用 jQuery 的 $.Deferred() ,它对于这么简单的事情来说已经足够好了。并使用 MutationObserver 代替 setTimeout。
推荐阅读
- xamarin.ios - 解决 Xamarin AOT 错误
- java - 如果以后想通过多个属性搜索对象,如何存储对象?
- reactjs - 反应地图未定义错误
- json - 如何访问 json 属性 laravel
- python - 创建流程树形式的 json 文件。在蟒蛇
- node.js - passport.js 登录不起作用
- spring - 在没有冻结浏览器作为客户端的情况下,在 Spring 中使用 deferredResult 在后台运行任务
- html - 媒体查询、视口居中和倾斜边距
- angular - 类方法的扩展泛型参数不构建
- authentication - .net core 2.0 & Identityserver4:注销后 Cookie 未过期