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>
最佳答案
您的问题与调用函数时的 this
上下文有关。当您调用 specialAttrFunctions[key](attributesCopy[key]);
时,调用函数中的 this
上下文是 specialAttrFunctions
对象而不是 jQuery - 包装的元素对象,它必须是为了使 jQuery 原型(prototype)方法能够工作。
我们需要做的是,在构建函数映射时,specialAttrFunctions
,确保将 jQuery 原型(prototype)方法绑定(bind)到正确的上下文。为了提高效率,我首先将 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供您引用。
关于javascript - 从函数对象调用 jQuery 方法没有效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47964992/