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. Jenkins升级、迁移、备份

    1.升级 下载新版Jenkins.war文件,替换旧版本war文件,重启即可. Jenkins.war文件的位置一般为/usr/lib/jenkins/Jenkins.war. 2.迁移.备份 Jen ...

  2. Visual Studio的“Waiting for a required operation to complete...”问题

    自从使用Visual Studio 2013之后,多次遇到这个恼人的“Waiting for a required operation to complete...”问题. 问题发生于在Visual ...

  3. opencv中Mat格式的数据访问.at

    opencv3中图形存储基本为Mat格式,如果我们想获取像素点的灰度值或者RGB值,可以通过image.at<uchar>(i,j)的方式轻松获取. Mat类中的at方法对于获取图像矩阵某 ...

  4. go 工具链目前[不支持编译 windows 下的动态链接库]解决方案

    go 工具链目前[不支持编译 windows 下的动态链接库][1],不过[支持静态链接库][2].想要产生dll,可以这样 workaround ,参考 golang [issuse#11058][ ...

  5. POI官网中的例子

    官方指南中的例子: http://poi.apache.org/spreadsheet/quick-guide.html#New+Sheet 这一节 Workbook wb = new HSSFWor ...

  6. Ubuntu下安装Nginx详细步骤

    Nginx安装之前需要三个支持: 模块依赖性 ①gzip 模块需要 zlib 库 ②rewrite 模块需要 pcre 库 ③ssl 功能需要 openssl 库 预先编译好的包: sudo apt- ...

  7. EOS Dapp开发(1)-基于Docker的开发环境搭建

    随着EOS主网的上线,相信基于EOS的Dapp开发会越来越多,查阅了很多资料相关的开发资料都不是很多,只能自己摸索,按照网上仅有的几篇教程,先git clonehttps://github.com/E ...

  8. mysql参数安全设置

    MySQL安全相关的参数有哪些?该如何配置? 1.MySQL数据安全 innodb_flush_log_at_trx_commit =1 #innodb每次提交事务redo buffer 刷新到red ...

  9. Java中内部类揭秘(一):外部类与非静态内部类的”相互可见性“

               声明:本博客为原创博客.未经同意,不得转载.原文链接为 http://blog.csdn.net/bettarwang/article/details/27012421.     ...

  10. MySQL 储存过程-原理、语法、函数详细说明

    Mysql储存过程是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之就是一组已经写好的命 ...