{"action":"opened","issue":{"url":"https://api.github.com/repos/xinglie/xinglie.github.io/issues/23","repository_url":"https://api.github.com/repos/xinglie/xinglie.github.io","labels_url":"https://api.github.com/repos/xinglie/xinglie.github.io/issues/23/labels{/name}","comments_url":"https://api.github.com/repos/xinglie/xinglie.github.io/issues/23/comments","events_url":"https://api.github.com/repos/xinglie/xinglie.github.io/issues/23/events","html_url":"https://github.com/xinglie/xinglie.github.io/issues/23","id":168809403,"number":23,"title":"提升拖动排序的效率","user":{"login":"xinglie","id":1290017,"avatar_url":"https://avatars.githubusercontent.com/u/1290017?v=3","gravatar_id":"","url":"https://api.github.com/users/xinglie","html_url":"https://github.com/xinglie","followers_url":"https://api.github.com/users/xinglie/followers","following_url":"https://api.github.com/users/xinglie/following{/other_user}","gists_url":"https://api.github.com/users/xinglie/gists{/gist_id}","starred_url":"https://api.github.com/users/xinglie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xinglie/subscriptions","organizations_url":"https://api.github.com/users/xinglie/orgs","repos_url":"https://api.github.com/users/xinglie/repos","events_url":"https://api.github.com/users/xinglie/events{/privacy}","received_events_url":"https://api.github.com/users/xinglie/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-02T06:29:58Z","updated_at":"2016-08-02T06:29:58Z","closed_at":null,"body":"拖动排序在前端是最常见的功能之一，那么如何做到效率最优呢？\r\n\r\n \r\n\r\n从拖动上，我们一般是为要拖动的元素绑定onmousedown事件，在onmousedown中进行判断是否需要拖动，如果可以拖动，则给document绑定onmousemove和onmouseup事件，在onmousemove中进行位置更改，onmouseup中释放拖动\r\n\r\n \r\n\r\n通常我们拖动时，需要实时获取鼠标指向的DOM节点，在onmousemove中根据event.srcElement或event.target获取，这样才能更改拖动中的各种效率，比如树节点的拖动，来显示是插入到2个节点中间，还是追加到某个节点下，在onmousemove中需要注意的时，拖动的东西不能挡着鼠标，要不然通过event.target或srcElement获取到的始终是挡着鼠标的节点，因此我们可以把拖动提示的节点跟随在鼠标的旁边，而不是挡在鼠标下面\r\n\r\n \r\n\r\n对于鼠标拖动到浏览器外边浏览器还能响应onmousemove事件，我们通常需要判断节点有没有setCapture方法，如果有则调用一下setCapture，这样对于像IE6这样的浏览器鼠标在浏览器外面也是可以响应的，但是这样又引入一个新问题，从firefox 4开始，firefox也提供了setCapture方法，一但这个方法被调用，在onmousemove事件中，取event.target始终是设置setCapture的这个节点，不再是鼠标指向的节点，不管有没有节点挡着鼠标，所以到这个地方又需要判断浏览器，我是不喜欢浏览器判断然后写不同的代码的，尽量使用各浏览器间通用的方法\r\n\r\n \r\n\r\n找到一个各浏览器间还算统一的方法document.elementFromPoint方法，不过这个方法在safari 4.0 ,opera 10.10实现都是不正确的，不过随后的版本修正了这个问题，但是这个方法还是有细微的浏览器差别，用起来也不是让人省心，而且在iOS5跟之前的iOS4也是不一致的，关于iOS的这里有篇文章可供参考：http://www.icab.de/blog/2011/10/17/elementfrompoint-under-ios-5/\r\n\r\n \r\n\r\n目前可通过如果元素有setCapture方法就使用elementFromPoint方法，否则使用onmousemove中的event.target或event.srcElement\r\n\r\n \r\n\r\n对于获取到鼠标指向的元素后，可缓存下来，鼠标再次移动时，先判断鼠标是否仍处于缓存的元素内，如果处于缓存的元素内，无需获取鼠标下的节点，反之再次获取鼠标下的节点，尽可能的提升查询效率。"}}
{"actor":{"display_login":"xinglie"}}