从函数对象调用jQuery方法没有效果

时间:2017-12-25 01:00:41

标签: javascript jquery json

TL; DR 谁能告诉我如何从其对象中正确调用jQuery函数?

背景

我尝试使用jQuery方法根据JSON对象提供的描述构建HTML对象。部分原因是尝试将JSON对象定义的一组属性应用于元素 - 非常类似于现有的jQuery attr。不同之处在于它旨在应用某些特殊的“特殊”特征。通过函数调用更智能地使用属性(例如css和innerHTML)。

e.g。一个css属性将通过调用jQuery.css()

来应用

问题

除了对特殊属性的jquery函数的调用之外,一切正常:

   var specialAttrFunctions = {
    'log': console.log,  // works
    'css': $(this).css,  // fails without error
    'html': $(this).html,  // fails without error
    'innerHTML': $(this).html  // fails without error
  };
  specialAttrFunctions['log']('log me'); // works
  specialAttrFunctions['html']('innerHtml sample'); // does not work

我尝试过的事情没有成功

($.fn.html).call(this, 'innerHTML');
($.html).call(this, 'innerHTML');
(this.html)('innerHTML');
($(this).html)('innerHTML');

整件事

我已经附上了整个文件,如果结果是相关的话。



keyIntersection = function(object1, object2) {
  var sharedKeys = [];
  for (var property in object1) {
    if (object1.hasOwnProperty(property) && object2.hasOwnProperty(property)) {
      sharedKeys.push(property);
    }
  }
  return sharedKeys;
};

$.fn.extend({
  setAttrs: function(attributesObject) {
    return this.each(function() {
      var attributesCopy = $.extend(true, {}, attributesObject);
      var specialAttrFunctions = {
        'log': console.log,  // works
        'css': $(this).css,  // fails without error
        'html': $(this).html,  // fails without error
        'innerHTML': $(this).html  // fails without error
      };
      keyIntersection(specialAttrFunctions, attributesCopy).forEach(function(key) {
        specialAttrFunctions[key](attributesCopy[key]);
        delete attributesCopy[key];
      });
      $(this).attr(attributesCopy);
    });
  }
});

var createDomObjectFromJson = function(domObjectJson, $parentElement) {
  var $element = $(document.createElement(domObjectJson.type));
  $element.setAttrs(domObjectJson.attributes || {});
  (domObjectJson.children || []).forEach(function(child) {
    $element.append(createDomObjectFromJson(child));
  });
  if ($parentElement) {
    $parentElement.append($element);
  }
  return $element;
};

$(document).ready(function() {
  var testData = {
    'type': 'div',
    'attributes': {
      'log': 'The log function call works correctly',
      'data-test': 'test1',
      'css': {
        'width': '640px',
        'height': '480px',
        'background-color': 'lightblue',
        'border': '1px solid black'
      }
    },
    'children': [{
      'type': 'p',
      'attributes': {
        'data': 'test2',
        'innerHTML': 'Hello Paragraph!',
        'title': 'paragraph title'
      }
    }]
  };
  createDomObjectFromJson(testData, $('body'));
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

调用函数时,您的问题与this上下文有关。当您调用specialAttrFunctions[key](attributesCopy[key]);时,调用函数中的this上下文是specialAttrFunctions对象,而不是jQuery包装的元素对象,它必须是jQuery原型方法才能工作。< / p>

我们需要做的是,在构造函数映射specialAttrFunctions时,确保将jQuery原型方法绑定到正确的上下文。为了提高效率,我首先将jQuery包装的元素缓存在一个变量中,然后将bind该变量缓存到相应的函数中。最终结果如下所示:

var $el = $(this);
var specialAttrFunctions = {
    'log': console.log,
    'css': $.fn.css.bind($el),
    'html': $.fn.html.bind($el),
    'innerHTML': $.fn.html.bind($el)
};

我创建了一个fiddle供您参考。