Rails中Javascript的e.preventDefault()无法正常工作问题
搞定这个表单提交错位的问题!
我一眼就看出问题出在哪了——你在search.js里写的$('form').submit()会触发页面上所有表单的提交动作!因为你的两个标签页里都有搜索表单,当用户允许地理定位后,这段代码会同时触发两个表单的提交,浏览器最终只会执行最后一个生效的跳转,也就是search_other对应的表单,这才导致了不符合预期的结果。
两种快速修复方案
方案一:精准传递目标表单引用
先修改pages/search局部视图里的提交拦截代码,把当前触发的表单元素传给地理定位函数:
<script> $('#form').submit(function(e) { e.preventDefault(); // 把当前表单的DOM对象传进去,明确告诉函数要处理哪个表单 getGeoLocation(this); }); </script>
然后更新search.js里的函数,接收这个表单引用,只提交它:
function getGeoLocation(targetForm) { navigator.geolocation.getCurrentPosition(function(position) { setGeoCookie(position, targetForm); }); } function setGeoCookie(position, targetForm) { var cookie_val = position.coords.latitude + "|" + position.coords.longitude; document.cookie = "lat_lng=" + escape(cookie_val); // 只提交我们指定的那个表单 $(targetForm).submit(); }
方案二:给目标表单加唯一标识
给pages/search的表单加一个独一无二的class,比如geo-target-form:
<div id="form"> <%= form_tag url_for(:controller => 'pages', :action => 'search'), :method => "get", class: "geo-target-form" do %> <%= text_field_tag :search, params[:search], autofocus: true, placeholder: "Enter keyword to search" %> <%= submit_tag "Search", name: nil, :style => "display: none;" %> <%end%> </div>
接着修改search.js里的提交代码,只选中这个带特定class的表单:
function setGeoCookie(position) { var cookie_val = position.coords.latitude + "|" + position.coords.longitude; document.cookie = "lat_lng=" + escape(cookie_val); // 精准定位到我们要提交的表单 $('.geo-target-form').submit(); }
额外小建议
- 可以加个加载提示,比如在请求地理定位的时候显示“获取位置中...”,避免用户重复点击;
- 别忘了处理定位失败的情况(比如用户拒绝授权),这时候要允许用户正常提交表单,不然会卡住;
- 两个表单都加了
autofocus,切换标签页的时候可能会有冲突,建议在标签页切换时动态设置autofocus,或者只给当前激活的表单加这个属性。
这样修改之后,当用户允许地理定位后,就只会提交你想要的那个search表单,跳转到正确的结果页面啦!
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

