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

问题描述 投票:1回答:1

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

背景

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

例如一个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>
javascript jquery json
1个回答
0
投票

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

我们需要做的是,在构造我们的函数映射时,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供您参考。

© www.soinside.com 2019 - 2024. All rights reserved.