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. 【MySQL】为什么不要问我DB极限QPS/TPS

    为什么不要问我DB极限QPS/TPS 背景 相信很多开发都会有这个疑问,DB到底可以支撑多大的业务量,如何去评估?对于这个很专业的问题,DBA也没有办法直接告诉你,更多的都是靠经验提供一个看似靠谱的结 ...

  2. javascript飞机大战-----006创建敌机

    先写一个敌机类 /* 创建敌机: */ function Enemy(blood,speed,imgs){ //敌机left this.left = 0; //敌机top this.top = 0; ...

  3. JS生成GUID方法

    function GUID() { this.date = new Date(); /* 判断是否初始化过,如果初始化过以下代码,则以下代码将不再执行,实际中只执行一次 */ if (typeof t ...

  4. codeforces#505--C Plasticine Zebra

    C. Plasticine zebra time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. 我见过的最完善的log4net配置

    Log4net的优点: 几乎所有的大型应用都会有自己的用于跟踪调试的API.因为一旦程序被部署以后,就不太可能再利用专 门的调试工具了.然而 一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的 ...

  6. 【Python】通过python代码实现demo_test环境的登录,通过csv/txt/excel文件批量添加课程并开启课程操作--(刚开始 项目 页面 模块 元素这种鸟 被称作pageobject 等这些搞完 然后把你的定位器、数据 和脚本在分离 就是传说中那个叫数据驱动 的鸟)

    一.1.通过csv文件批量导入数据 1 from selenium import webdriver from time import ctime,sleep import csv #循环读取每一行每 ...

  7. 第1章 1.6计算机网络概述--OSI参考模型

    ISO七层模式:国际标准组织对互联网通信规则进行的定义. 7.应用层:所有能产生网络流量的程序,如:QQ. 6.表示层:传输前对数据进行进行处理,是一种数据处理的规则,如:加密.压缩.传输二进制(图片 ...

  8. 20165324_mypwd

    20165324_mypwd 实验要求 实验要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd 背景知识 文件存储结构 介绍文件 ...

  9. (13)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分

    引言 程序截图: 本教程将会教大家如何使用Cocos2d-x来做一个基于tile地图的游戏,当然还有Tiled地图编辑器.(我们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦 ...

  10. Python:笔记(7)——yield关键字

    Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...