2017-01-08 8 views
0

Так что проблема в том, что у меня есть элемент html, у которого есть объект в атрибуте «data-» (устанавливается через jQuery ofc), и я хочу слушать изменения этого атрибута.Может ли наблюдатель мутации прослушивать изменения атрибутов «data-»?

Я уже пробовал много вещей, например, установил почти все возможные значения комбинации в MutationObserverInit object, но ничто из этого не поможет.

Кто-нибудь знает, если это возможно?

$('#some-id').click(function() { 
 
    //$('#some-id').attr('title', 'some-title'); //this works 
 
    $('#some-id').data('foo', 'bar1'); //this don't 
 
}); 
 

 
var functionCallBack = function(mutations) { 
 
    alert('something changed') 
 
} 
 

 
// select the target node 
 
var target = document.getElementById("some-id"); 
 

 
// create an observer instance 
 
var observer = new MutationObserver(functionCallBack); 
 

 
// configuration of the observer: 
 
var config = { subtree: true, childList: true , attributes: true}; 
 

 
// pass in the target node, as well as the observer options 
 
observer.observe(target, config); 
 

 
$('#some-id').data('foo', 'bar');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="some-id">HEY</div>

+0

Пожалуйста, покажите, что именно вы пробовали.Конечно, можно прослушать изменения атрибутов 'data-' с помощью 'MutationObserver'. – Xufox

+3

* «установить через jQuery» * ... если он установлен с использованием метода 'data()', это не будет атрибут. Пожалуйста, покажите все соответствующие коды, если вы хотите помочь – charlietfl

+0

@Xufox Я добавил jsfiddle. – user3149173

ответ

2

Новый ответ (на основе Oriol's Answer):

Я думаю, Ориоль при условии, лучший подход, но она может быть оптимизирована дальше.

var object = { 
 
    'key': 'value' 
 
}; 
 

 
$('.addObj').click(function() { 
 
    $('#some-id').observeData('foo', object, function() { 
 
    console.log("Object Added"); 
 
    }); 
 
}); 
 

 
$('.removeObj').click(function() { 
 
    $('#some-id').observeData('foo', null, function() { 
 
    console.log("Object removed"); 
 
    }); 
 
}); 
 

 

 
jQuery.fn.observeData = function(name, object, callback) { 
 
    // Get elemenet 
 
    var element = $(this[0]); 
 

 
    // Add data 
 
    element.data(name, object); 
 

 
    // Call the callback function 
 
    callback(); 
 

 
    // Return this for a chainable function 
 
    return this; 
 
};
span { 
 
    padding: 10px; 
 
    float: left; 
 
    margin: 5px; 
 
    cursor: pointer; 
 
    background-color: green; 
 
    border: 1px solid black; 
 
    border-radius: 5px; 
 
    transition: all 0.5s; 
 
    color: white; 
 
    font-size: 13px; 
 
} 
 
span:hover { 
 
    opacity: 0.8; 
 
} 
 
#some-id { 
 
    text-align: center; 
 
    width: 100%; 
 
    margin: 10px 0; 
 
    font-size: 20px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="some-id">HEY</div> 
 

 
<span class='addObj'>Add Object</span> 
 
<span class='removeObj'>Remove Object</span>

JSFiddle: https://jsfiddle.net/t012rb9j/1/

Старый Ответ:

Как указано в коде:

$('#some-id').click(function() { 

// $('#some-id').attr('title', 'some-title'); //this works 
$('#some-id').data('foo', 'bar1'); //this don't 
}); 

.att r() работает, а .data() не работает. Причина в том, что .attr() добавляет значение атрибута в свой HTML-тег, а данные хранит эти данные в памяти.

С Jquery документации:

.data(): Хранить произвольные данные, связанные с указанным элементом и/или возвращать значение, которое было установлено.

: Получить значение атрибута для первого элемента в наборе соответствующих элементов или установить один или несколько атрибутов для каждого элемента набора.

Одним из способов обнаружения изменений данных (если вы хотите сохранить объект) является объединение обеих функций.

var object = { 
 
    'key': 'value' 
 
}; 
 

 
$('.addObj').click(function() { 
 
    $('#some-id').data('foo', object).attr("data-attached", "true"); 
 
}); 
 

 
$('.removeObj').click(function() { 
 
    $('#some-id').data('foo', null).attr("data-attached", "false"); 
 
}); 
 

 

 
var functionCallBack = function(mutations) { 
 
    mutations.forEach(function(mutation) { 
 
    if (jQuery(mutation.target).attr("data-attached") == "true") { 
 
     // Your code here 
 
     console.log("Object Added"); 
 
    } else { 
 
     console.log("Object removed"); 
 
    } 
 
    }); 
 
} 
 

 
// select the target node 
 
var target = document.getElementById("some-id"); 
 

 
// create an observer instance 
 
var observer = new MutationObserver(functionCallBack); 
 

 
// configuration of the observer: 
 
var config = { 
 
    subtree: true, 
 
    childList: true, 
 
    attributes: true 
 
}; 
 

 
// pass in the target node, as well as the observer options 
 
observer.observe(target, config);
.addObj, .removeObj { 
 
    padding: 10px; 
 
    float: left; 
 
    margin: 5px; 
 
    cursor: pointer; 
 
    background-color: green; 
 
    border: 1px solid black; 
 
    border-radius: 5px; 
 
    transition: all 0.5s; 
 
    color: white; 
 
    font-size: 13px; 
 
} 
 

 
.addObj:hover, .removeObj:hover { 
 
    opacity: 0.8; 
 
} 
 

 
#some-id { 
 
    text-align: center; 
 
    width: 100%; 
 
    margin: 10px 0; 
 
    font-size: 20px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="some-id">HEY</div> 
 

 
<span class='addObj'>Add Object</span> 
 
<span class='removeObj'>Remove Object</span>

JSFiddle: https://jsfiddle.net/9xkb6jv4/

+1

'data' изменяет свойство DOM, а' attr' изменяет атрибут HTML. Это правильные условия. Все как-то хранится в памяти. – Xufox

+1

'attr()' как getter, так и setter – charlietfl

+0

@Xufox, так можно ли это сделать, используя данные jQuery()? – sinisake

1

Если вы хотите, чтобы обнаружить новый набор данных с JQuery-х data, вы всегда можете захватить его.

var functionCallBack; 
 
var $data = jQuery.fn.data; 
 
jQuery.fn.data = function(key, value) { 
 
    var ret = $data.apply(this, arguments); 
 
    if(functionCallBack && this[0] && value !== undefined) { 
 
    functionCallBack(this, key, value); 
 
    } 
 
    return ret; 
 
}; 
 

 
$('#some-id').click(function() { 
 
    $(this).data('foo', 'bar1'); 
 
}).data('foo', 'bar'); 
 
functionCallBack = function(elements, key, value) { 
 
    console.log('something changed') 
 
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="some-id">HEY</div>