天道酬勤,学无止境

从DOM中删除并再次插入后如何更新聚合物元素绑定(How to update polymer element bindings after it was removed from DOM and inserted again)

问题

假设我们有容器聚合物元素和另一个虚拟聚合物元素。 容器聚合物元素具有用于插入另一种聚合物的 div 块。

container_polymer.html

<polymer-element name='container-polymer'>
  <template>
    <div id="container">
    </div>
    <button on-click="{{first}}">show first</button>
    <button on-click="{{firstPrepared}}">show first prepared</button>
    <button on-click="{{second}}">show second</button>
  </template>
  <script type="application/dart" src="container_polymer.dart">
  </script>
</polymer-element>

插入虚拟聚合物有三个按钮:

  1. 第一个按钮将第一个虚拟聚合物插入容器。
  2. 第二个按钮也插入第一个虚拟聚合物,并在该聚合物上调用prepareElement()
  3. 第三个按钮将第二个虚拟聚合物插入容器

container_polymer.dart

import 'package:polymer/polymer.dart';
import 'dart:html';
import 'dummy_polymer.dart';

@CustomTag('container-polymer')
class ContainerPolymer extends PolymerElement {
  PolymerElement firstPolymer, secondPolymer, currentPolymer;
  Element container;

  ContainerPolymer.created() : super.created();

  void enteredView() {
    super.enteredView();
    container = $['container'];
  }

  void first(Event e, var detail, Node target) {
    showFirst(false);
  }

  void firstPrepared(Event e, var detail, Node target) {
    showFirst(true);
  }

  void showFirst(bool prepare) {
    if (firstPolymer == null) {
      DummyPolymer dummyPolymer = new Element.tag("dummy-polymer");
      dummyPolymer.title = "first";
      firstPolymer = dummyPolymer;
    }

    if (currentPolymer != firstPolymer) {
      if (secondPolymer != null) {
        secondPolymer.remove();
      }

      if (prepare) {
        firstPolymer.prepareElement();  
      }
      currentPolymer = firstPolymer;
      container.children.add(firstPolymer); 
    }
  }

  void second(Event e, var detail, Node target){
    if (currentPolymer != secondPolymer) {
      DummyPolymer dummyPolymer = new Element.tag("dummy-polymer");
      dummyPolymer.title = "second";
      secondPolymer = dummyPolymer;
      if (firstPolymer != null) {
        firstPolymer.remove();
      }

      currentPolymer = secondPolymer;
      container.children.add(secondPolymer);
    }
  }

}

虚拟聚合物具有几个可观察的特性,以测试结合效果。 当您在此聚合物内部单击时,它会更改根 div 的背景颜色、标题 div 的背景颜色并增加计数器。 它还有用于检测聚合物元素状态是否发生变化的输入,以及用于测试父样式使用情况的白色背景块。

dummy_polymer.html

<polymer-element name='dummy-polymer'>
  <template>
    <div style="width: 500px; height: 300px; background-color: {{color}}" on-click="{{changeColor}}">
      <div id="title">
        <h1>{{title}}</h1>
        <span>Clicks: {{clicks}}</span>
      </div>
      <input type="text" />
      <div class="external">Parent style block: background should be white</div>
    </div>

  </template>

  <script type="application/dart" src="dummy_polymer.dart">
  </script>

</polymer-element>

dummy_polymer.dart

import 'package:polymer/polymer.dart';
import 'dart:html';

@CustomTag('dummy-polymer')
class DummyPolymer extends PolymerElement {
  @observable String color = "red";
  @observable String title;
  @observable num clicks = 0;
  Element titleElement;

  DummyPolymer.created() : super.created() {
    var root = getShadowRoot('dummy-polymer');
    root.applyAuthorStyles = true;
  }

  void enteredView() {
    super.enteredView();
    titleElement = $['title'];
  }

  void changeColor(Event e, var detail, Node target){
    clicks++;

    if (color == "red") {
      color = "green";
    } 
    else if (color == "green") {
      color = "blue";
    }
    else {
      color = "red";
    }
    titleElement.style.backgroundColor = color;
  }

}

此处托管的测试页面 http://dart-style-binding-test.herokuapp.com/

因此,要重现我的问题,请执行以下操作:

  1. 单击“首先显示”按钮。 确保单击内部会更改背景颜色并增加计数器。
  2. 在输入字段中输入内容
  3. 点击“显示第二个”
  4. 点击“先显示”。 确保第一个聚合物具有与以前相同的状态:背景颜色、计数器和输入字段文本。
  5. 在第一个聚合物内部单击。 现在它不会改变背景颜色和计数器,但它会改变顶部区域的背景颜色。

绑定到可观察属性不再起作用。 但是on-click处理程序有效,您可以在顶部区域的背景颜色更改时看到它。 它是通过直接更改元素的backgroundColor属性来实现的:

titleElement.style.backgroundColor = color;

所以,我的问题是:如何在现有聚合物再次插入 DOM 后正确更新绑定机制?

有一种方法可以使用“显示第一个准备好的”按钮来做脏事。 它在插入容器之前在第一个元素上调用prepareElement() 。 因此,请执行以下操作:

  1. 单击“首先显示”按钮。 确保单击内部会更改背景颜色并增加计数器。
  2. 在输入字段中输入内容
  3. 点击“显示第二个”
  4. 单击“显示第一个准备好的”。 您可以看到输入元素为空,但计数器和背景颜色是最新的。 (如果您在 dartium 中运行此演示,则白色块也会将其背景颜色更改为父级,因为未应用父级样式)
  5. 在第一个聚合物内部单击。 现在它改变了背景颜色和计数器。 绑定正常工作,但我们在输入字段中丢失了文本。

注意:在使用“先显示准备好的”按钮插入第一个元素后,即使在使用“先显示”按钮插入第一个元素后,绑定也能正常工作。

代码在这里 https://github.com/petalvlad/dart-style-binding-test

回答1

我自己没有尝试过,但似乎合理。 我希望作者在重用元素时不介意从 Detached observables 中处理他的答案。

查看了polymer.js 信息位后,我发现有一个cancelUnbindAll 函数,必须在创建元素或将preventDispose 属性设置为true 时调用该函数。

对于可能需要执行相同操作的任何人,在 Dart 实现中,您必须在 super 调用后在分离函数中调用 cancelUnbindAll,如下所示:

void detached()
{
    super.detached();
    this.cancelUnbindAll(preventCascade: true);
}

或者,您可以简单地覆盖自定义元素中的 preventDispose 属性:

bool get preventDispose => true;

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何找到某些事件正在运行的Javascript?(How do I find what Javascript is running on certain events?)
    问题 在本示例中,我将选择Chrome,但是我可以使用任何浏览器的解决方案。 用例:我的网站上有一个更新按钮,用于更新购物车中的物品数量。 我想允许用户输入0并单击“更新”以删除该项目。 麻烦的是,某些js函数中有一些侦听器拒绝输入0并单击更新(单击更新后仍保留旧数量)的功能。 我的问题是,在该事件期间我可以使用哪种开发者工具查找正在运行的js函数? 我不认为Chrome的检查器可以做到这一点,而且我对Firebug不太熟悉,但是我也找不到那里的功能。 我觉得我应该像检查CSS样式一样能够检查js触发。 有人知道我可以使用的工具吗? 回答1 在我的工作中,我不得不调试一些特别讨厌的,看不见的Javascript问题。 了解诸如Chrome之类的开发人员工具的全部深度绝对是有帮助的。 不可否认的是,要找到可能导致问题的地方需要一些创造力,但有一些技巧: 跟踪事件监听器 在Chrome的“元素”视图下,尝试检查元素(右键单击,检查);然后单击“确定”。 然后,在开发人员视图的右侧,向下滚动到“事件侦听器”。 在这里,您可以查看哪些代码文件关联了事件。 通常,这只会使您从正在寻找的真正曲折的代码中指向中间框架,但有时它将为您指明正确的方向。 陷阱DOM修改 我看到的许多不良影响是由于某些内容更改了我不想要的页面上的某些值或属性。 每当发生这种情况时,您都可以右键单击该元素
  • 如何清除/删除Knockout.js中的可观察绑定?(How to clear/remove observable bindings in Knockout.js?)
    问题 我正在将功能构建到用户可以执行多次的网页上。 通过用户的操作,使用ko.applyBindings()创建对象/模型并将其应用于HTML。 数据绑定的HTML是通过jQuery模板创建的。 到目前为止,一切都很好。 当我通过创建第二个对象/模型重复此步骤并调用ko.applyBindings()时,遇到两个问题: 标记显示先前的对象/模型以及新的对象/模型。 尽管对象/模型中的属性之一仍在标记中呈现,但仍发生了JavaScript错误。 为了解决这个问题,在第一遍之后,我调用jQuery的.empty()来删除包含所有数据绑定属性的模板化HTML,以使其不再存在于DOM中。 当用户启动第二遍的过程时,将数据绑定的HTML重新添加到DOM。 但是就像我说的那样,当HTML重新添加到DOM并重新绑定到新的对象/模型时,它仍然包含来自第一个对象/模型的数据,并且我仍然遇到未发生的JS错误。在第一遍。 结论似乎是,即使从DOM中删除了标记,淘汰赛仍保留了这些绑定属性。 因此,我正在寻找一种从淘汰赛中删除这些绑定属性的方法。 告诉淘汰赛,不再有可观察的模型。 有没有办法做到这一点? 编辑 基本过程是用户上传文件。 然后服务器使用JSON对象进行响应,将数据绑定的HTML添加到DOM中,然后使用 mn.AccountCreationModel = new AccountViewModel
  • DOM节点上的事件处理程序是否随该节点一起删除?(Do events handlers on a DOM node get deleted with the node?)
    问题 (注意:我在下面使用jQuery,但问题实际上是一个通用的Javascript。) 假设我有一个div#formsection其内容使用AJAX反复更新,如下所示: var formSection = $('div#formsection'); var newContents = $.get(/* URL for next section */); formSection.html(newContents); 每当我更新此div时,我都会触发一个自定义事件,该事件将事件处理程序绑定到一些新添加的元素,如下所示: // When the first section of the form is loaded, this runs... formSection.find('select#phonenumber').change(function(){/* stuff */}); ... // ... when the second section of the form is loaded, this runs... formSection.find('input#foo').focus(function(){/* stuff */}); 因此:我将事件处理程序绑定到某些DOM节点,然后再删除那些DOM节点并插入新的DOM(通过html()这样做)
  • 理解VUE双向数据绑定原理和实现
    一、原理:1.vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;2.核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法;3.介绍一下Object.defineProperty()方法 (1)Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数,分别为 obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法) (2)简单地说,就是用这个方法来定义一个值。当调用时我们使用了它里面的get方法,当我们给这个属性赋值时,又用到了它里面的set方法;set,get方法初步了解二、先简单的实现一个js的双向数据绑定来熟悉一下这个方法: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document<
  • 什么是Ember RunLoop,它如何工作?(What is Ember RunLoop and how does it work?)
    问题 我正在尝试了解Ember RunLoop的工作原理以及使它滴答作响的原因。 我看过文档,但是仍然有很多疑问。 我有兴趣更好地了解RunLoop的工作原理,以便在以后不得不推迟执行某些代码的情况下,可以在其名称空间中选择适当的方法。 Ember RunLoop何时启动。 它依赖于路由器,视图或控制器还是其他? 大概需要多长时间(我知道这很愚蠢,并且要取决于很多事情,但是我正在寻找一个总体思路,或者是否可能需要最小或最大的运行循环时间) RunLoop是否一直在执行,还是只是指示从开始执行到结束执行的时间,可能不会运行一段时间。 如果从一个RunLoop内创建视图,是否可以保证在循环结束时所有视图的内容都将进入DOM? 如果这些是非常基本的问题,请原谅我,我认为了解这些内容将有助于像我这样的菜鸟更好地使用Ember。 回答1 2013年10月9日更新:查看运行循环的这种交互式可视化效果:https: //machty.s3.amazonaws.com/ember-run-loop-visual/index.html 2013年5月9日更新:下面的所有基本概念仍然是最新的,但是截至提交时,Ember Run Loop实现已拆分为一个单独的库,名为backburner.js,两者之间的API差别很小。 首先,请阅读以下内容: http://blog.sproutcore.com
  • vue2.x入坑总结—回顾对比angularJS/React
    从感性的角度讲,我是不屑于用VUE,觉得react套件用起来更顺手,但是vue现在越来火,所以也不得入vue(杂烩汤)的坑。vue/anguarJS/React,三者对关系现在就是:https://www.zhoulujun.cn/uploadfile/images/2018/0626/20180626214906428779269.jpg自己ps了下,觉得深有道理,骚年们自己体悟,然后再问军哥^_^不过回归真题,看vue还是先了解下https://cdn.zhoulujun.cn/vue.jpg(太大,自己打开)vue生命周期及相关主题组件实例周期vue所有功能的实现都是围绕其生命周期进行的,在生命周期的不同阶段调用对应的钩子函数可以实现组件数据管理和DOM渲染两大重要功能。学习实例的生命周期,能帮助我们理解vue实例的运行机制,更好地利用钩子函数完成我们的业务代码。create 和 mounted 相关 的函数有:beforecreated》created》beforeMount》mounted》beforeDestroybeforecreated:el 和 data 并未初始化, 案例:可以在这加个loading事件 及获取路由参数,但是this.(data|computed|methods)参数均为undefind(无法访问到 el 属性和 data 属性等
  • angularjs中的compile和link函数有什么区别(What is the difference between compile and link function in angularjs)
    问题 有人可以用简单的方式解释吗? 该文档似乎有点钝。 我没有掌握何时使用另一种方法的本质和全局。 对比两者的示例将是很棒的。 回答1 编译功能-用于模板DOM操纵(即,tElement =模板元素的操纵),因此适用于与指令关联的模板的所有DOM克隆的操纵。 链接功能-用于注册DOM侦听器(即实例范围内的$ watch表达式)以及实例DOM操作(即iElement =单个实例元素的操作)。 克隆模板后执行。 例如,在<li ng-repeat ...>内部,已为特定的<li>元素克隆了<li>模板(tElement)(将其插入到iElement中)之后,将执行链接功能。 $ watch()允许指令通知实例范围属性更改(实例范围与每个实例相关联),这允许指令将更新后的实例值呈现给DOM-通过将内容从实例范围复制到DOM。 请注意,可以在编译功能和/或链接功能中完成DOM转换。 大多数指令仅需要链接函数,因为大多数指令仅处理特定的DOM元素实例(及其实例范围)。 帮助确定使用哪个方法的一种方法:考虑编译函数没有接收scope参数。 (我故意忽略了transclude链接函数参数,该参数接收到一个transcluded范围-很少使用。)因此,compile函数无法执行需要(实例)范围的任何操作-您可以$不会监视任何模型/实例作用域属性,您不能使用实例作用域信息来操作DOM
  • Polymer元素和AngularJS指令之间有什么区别?(What is the difference between Polymer elements and AngularJS directives?)
    问题 在“聚合物入门”页面上,我们看到了一个正在使用的聚合物示例: <html> <head> <!-- 1. Shim missing platform features --> <script src="polymer-all/platform/platform.js"></script> <!-- 2. Load a component --> <link rel="import" href="x-foo.html"> </head> <body> <!-- 3. Declare the component by its tag. --> <x-foo></x-foo> </body> </html> 您会注意到, <x-foo></x-foo>由platform.js和x-foo.html定义。 似乎这等效于AngularJS中的指令模块: angular.module('xfoo', []) .controller('X-Foo', ['$scope',function($scope) { $scope.text = 'hey hey!'; }) .directive('x-foo', function() { return { restrict: 'EA', replace: true, controller: 'X-Foo', templateUrl: '/views
  • 在Meteor.js中更新DOM之后的回调(Callback after the DOM was updated in Meteor.js)
    问题 我有这个流星项目:https://github.com/jfahrenkrug/code_buddy 基本上,这是一个具有大文本区域和前置区域的工具,可让您输入源代码片段,这些片段将自动推送到所有连接的客户端。 我想在代码更改后自动运行highlightSyntax函数,但实际上并没有用。 我已经尝试使用query.observe,但是效果不是很好:语法高亮显示一次,然后再次消失。 所以我的问题是:DOM更新后如何运行代码? 回答1 一种骇人听闻的方法是: foo.html <template name="mytemplate"> <div id="my-magic-div"> .. stuff goes here .. {{add_my_special_behavior}} </div> </template> foo.js Template.mytemplate.add_my_special_behavior = function () { Meteor.defer(function () { // find #my-magic-div in the DOM // do stuff to it }); // return nothing }; 每当渲染(或重新渲染)模板时,都会调用该函数,因此您可以将其用作执行任何特殊DOM操作所需的钩子。 您需要使用Meteor
  • 虚拟DOM 之 Snabbdom 二、源码解析(h函数,虚拟DOM对比,Diff算法)
    Snabbdom 源码解析 核心源码解析 如何学习源码 先宏观了解:学习库的核心执行过程带着目标看源码,比如: VNode是如何创建的VNode是如何渲染成真实DOM的 看源码的过程要不求甚解 看源码的过程要围绕核心目标因为一个开源项目的功能会非常的多,代码分支逻辑会非常的多,分支会干扰看源码要先把主线逻辑走通,涉及分支的部分可以先不看这样可以提高源码的阅读速度 调试 一旦主线逻辑走通,可以写一个小Demo,对代码进行调试,加深理解 参考资料 在看源码之前,可以看别人写的文章,帮助更好理解,以提升源码阅读效率 vscode看源码快捷键 右键-转到定义:快速跳转到定义 或 导入变量的位置 当定义在当前文件中,会跳转到定义的位置当定义不在当前文件中,会弹出展示定义的小窗口 窗口顶部是定义所在的文件,点击可以快速跳转 当操作时鼠标/光标就是定义 或 导入的位置,同样会弹出定义的小窗口 Ctrl + 鼠标左键:效果同【转到定义】F12:效果同【转到定义】Alt + 左右方向键:在跳转历史中前进后退 可用于查看完定义后,快速回到之前的位置 Snabbdom 的核心 使用h()函数创建 Javascript 对象(VNode) 描述真实DOMinit() 设置模块,创建patch()patch()根据diff算法比较新旧两个VNode把变化的内容更新到真实 DOM 树上 Diff 算法
  • 化身面试官出30+Vue面试题,超级干货(附答案)
    之前一直没有总结Vue相关的知识,看了挺多别人总结的,其实也能快速知道一些,但是遇到真正的面试,发现自己的知识都还是是碎片化的,觉得不行,得总结一下了。 不知道大伙是不是已经在准备春招面试了呢,准备得咋样了呢,面试的Vue复习得怎么样了呢? 如果你感觉在vue这方面还比较薄弱的话,不如来做一做这套模拟面试吧,看看大伙能不能打个满分,祝你顺利,答案仅供参考 欢迎访问GitHub(私聊找我拿链接)仓库,目前已经有 552 道大厂真题了,涵盖各类Android的真题 ------ 进入正题化身为面试官 ------ 电话拨通中,咳咳喂,听得到吗,听得到是吧,那面试开始了,你先做个自我介绍吧 。。。 在你自我介绍的时候呢,我就看看你做过的项目,技术栈什么的。 第一个问题,先摸个底: 了解过(用过)react或者angular吗,他们有什么区别? 答案 Vue 借鉴了 angular 的模板和数据绑定技术,又借鉴了 react 的组件化和虚拟 DOM 技术。 对 Vue 比较熟一些是吧~(这里只说 Vue 假设你就只熟练 Vue ) 那首先谈谈你对Vue的理解吧? 答案 官网介绍: cn.vuejs.org/index.html 关键点: 渐进式 JavaScript 框架、核心库加插件、动态创建用户界面(异步获取后台数据,数据展示在界面) 特点: MVVM 模式;代码简洁体积小,运行效率高
  • 前端面试题JS-H5-VUE
    前端面试题 总结 H5:Video.js、PDF.js 、canvas、localStorage、sessionStorage、localStorage跨页面通信、manifest、拖放 CSS3:哪些样式可继承,行内元素,非行内元素,动画等 DOM:节流,重排重绘,防抖 http协议:302、304、304的解决方法、403、404、500、 继承、原型链、数组API,字符串API、Object.difineProperty UI设计图进行还原:像素还原,比例还原 不同屏幕适配:媒体查询:print、screen、speech、min-width 原型链原理 构造函数的原型分配的函数是所有对象共享的。 原型是什么:一个对象,我们也称prototype为原型对象 原型的作用:共享方法 对象原型 ——proto—— 对象都有一个属性——proto——,指向它的构造函数的prototype ——proto——对象原型和原型对象prototype是等价的 原型链 js的成员查找机制 ​ 1 当访问一个对象的属性和方法的时,首先查找这个对象自身有没有该属性 ​ 2 如果没有就查找它的原型(——proto——指向prototype) ​ 3 如果还没有,就去找prototype的原型(object的原型对象) ​ 4 一直查找到Object为止(null) JS中new和Object
  • AngularJS:AngularJS渲染模板后如何运行其他代码?(AngularJS: How to run additional code after AngularJS has rendered a template?)
    问题 我在DOM中有一个Angular模板。 当我的控制器从服务中获取新数据时,它将更新$ scope中的模型,然后重新呈现模板。 到目前为止一切都很好。 问题是,在模板已重新呈现并且在DOM中(在本例中为jQuery插件)之后,我还需要做一些额外的工作。 似乎应该有一个事件要听,例如AfterRender,但我找不到任何此类事件。 也许一条指令是一个可行的方法,但是它似乎还为时过早。 这是一个概述我的问题的jsFiddle:Fiddle-AngularIssue ==更新== 基于有用的评论,我相应地切换到了处理DOM操作的指令,并在指令内部实现了$ watch模型。 但是,我仍然遇到相同的基本问题。 $ watch事件内部的代码在模板被编译并插入DOM之前触发,因此,jQuery插件始终在评估一个空表。 有趣的是,如果我删除了异步调用,那么整个程序就可以正常工作,因此这是朝着正确方向迈出的一步。 这是我更新的小提琴,以反映这些更改:http://jsfiddle.net/uNREn/12/ 回答1 这篇文章很旧,但是我将您的代码更改为: scope.$watch("assignments", function (value) {//I change here var val = value || null; if (val) element.dataTable({
  • 2021 前端工程师 面试题总汇
    HTTP、网络、浏览器 HTTP和HTTPS的区别? HTTPS需要CA申请书,很少有免费的,需要交费HTTP运行在TCP之上,所有传输都是明文,而HTTPS是运行在SSL/TLS之上,而SSL/TLS是运行在TCP之上,所有传输内容都是经过加密的HTTPS有效的防止了运营商的劫持HTTP用的端口是80,HTTPS运行的端口是443HTTPS是非对称加密 HTTP1.0、HTTP1.X 与HTTP2.0的区别? 1996年 1999年 2015年 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小
  • 如果删除DOM元素,以该元素开头的事件是否会继续冒泡?(If you delete a DOM element, do any events that started with that element continue to bubble?)
    问题 如果我删除了用于启动事件气泡的DOM元素,或者删除了它的孩子启动事件气泡的DOM元素,则该期望什么行为?如果删除了该元素,它会继续气泡吗? 例如-假设您有一个表格,并且想要检测表格单元格上的点击事件。 另一段JS执行了一个AJAX请求,一旦请求完成,该请求最终将完全替换该表。 如果我单击表格,并且在表格被成功完成AJAX请求替换后立即发生了什么? 我问是因为我看到了一些点击事件似乎没有冒泡的行为,但是很难复制。 我正在表的父元素上观看事件(而不是将事件附加到每个TD),而且有时似乎没有达到它。 编辑:再次遇到此问题,并最终找到它的根源。 根本不是一个冒泡事件! 请参阅下面的详细信息。 回答1 根据经验:这取决于您使用的浏览器;具体取决于您所使用的浏览器。 IE取消了该事件,其他所有事件(据我所知)仍在继续。 请参阅下面的测试页和讨论。 从理论上讲: Andy E的负责人发现DOM2表示事件应继续进行,因为冒泡应基于树的初始状态。 因此,大多数人的行为是正确的,IE在这里是独立存在的。 让奎尔感到惊讶。 但是:那是否与您所看到的有关确实是另一个问题。 您正在观察对表的父元素的单击,而您怀疑的是很少有,当您单击表时,会出现带有Ajax补全的竞争条件,该条件会替换表并导致点击丢失。 Java解释器中不存在这种竞争条件,因为目前,浏览器上的Javascript是单线程的。 (但是
  • vue自学笔记
    <div id="app"> {{ message }} </div> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) 处理用户输入: <div id="app-5"> <p>{{ message }}</p> <button v-on:click="reverseMessage">反转消息</button> </div> var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } }) 根实例 └─ TodoList ├─ TodoItem │ ├─ DeleteTodoButton │ └─ EditTodoButton └─ TodoListFooter ├─ ClearTodosButton └─ TodoListStatistics 生命周期 #beforeCreate 在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用。 #created
  • vue高频面试题
    1.为什么要选vue?与其它框架对比的优势和劣势? (1)vue: 优点: 1.双向数据绑定 2.组件化开发 3.采用virtual DOM 4.轻量高效 5.动画系统 Virtual DOM则是虚拟DOM的英文,简单来说,他就是一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM。最后在计算完毕才真正将DOM操作提交,将DOM操作变化反映到DOM树上。 缺点: 1.不支持IE8及以下版本 2.生态不太成熟,例如编辑器中的语法提示不太完善 3.社区无法与angular和react相比 (2)0angular: 相同点: 1.都支持指令,内置指令和自定义指令 2.都支持过滤器,内置过滤器和自定义过滤器 3.都支持双向数据绑定, 4.都不支持低端浏览器 不同点: 1.Angular的学习成本较高,二vue.js本提供的api就比较简单.直观 2.从性能上来说: AngularJS依赖对数据做脏检查.Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。 (3)react: 相同点: 1.react采用特殊的jsx语法,vue进行组件化编写,采用.vue特殊文件格式,两者都需用编译后使用. 2.中心思想相同:都是组件化开发,组件实例之间可进行嵌套 3
  • 学习vue实现双向绑定【附源码下载地址】
    学习vue实现双向绑定【附源码下载地址】 嘉宝 web前端开发 问题:我怎么才能收到你们公众号平台的推送文章呢?答案:只需要点击标题下面的蓝色字【web前端开发】关注即可。 写在前面 几乎是所有人都知道 Vue 是一个双向绑定的前端框架,但只有部分人知道实现 Vue-1 (下文中的Vue 均为Vue1 )是利用 defineProperty 来实现双向绑定的。 再次但是,只有部分的部分人,才知道 Vue 到底是如何利用 defineProperty 实现双向绑定的。 本文会带有一点解释,并用简单的例子实现一个 defineProperty 双向绑定。本文中可能会使用【可疑】这个字眼,代表这个函数很值得关注,别无他意。 先看看 Vue 是在哪里使用了defineProperty? 在源码中,发现了一个这样的函数,def()。这个函数里面包裹着我们最重要的api -- defineProperty。 /** * Define a property. * * @param {Object} obj * @param {String} key * @param {*} val * @param {Boolean} [enumerable] */function def(obj, key, val, enumerable) { Object.defineProperty(obj, key,
  • 如果我有jQuery背景,那么“ AngularJS中的思考”吗? [关闭](“Thinking in AngularJS” if I have a jQuery background? [closed])
    问题 关门了。 这个问题需要更加集中。 它当前不接受答案。 5年前关闭。 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 假设我熟悉用jQuery开发客户端应用程序,但是现在我想开始使用AngularJS。 您能描述必要的范式转换吗? 以下是一些可以帮助您确定答案的问题: 我如何以不同的方式设计和设计客户端Web应用程序? 最大的区别是什么? 我应该停止做什么/使用; 我应该开始做什么/使用呢? 是否有服务器端注意事项/限制? 我不是要在jQuery和AngularJS之间进行详细的比较。 回答1 1.不要设计您的页面,然后通过DOM操作对其进行更改 在jQuery中,您可以设计一个页面,然后将其动态化。 这是因为jQuery是为增强而设计的,并且在此简单前提下得到了不可思议的发展。 但是在AngularJS中,您必须从头开始,牢记架构。 您不必从“我拥有DOM的这个部分,但我想使其成为X”开始,而是必须从要完成的事情开始,然后开始设计应用程序,然后最后开始设计视图。 2.不要用AngularJS扩充jQuery 同样,不要以jQuery做X,Y和Z的想法开始,所以我只在模型和控制器的基础上添加AngularJS。 当您刚开始时,这确实很诱人,这就是为什么我总是建议新的AngularJS开发人员根本不使用jQuery
  • 如何在没有内存泄漏的情况下删除DOM元素?(How to remove DOM elements without memory leaks?)
    问题 我的JavaSript代码构建了一个LI元素列表。 当我更新列表时,内存使用量会增加并且永远不会减少。 我在sIEve中进行了测试,结果表明浏览器保留了所有应该由$.remove()或$.empty jQuery命令删除的元素。 我该怎么做才能在没有内存泄漏的情况下删除DOM节点? 有关具体代码,请参见我的其他问题。 回答1 DOM会保留所有DOM节点,即使已将它们从DOM树本身中删除,删除这些节点的唯一方法是进行页面刷新(如果将列表放入iframe中,刷新将不会那么明显) 否则,您可以等待问题变得严重到足以迫使浏览器垃圾收集器执行操作(在此处谈论数百兆未使用的节点) 最佳实践是重用节点。 编辑:试试这个: var garbageBin; window.onload = function () { if (typeof(garbageBin) === 'undefined') { //Here we are creating a 'garbage bin' object to temporarily //store elements that are to be discarded garbageBin = document.createElement('div'); garbageBin.style.display = 'none'; //Make sure it is