1 An Introduction to Ajax

打开网页的的过程也叫:request response cycel。

JavaScript也可以request然后parse the response,还可以更新网页上的信息。

因此JS可以部分更新网页。这个技术称为Ajax.

Rails默认使用CoffeeScript。包括应用JS.例子:

$.ajax(url: "/test").done (html) ->

$("#results").append html

这段代表从url上取数据,然后附加到一个id为results的div后面。

Rails 提供了内建支持来使用这个技术开发网页。无需你自己写这样的代码。有helper方法。

基本原理就是这样。

2 Unobtrusive JavaScript  不冒失的JS

Rails使用这个技术来把JS附加到DOM上去。unobtrusive意味着不把JS代表混入到HTML。

而是用data-*属性来传递参数给behavior。

3 Built-in Helpers

3.1 Remote elements

Rails提供了一组视图帮助方法,是用Ruby写的,用于帮你生成HTML元素。有时,你要增加Ajax到那些元素中。

因为Unobtrusive JS, the Rails "Ajax helper"其实一半是Ruby一半是JS。

rails-ujs提供了JS的部分,Ruby view helper增加适当的tags到你的DOM。

3.1.1 form_with

form_with默认生成data-remote= "true",可以绑定事件:

$(document).ready ->
 $("#new_article").on("ajax:success", (event) ->
  [data, status, xhr] = event.detail
  $("#new_article").append xhr.responseText
 ).on "ajax:error", (event) ->
  $("#new_article").append "<p>ERROR</p>"

解释:如果成功了则。。。,如果失败了则附加一个<p>

3.1.2 link_to

link_to 添加remote: true,后生成data-remote= "true",我们可以绑定Ajax events.如:

$ ->
   $("a[data-remote]").on "ajax:success", (event) ->
  alert "The article was deleted."

另外button_to 实际生成一个<form><input>...表格。

3.2 Customize remote elements

使用data-remote 属性无需再写一行jS代码,就能客制化元素的行为。你可以指定额外的 data-attributes来完成它。

3.2.1 data-method

就是RESTful风格,可以用HTTP的4个事件来激活link。

3.2.2 data-url and data-params

某个元素不涉及任何URL, 但你想要它们trigger Ajax calls。需要一起使用data-url和data-remote,另外还可以用data-params增加额外的参数。

如选项框:checkbox

<input type="checkbox" data-remote="true"
      data-url="/update" data-params="id=10" data-method="put">

3.2.3 data-type

data-type attribute.

3.3 其他:

data-confirm属性:

link_to "Dangerous zone", *_path, data: { confirm: "Are you sure?"} 生成类似:

<a href="..." data-confirm="Are you sure?">Dangerous zone</a>

data-disable-with attribute:

<%= form_with(model: @article.new) do |f| %>
   <%= f.submit data: { "disable-with": "Saving..." } %>
<%= end %>

生成:<input data-disable-with="Saving..." type="submit">

3.5 Rails-ujs event handlers(点击见,变化的event表格)

Rails5.1介绍rails-ujs,并且无需依赖jQuery。新版所有custom events只返回一个参数event.

增加了一个event.detail属性,它会返回一个array,这个array包括了其他的参数xhr, options, response, status。

Event name Extra parameters (event.detail) Fired
ajax:success    [response, status, xhr] 在完成后,如果response是success,则激活event

例子:

document.body.addEventListener('ajax:success', function(event) {
    var detail = event.detail;
  var data = detail[0], status = detail[1], xhr = detail[2];
})

补充EventTarget.addEventListener()方法:

将指定的监听器注册到EventTarget上,当该对象出发指定的事件时,指定的回调函数就会被执行。target.addEventListener(type, listener, options)

在上面的例子'ajax:success'就是一个事件,后面的function是监听器。一旦事件触发,就会执行函数。结果返回给body.

4 Server-Side Concerns

Ajax除了客户端需要设置,服务器端也需要设置来支持它。通常,开发者想要Ajax request 返回JSON而不是HTML。看看怎么做:

4.1 案例http://guides.rubyonrails.org/working_with_javascript_in_rails.html#a-simple-example

或者参考:

file:///Users/chentianwei/离线保存的全栈文件/学习中心%20新生大学全栈营/Content/954.html

重点:

在create方法内加 format.js, 添加create.js.erb文件。

然后使用escape_javascript(javascript)方法,也可以使用别名  j(),它的作用是转化为可以识别的javsscript代码。

下面2句code作用相同:

$("#post-list").prepend("<%=j render :partial => "post", :locals => { :post => @post } %>");

$("<%= escape_javascript(render :partial => "post", :locals => { :post => @post }) %>").prependTo("#post-list");


常用的vanilla javascript方法 替代jquery

其实是一个joke的叫法,准确的说是plain, regular javascript.

valla是一种俚语,意思是太常见以至于被认为是unexciting/normal/boring. 所以Vanllia JS实际上的意思是Normal Javascript。就像一个普通的vanilla icecream without topping。

(视频), 比jquery快100倍。

  • How to do queries for elements on the page.
  • How to add events.
  • How to hide/show just like you do with jQuery.
  • and so on...

在chrome的inspect-console可以输入JS查询,得到对应的web element.

document.querySelector("#notifications")
<div id=​"notifications">​…​</div>​

document.getElementById("notifications")
<div id=​"notifications">​…​</div>​

document.getElementsByTagName("a")
HTMLCollection(8) [a, a, a, a, a, a, a, a]

document.querySelectorAll("#notifications p")

返回匹配元素的NodeList,这是一个array,可以使用array的方法, 如果是空的,则没有找到匹配。
NodeList(4) [p#notification_1, p#notification_2, p#notification_3, p#notification_4]

jquery和使用vanilla javascript的区别:

$("a").on("click", function(){  })  #无论你在function中运行什么都行,比如循环

而原生js必须明确指定循环操作:

VM16935:2 Uncaught TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only 1 present.
document.querySelectorAll("p").forEach(function(anchor) {

anchor.addEventListener("click", function(event) {

  event.preventDefault();

  console.log("clicked");

})

})

> undefined  #如果点击网页上的任意p元素,则出现:

> clicked

⚠️ Array.prototype.forEach()方法执行一个提供的函数对每一个array element。

jquery的show, hide

$("#notifications").show/hide等同于:

document.querySelector("#notifications").style.display = 'none'
>"none"
document.querySelector("#notifications").style.display = 'block'
>"block"

document.querySelector("p").style

>CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}

点击css,会弹出所有可以使用的style后的css。是使用驼峰写法的,根原生css有区别:

css:   body {background-color: red; }

JS:  backgroundColor: "red";

jquery的append

$("#notifications").append("<p>Test</p>") ,等同于:

node = document.createRange().createContextualFragment("<p>test</p>")

#document-fragment<p>​test​</p>​

document.querySelector("#notifications").appendChild(node)

⚠️:有几个知识点:

抓取attributes和Data

<a rel="nofollow" data-method="delete" href="/users/sign_out">登出</a>

$("a").data("method")
> "delete"

$("a").attr("href")
>"/users/sign_out"

使用原生的:

document.querySelector("a").dataset
> DOMStringMap {method: "delete"}

document.querySelector("a").dataset.method = "post"   #可以改变
> "post"                       

另外一种原生写法:

document.querySelector("a").attributes,    #attributes获得所有属性。
>NamedNodeMap {0: rel, 1: data-method, 2: href, rel: rel, data-method: data-method, href: href, length: 3}

document.querySelector("a").getAttribute("data-method")

> "delete"

Ajax requests

用jquery version这么写: $.ajax({ })

Rails.5.1 这么写:(Javascript version with Rails UJS)

这会自动包括你的CSRF token for non-GET requests as well。❓啥意思

csrf token是一个校验随机数,用于防止cross-site request forgery跨站请求伪装攻击。

Rails.ajax({

url: "/notificaitons.json",

type: "GET",

success: function(data) {

console.log(data)

}

})

⚠️ 视频:Rails5.1 new UJS library的使用

使用turbolinks,目的:放置到页面上面,等待HTML加载完成后,再加载

$(document).on("turbolinks:load", function() { ... }), 可以改成javascritp version:

document.addEventListener("turbolinks:load", function() { ... })


原生javascript 转化为coffeescript  (点击,进入自动转化网站)

document.addEventListener("turbolinks:load", function() {
 document.getElementById("new_message").addEventListener("keypress", function(e){
  console.log(e.key)
 })
})

转化为:

document.addEventListener 'turbolinks:load', ->
 document.getElementById('new_message').addEventListener 'keypress', (e) ->
  console.log e.key
  return
 return


jquery和原生js的相同功能代码( slim结构 ):

功能:删除一个贴文:

$(document).on("turbolinks:load", function(){
 $(".delete-post").click(function(evt){
  // 只能终止刷新index后的行为。
  evt.preventDefault();
  var url = $(this).attr("href");
  $.ajax({
    url: url,
    method: 'DELETE',
    dataType: 'json',
    success: function(data){
     $("#post-" + data["id"]).remove();
    }
  })
  // 也有preventDefault()的作用
  // return false
   })
})

document.addEventListener("turbolinks:load", function() {
  document.querySelectorAll(".delete-post").forEach(function(anchor) {
  anchor.addEventListener("click", function(event) {
    event.preventDefault();
    var url = this.getAttribute("href");
    Rails.ajax({
        url: url,
    type: "DELETE",
    dataType: 'json',
    success: function(data) {
     document.getElementById("post-" + data["id"]).style.display = 'none'
    }
  })
 })
  })
})

解释:

蓝色:放置在页面顶部 放置到页面上面,等待HTML加载完成后,再加载

绿色:主要区别。

黄色:写法的完全区别。

错误❌:新增的贴文,页面必须从新加载一次,否则点击删除按钮,会自动跳转到show页面


Turbolinks(6600

Rails Guide--Working with JavaScript in Rails; 如何把jquery转化为原生js的更多相关文章

  1. JavaScript中函数和类(以及this的使用<重点>,以及js和jquery讲解,原生js实现jquery)

    1.javascript中以函数来表示类: 一般函数是小写开头:function foo() 类开头是大写:function Foo() 实例化类: obj = new Foo() 其他属性就同类是一 ...

  2. Ruby Rails正式学习:Ruby on Rails 做个演示项目吧,逐渐完善

    项目开始 一. 新建Rails项目 1. 修改一下Gemfile文件(简单修改一下) source 'https://rubygems.org' git_source(:github) { |repo ...

  3. Ruby On Rails 4 hello world,Ruby On Rails上手

    有机会再试一试Rails了,仅仅是原来接触的是2,如今已然变成了4,似乎如今的安装比原来会快些.. Rails 4 安装 针对于安装了RVM gem install rails 没有的话应该主 sud ...

  4. THE DEFINITIVE GUIDE TO DEBUGGING JAVASCRIPT

    FIGURING OUT WHERE THE ERROR COULD BE READ THE CODE USING THE CONSOLE THE CHROME DEV TOOLS THE DEBUG ...

  5. Ruby on Rails入门——macOS 下搭建Ruby Rails Web开发环境

    这里只介绍具体的过程及遇到的问题和解决方案,有关概念性的知识请参考另一篇:Ruby Rails入门--windows下搭建Ruby Rails Web开发环境 macOS (我的版本是:10.12.3 ...

  6. 你可能不需要 jQuery!使用原生 JavaScript 进行开发

    很多的 JavaScript 开发人员,包括我在内,都很喜欢 jQuery.因为它的简单,因为它有很多丰富的插件可供使用,和其它优秀的工具一样,jQuery 让我们开发人员能够更轻松的开发网站和 We ...

  7. 我自己的Javascript 库,封装了一些常用函数 Kingwell.js

    我自己的Javascript 库,封装了一些常用函数 Kingwell.js 博客分类: Javascript javascript 库javascript库  现在Javascript库海量,流行的 ...

  8. javascript: jquery.gomap-1.3.3.js

    from:http://www.pittss.lv/jquery/gomap/solutions.php jquery.gomap-1.3.3.js: /** * jQuery goMap * * @ ...

  9. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

随机推荐

  1. Python默认调用路径

    记录个遇到的小问题,防止下次遇到忘记怎么解. 起因:pip安装扩展库时提示安装完成,但是在Python 终端下无法import 现象:终端直接运行python 时提示如下:(2.7.13)然而用/us ...

  2. PGA结构

    当客户端向服务器发送连接请求,服务器监听到客户端的请求,在专用服务器模式下,会在服务器端衍生一个server process来代理客户的请求,server process进而向实例发起连接,创建会话, ...

  3. 词频统计 in office

    ROSTCM6 1. http://www.writewords.org.uk/word_count.asp 2. http://darylkinsman.ca/tools/wordfreq.shtm ...

  4. docker搭建oracle 11.2.0.3.0

    dockerfile 如下: FROM oraclelinux:-slim ARG ORACLE_BASE=/opt/oracle ARG ORACLE_HOME=/opt/oracle/produc ...

  5. git-【十】忽略文件

    1.在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件. 不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置 ...

  6. 江苏新美星智能物流无人叉车AGV

    新美星一家全球领先的液体包装解决方案供应商,高附加值的产品应用于食品饮料等行业,为液体食品和自动化系统提供完整解决方案.新美星,于CBST2017展会首次亮相了能够从仓库或工厂的某个地方把材料.托盘和 ...

  7. Django之Rest Framework框架

    一.什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度 ...

  8. rtcp多媒体控制协议应用

    rtcp package send/recv demo main.c #include <stdio.h> #include <rtp.h> #include <rtcp ...

  9. EF code first:列名 'Discriminator' 无效

    使用EF code first编写类继承的时候,出现列名 'Discriminator' 无效 . 字段中没有列名 'Discriminator' 原来在代码中,定义了一个类A,类B,B继承A,但是数 ...

  10. Java之Integer源码

    1.为什么Java中1000==1000为false而100==100为true? 这是一个挺有意思的讨论话题. 如果你运行下面的代码 Integer a = 1000, b = 1000; Syst ...