一个 JS 封装代码的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
Mascdo
V2EX    Javascript

一个 JS 封装代码的问题

  •  
  •   Mascdo 2018-08-29 01:43:31 +08:00 3894 次点击
    这是一个创建于 2651 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在写 d3 的相关内容,不过我 JS 掌握不是很多。 题目要求组块化,我就想把画矩形的函数给封装起来,当做一个方法,以后画矩形的话只要调用一下就行了。以前学过一些 sql,考虑用 sql 的方式拼装,结果好像不太行,不知道有谁能指导一下怎么做么,或者有什么好的方法。

    这里是原来我写的代码

     var rect = svg.selectAll("rect") .data(dataset) // 绑定数据 .enter() // 获取 enter .append("rect") // 添加 rect 元素,绑定和数组长度一致 .attr("fill", "steelblue") // 设置填充颜色 .attr("x", function(d, i){ // x return padding.left + i * rectStep; }) .attr("y", function(d){ //y return height - padding.bottom - d; }) .attr("width", rectWidth) // 设置矩形的高度 .attr("height", function(d){ return d; }) 

    这里开始是我封装的代码,但是封装的方式不对,我是想把自己固定想要传的参数写清楚,其他不固定的参数,就放在一个数组里传进来,最后的参数[["attr",["fill", "blue"]],["attr",["fill","pink"]] 放进来以后,可以在 svg 最后执行的位置,执行 .attr("fill", "blue").attr("fill", "pink") 如果是其他的方法当然执行的不同,不过自己试了一下,根本行不通啊!!!原来的代码不难,就是封装没思路,请指教一下谢谢!

    另外补充一点,我知道可以 attr({key1: value1}, {key2, value2})的方式设置多个属性,但是这种方法的思路有局限性,就比如说要给它添加一个 mouseover 事件,没办法添加,类似这里结尾

     svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.city); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.money); }) .attr("height", function(d) { return height - y(d.money); }) .on('mouseover', tip.show) .on('mouseout', tip.hide) 

    封装代码:

    function Rect(svg, data, width, height, x, y, argsarray ){ var length = argsarray.length; var co =''; for (var i = 0; i < argsarray.length; i++) { co += '.' +argsarray[i][0] + '("' + argsarray[i][1][0] + '","' +argsarray[i][1][1] +'")'; console.log(co); // 这里输出 .attr("fill","blue").attr("fill","pink") } svg.selectAll("rect") .data(data) // 绑定数据 .enter() // 获取 enter .append("rect") // 添加 rect 元素,绑定和数组长度一致 .attr("x", x) .attr("y", y) .attr("width", width) // 设置矩形的高度 .attr("height", height) //.(eval(co)); } var getRectx = function(d, i){ return padding.left + i * rectStep}; var getRecty = function(d){ return height - padding.bottom - d}; var getHeight = function(d){ return d}; Rect(svg, dataset, rectWidth, getHeight, getRectx, getRecty, [["attr",["fill", "blue"]],["attr",["fill","pink"]]]); 

    这里设置成蓝色又设置成粉色就是看看数组中多属性能不能使用。

    5 条回复    2018-08-29 09:39:14 +08:00
    dingz
        1
    dingz  
       2018-08-29 08:45:41 +08:00
    先把你的默认参数都封装到一个对象里, 就比如叫作 defaultOptions 吧,放到全局变量。
    然后这个函数接受一个新的 options 对象作为参数, 函数里把 options 继承 defaultOptions。
    然后函数后续就对这个参数对象要干嘛干嘛的用即可。

    .attr("fill", options.fill)
    .attr("x", options.x)
    .attr("y", options.y)
    .attr("width", options.width) // 设置矩形的高度
    .attr("height", options.height)
    murmur
        2
    murmur  
       2018-08-29 08:49:50 +08:00
    如果我是用户 我希望我要的最终东西就和网上一大堆各种 chart 一样 如果只是到 rect 级别的封装还远远不够
    你现在做什么东西
    面试题么
    Mascdo
        3
    Mascdo  
    OP
       2018-08-29 09:16:53 +08:00
    @murmur 对啊,面试题。。
    dingz
        4
    dingz  
       2018-08-29 09:38:32 +08:00   1
    如果一定要按你的思路来可以这样

    // argsObj 是个对象,他的属性对应 attr 或者 on,
    //其下的属性也是个对象对应属性名或事件,
    //最终叶子属性可以是数组或者不是
    var argsObj = {
    attr: {
    fill: ['red', 'blue'],
    height: 1213
    },
    on: {
    mouseover: tip.show,
    mouseout: tip.hide
    }
    };

    function Rect(svg, data, width, height, x, y, argsObj ){
    for (var i in argsObj) {
    if (argsObj[i] && typeof argsObj[i] === 'object') {
    for (var j in argsObj[i]) {
    if (Array.isArray(argsObj[i][j]))
    for (var k = 0; k < argsObj[i][j].length; k++)
    svg[i](j, argsObj[i][j][k]);
    else
    svg[i](j, argsObj[i][j]);
    }
    }
    }
    }
    dingz
        5
    dingz  
       2018-08-29 09:39:14 +08:00
    或者把不固定参数交给一个回调函数做
    function afterDraw(svg)
    {
    svg.attr("fill", "steelblue").attr("fill", "red").on('mouseover', tip.show);
    }

    function Rect(svg, data, width, height, x, y, afterDraw)
    {
    ......
    if (afterDraw) afterDraw(svg);
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5301 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 07:14 PVG 15:14 LAX 23:14 JFK 02:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86