two-way-data-binding
two-way-data-binding copied to clipboard
如果标签有嵌套,你这个好像只能识别最外层标签
如果把compile做一下递归,就可以了
function compile (node, vm) {
var reg = /\{\{(.*)\}\}/;
//这里加一个递归
if(node.childNodes && node.childNodes.length>0){
for(var i=0,len =node.childNodes.length;i<len;i++ ){
compile(node.childNodes[i],vm);
}
}
// 节点类型为元素
if (node.nodeType === 1) {
var attr = node.attributes;
// 解析属性
for (var i = 0; i < attr.length; i++) {
if (attr[i].nodeName == 'v-model') {
var name = attr[i].nodeValue; // 获取v-model绑定的属性名
node.addEventListener('keyup', function (e) {
// 给相应的data属性赋值,进而触发该属性的set方法
vm[name] = e.target.value;
});
node.value = vm[name]; // 将data的值赋给该node
node.removeAttribute('v-model');
}
};
new Watcher(vm, node, name, 'input');
}
// 节点类型为text
if (node.nodeType === 3) {
if (reg.test(node.nodeValue)) {
var name = RegExp.$1; // 获取匹配到的字符串
name = name.trim();
new Watcher(vm, node, name, 'text');
}
}
}
没错,这个功能是不完整的。主要是为了向初学者把原理解释清楚,所以尽可能的简化了不必要的功能,否则那篇博客不可能有如此的传播量。
` function nodeToFragment (node, vm) { var flag = document.createDocumentFragment(); var child;
while (child = node.firstChild) { //这句话没有看懂啊 while 里面为什么可以使一个等于号
compile(child, vm);
flag.appendChild(child); // 将子节点劫持到文档片段中
}
return flag;
}`
只要是表达式一定会返回一个值,赋值表达式返回的值就是所赋的值
没有听懂你的意思 var i=2; while(i=3){ alert(1111) } 这个是一个死循环
正常情况下while(这个里面不应该是 > < 或者==)吗 ? 所以你的这段代码我没有看明白 while (child = node.firstChild) { //这句话没有看懂啊 while 里面为什么可以使一个等于号 compile(child, vm); flag.appendChild(child); // 将子节点劫持到文档片段中 } return flag; }`
while (i = 3) {} 就相当于 while (3) {} 也就相当于 while (true) {} "表达式 expression 一定会返回一个值",“真值/假值 truthy/falsy 转换”,搞清楚这两点,就明白这种“非正常”用法了
while (child = node.firstChild) { // //child = node.firstChild 没有起到判断的效果啊 不如直接写成true 或者false好了 这里我没有看懂 compile(child, vm); flag.appendChild(child); // 将子节点劫持到文档片段中 } return flag; }`
你需要摒弃 while 后面的括号中必须是一个“比较(判断)表达式“的观念,括号中只需要得到真值或假值 while 语句即可运行。得到真值和假值的途径并非只有用“>, <, ==”这些东西
那child = node.firstChild 这句话是什么意思想干嘛?
上面的写法其实是下面这种写法的一种简化版:
var child = node.firstChild;
while (child !== null) {
flag.appendChild(child); // firstChild 被劫持了,相当于从 DOM 中删除了
child = node.firstChild; // 这时的 firstChild 其实已经是“下一个”子节点了
console.log(child); // 你可以试试看打印出啥
}
var child = node.firstChild; while (child !== null) { flag.appendChild(child); // firstChild 被劫持了,相当于从 DOM 中删除了 child = node.firstChild; // 这时的 firstChild 其实已经是“下一个”子节点了 console.log(child); // 你可以试试看打印出啥 } 为啥我感觉没必要写这个判断 就算是空格也是文本节点 node.firstChild不存在为null这种情况啊?
flag.appendChild(child); // firstChild 被劫持了,相当于从 DOM 中删除了 # 这句话的劫持怎么理解的?为什么说相当于从DOM中删除了?
// 此处判断条件为什么是 " node.firstChild 的值赋值给 child " ? // 答: (js高程-10.1.1) 在 DOM 中每个节点都有一个 childNodes 属性,其中保存着一个 NodeList 对象, // NodeList 对象会随着 DOM 结构的变化动态更新,如果保存在 NodeList 中的节点为0,再次访问 node.firstChild // 浏览器会返回一个 null。在 while 语句内部找到当前节点的第一个子节点推入到文档对象模型中,此时浏览器动态把 // 第二个子节点变更为第一个, 这样循环直到 node.firstChild = null 退出循环
判断条件是不是这样理解的?