js的事件代理/委托

=================
关于事件代理/委托(delegate), 内容很多, 就看这篇文章就好了. https://www.cnblogs.com/liugang-vip/p/5616484.html 以下内容完全是来自它的:

  • 事件委托, 为什么要使用它? 其实对多个 同级的元素 使用 for 循环一样的可以处理它们上面绑定的相同事件, 而且以前还就是这样用的. 但是这样做有几个问题:
    一个是 会多次访问dom元素, (造成浏览器多次重绘??), 造成内存中存在多个对象句柄, 总之就是性能很老火...
    第二个就是for循环对新加入进来的子元素, 并不会自动绑定之前的for里面的事件.
    所以 , 为了提升性能, (如果在它们的共同 父元素上绑定 某个鼠标事件)就可以帮所有的子元素处理同一个事件了,这样就只需要访问一次dom元素, 二是对新加入的子元素一样的道理可以实现加入就有事件的好处/

  • 事件代理, 的基础,是 由于js的冒泡机制...所有子元素的 某种相同类型的鼠标事件 由于冒泡, 都可以被传递到父元素上来....就可以由父元素帮它们处理. 所以事件委托: 是多个子元素 委托它们的父元素 来实现某种事件. 即委托是绑定在 父元素上的, 即父元素就是那个 前台姑娘了.

  • 要知道, 任何机制 都不是 无所不能的, 任何机制都主要是用来 解决某一类的 问题的. 所以 , 事件委托, 也主要是用来处理 多个子元素上 绑定 相同类型的事件时, 或者说, 委托机制是最适合用来 处理 for循环绑定同一类型鼠标事件的.其他地方就不一定适合委托.
    同样的道理, 今后如果遇到这种 for循环绑定事件的时候, 就尽量使用委托机制了(其实遇到的时候还是很多的). 这时候, 可能需要 创建一个(即使从语义上可能不需要的) 共同的父元素来包裹它们.

  • 最后并不是所有的 事件都适合用 委托, 就像前台姑娘适合 委托( 收快递, 定盒饭), 但不一定适合委托 带孩子等事情了....

========
js的let和const?
它们是es6中的新加关键字,let和condt作用域是块域,即函数内部的大括号内部区域。都不可以重复定义,而且,都不可以被var定义所覆盖,注意let关键字的暂时死区temperal deadzone 即TDZ, 它会霸占大括号作用区,即屏蔽相同区域的同名全局变量,使得这个全局变量被隐藏,好像不存在一样
而const关键字定义的变量,必须声明时就要赋值,不能被修改,注意这个修改,对于数组或对象来说,是指它指向的内存引用地址不能被修改,而他里面的元素或对象成员是可以被修改,添加,删除的。 但是不能对数组或对象的const变量,做整体重新赋值,因为那一个相当于修改了变量的指向地址。

  • let 和var之间的3大区别:
  1. 作用域啊不同,即它们的生效区间,生存期间不同
  2. let有暂时性死区,var没有
  3. let变量没有 var那样的在预编译期的 变量提升,如果let变量声明定义之前就使用,会直接报错,而不是声明为undefined

===========

关于slideDown不显示的问题

  • 要想slidedown有效果, 被显示的元素, 之前开始的时候,要是隐藏的, 如果已经显示出来了, 你再用这个方法,就没有效果了.
  • 被隐藏的元素如果包含在另一个容器中, 要在正确的 元素上(即display: none的元素)使用 slideDown方法, 而不能想当然的 在 容器上使用slideDown

      $('<br><p>新密码<br><input id="newpwd" type="password" style="border-bottom-color: #09c; display:none"></p><br><p>确认新密码<br><input id="repwd" type="password" style="border-bottom-color: #09c;display:none"></p>').appendTo('form');
      $('input#newpwd').slideDown();  // 这里如果用 $('p').slideDown()就无效,而且 input也不会显示出来! 
      $('input#repwd').slideDown();
  • 注意 slideDown是 显示, 而slideUp是隐藏, 不要理解成 slideUp是向上 滑动!!
    ====================

关于input的val()方法, 注意是val() , 不是 value(...) 方法!

#### 如果是动态产生的 元素, 比如在click 回调函数中 动态产生的 元素, 要获取这个元素, 并对齐绑定 某些事件的时候, 必须在 前面的 click回调函数中 操作, 否则, 在回调函数外 这些动态元素是获取不到的! 虽然你感觉很奇怪的, 你看firebug调试器中明明就有 产生的动态元素, 但是却给你一个 错误导向!!!
  $('span.edt').click(function(){
    pwd.css('border-bottom-color','#09c');
    pwd.val('');
    pwd.attr('placeholder', '请输入旧密码');
    pwd.attr('disabled',false);

    if(i==0){
      $('<br><br><p>新密码<br><input id="newpwd" type="password" style="border-bottom-color: #fcc; display:none"></p><br><p>确认新密码<br><input id="repwd" type="password" style="border-bottom-color: #fcc;display:none"></p>').appendTo('form');
      $('input#newpwd').slideDown();
      $('input#repwd').slideDown();
      ++i;
    }

/////////////  这个newpwd和newpwd.focus必须在 click的回调函数中写,不能在外面写.否则会取不到的. console.log(newpwd)的length: 0
    var newpwd = $('input#newpwd');   
    newpwd.focus(function(){
      $.ajax({
	type:'post',
	async: false,
	dataType: 'text',
	data: {user: '{$account}', pwd:pwd.val(),usrtype: 'stupj'},
	url: '/index.php/Home/Index/verifyNP',
	error: function(xml) {
	  alert('ajax failed, 请检查: '+ xml.status +'  '+ xml.responseText)
	},
	success: function(respon){
......................

button的reset按钮是 "重置"功能, 不是清空, 是指恢复到 input控件 在属性value中设置的值!

  • 在没有关闭页面标签的情况下, 如果你只是按f5刷新的话,::: 这样, 凡是 直接 在 script脚本标签中书写的语句, 包括变量定义赋值语句等都只会执行一次 即在页面加载的时候执行一次! 而元素的事件 监听函数 则会执行多次. 所以当你在事件监听函数中 改变了外部的某个变量的值, 那么 这个值会一直保留着, 不会恢复到这个变量最开始定义/赋值时的值. 这可能给你的判断带来失误, 你还以为这个变量的值 在 下一次 事件发生时 它的值 还 是原来初始化时的值, 其实已经变了,
  • 那么 , 为了让每次事件监听发生时, 变量的值都恢复到初始化值, 就要记得把该变量放到 事件的回调函数中去定义. 不要放在外面去定义.

====
为什么thinkphp的setField更新字段出错?? 但是明明传入的新密码没有错误?

  • 是因为 setField的返回值跟 setInc setDec,save的返回值一样: (它们返回 "受影响的记录数") 所以, 有三种返回值: 如果出错返回false; 如果新的密码跟原来的密码一样, 则不用更新, 返回值为0; 所以在点击更新密码的时候, 要检查一下跟上一次的密码是否相同, 当然,你也可以不检查和之前的密码是否相同, 接受两次相同的密码. 当然如果不一样,更新成功后,返回true!
  • isset的参数是一个变量, 判断某个变量是否设置了. 它的参数不能是一个函数的返回值, 比如 isset(func_name('get.name'));就是错误的!

=========================================

先后判断用户名和密码是否正确的写法?

主要是要注意, 在第二次判断 密码是否正确的时候, 要再次把用户名的条件也要一同写上, 而不能只是 密码的判断条件, 那样的话, 就成了 用户名或密码的判断, 而不是两个条件同时要满足的判断了, 不能把两个条件分割开来判断了:

	$stu = M('stu');
	if($stu -> where(array('account' => $user))->find()){
	  if($stud->where(array('account' => $user, 'passwd' => $pwd))-> find()){    // 这里就不能只是写 array('passwd'=>$pwd), 否则就只是判断密码了,而报错! 必须还要同时把 account=>$user 的条件写上...
	    echo 'passed';
	  }else{
	    echo 'nopassed';
	  }
	}else{
	  echo 'nopassed';
	}

==============================================================

php中的数组相减用的是函数: array_diff($arr1, $arr2, \(arr3,....), 如果知道数组元素的key而不知道value, 用 array_diff_key(...). 如果要判断两个数组是否相等用`if(!array_diff(\)arr1, \(arr2) && ! array_diff(\)arr2, $arr1)){return true;}`

如果是单独的删除数组中的某一个元素, 用 unset 或 array_splice, 前者不会管元素下标, 后者会重排元素的下标.
索引数组是用 整数做键值/键名 的数组, 关联数组是用字符串做键值的数组, 它们的元素值都是一样的.

  • 关于shell中的编辑操作, 除了之前的快捷键之外, 新增几个: 按单词左右移动: ctrl+left/right, 删除单词: ctrl_w, 撤销和重做: ctrl_y 与 ctrl+?

  • 要使input控件和文字对齐?
    主要还是要调整input控件的位置, 主要是设置 input控件的margin-top: -5px, 让input控件向上移动.

  • 在jquery中的选择器, 有元素选择器, 类/id选择器, 属性选择器, 其他最大的一类就是 "冒号选择器", 即":", 也叫伪类选择器, 包括: 序号/顺序选择器, 比如 :first, :last, :odd
    :even, :gt, :eq等, :checked, :button, :radio....

  • 要获取单选按钮, 复选框等的选择值, 要用 :checked伪选择器, 不能只是写单选/复选元素: 比如: $('input[type=radio]:checked').val()

posted @ 2020-03-06 18:07  noitanym  阅读(394)  评论(0编辑  收藏  举报