【问题标题】:Can mutation observer listen for changes in "data-" attributes?突变观察者可以监听“数据”属性的变化吗?
【发布时间】:2017-01-08 22:41:54
【问题描述】:

所以问题是我有一个 html 元素,它在“data-”属性中有一个对象(通过 jQuery ofc 设置),我想听听该属性的变化。

我已经尝试了很多东西,比如在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>

【问题讨论】:

  • 请显示您所尝试的具体内容。当然可以用MutationObserver监听data-的属性变化。
  • "set via jQuery" ...如果它是使用data() 方法设置的,它将不是一个属性。如果您需要帮助,请显示所有相关代码
  • @Xufox 我添加了一个 jsfiddle。
  • @charlietfl 我添加了一个 jsfiddle。那我该如何解决呢?最好的选择是什么?
  • 使用这个:jsfiddle.net/u5Lcfayf/2 使用 data() 方法时,您设置的数据存储在一个随机命名的 (?) jQuery 对象中,MutationObserver 无法访问该对象(似乎)。

标签: javascript jquery dom mutation-observers


【解决方案1】:

新答案(基于Oriol's Answer):

我认为 Oriol 提供了更好的方法,但可以进一步优化。

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
});

.attr() 工作,而 .data() 不工作。原因是 .attr() 添加 an 属性值到您的 HTML 标记,而 data 存储 此数据在内存中。

来自 jQuery 文档:

.data():存储与指定元素关联的任意数据和/或返回设置的值。

.attr():获取匹配元素集中第一个元素的属性值,或者为每个元素设置一个或多个属性 匹配的元素。

检测数据变化的一种方法(如果你想存储一个对象)是结合这两个函数。

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/

【讨论】:

  • data 修改 DOM 属性,而 attr 修改 HTML 属性。这些是正确的术语。一切都以某种方式存储在内存中。
  • attr() 既是 getter 也是 setter
  • @Xufox,那么是否可以使用 jQuery data() 来做到这一点?
  • @sinisake 我不确定我的评论会如何。 attr 是可能的。
  • @Xufox,我认为data 不会向 DOM 中添加任何内容,甚至不会向其属性添加任何内容。它存储 DOM 对象的引用以及保存的数据,但我认为它根本不附加到 DOM 对象。这只是内部的。
【解决方案2】:

如果你想用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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2021-05-15
    • 1970-01-01
    • 2011-05-27
    • 2012-01-19
    相关资源
    最近更新 更多